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 @@ true true true + $(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 @@ true true true + $(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, " ", SAF_NONE); + play_and_get_digits_function, + " []", SAF_NONE); SWITCH_ADD_APP(app_interface, "stop_record_session", "Stop Record Session", STOP_SESS_REC_DESC, stop_record_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "record_session", "Record Session", SESS_REC_DESC, record_session_function, " [+]", SAF_MEDIA_TAP); SWITCH_ADD_APP(app_interface, "record", "Record File", "Record a file from the channels input", record_function, diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index aa49689062..560b1cd6ad 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -439,7 +439,7 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, #define check_string(s) if (!zstr(s) && !strcasecmp(s, "undef")) { s = NULL; } -static int node_consumer_wait_count(fifo_node_t *node) +static int node_caller_count(fifo_node_t *node) { int i, len = 0; @@ -458,7 +458,7 @@ static void node_remove_uuid(fifo_node_t *node, const char *uuid) fifo_queue_popfly(node->fifo_list[i], uuid); } - if (!node_consumer_wait_count(node)) { + if (!node_caller_count(node)) { node->start_waiting = 0; } @@ -507,20 +507,19 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session args.buflen = sizeof(buf); if (switch_ivr_play_file(session, NULL, cd->list[cd->index], &args) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; + return SWITCH_STATUS_BREAK; } if (match_key(caller_exit_key, *buf)) { cd->abort = 1; - return SWITCH_STATUS_FALSE; - switch_channel_set_variable(channel, "fifo_caller_exit_key", (char *)buf); + return SWITCH_STATUS_BREAK; } cd->next = switch_epoch_time_now(NULL) + cd->freq; cd->index++; } } else if (cd->orbit_timeout && switch_epoch_time_now(NULL) >= cd->orbit_timeout) { cd->do_orbit = 1; - return SWITCH_STATUS_FALSE; + return SWITCH_STATUS_BREAK; } return SWITCH_STATUS_SUCCESS; @@ -541,7 +540,7 @@ static switch_status_t consumer_read_frame_callback(switch_core_session_t *sessi } if (total) { - return SWITCH_STATUS_FALSE; + return SWITCH_STATUS_BREAK; } return SWITCH_STATUS_SUCCESS; @@ -875,7 +874,7 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses char *sql; switch_event_t *event; - switch_channel_clear_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG); + switch_channel_clear_app_flag_key(__FILE__, consumer_channel, FIFO_APP_BRIDGE_TAG); switch_channel_set_variable(consumer_channel, "fifo_bridged", NULL); ts = switch_micro_time_now(); @@ -989,7 +988,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ goto end; } - switch_channel_set_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG); + switch_channel_set_app_flag_key(__FILE__, consumer_channel, FIFO_APP_BRIDGE_TAG); switch_channel_set_variable(consumer_channel, "fifo_bridged", "true"); switch_channel_set_variable(consumer_channel, "fifo_manual_bridge", "true"); @@ -1683,7 +1682,7 @@ static void find_consumers(fifo_node_t *node) switch(node->outbound_strategy) { case NODE_STRATEGY_ENTERPRISE: { - int need = node_consumer_wait_count(node); + int need = node_caller_count(node); if (node->outbound_per_cycle && node->outbound_per_cycle < need) { need = node->outbound_per_cycle; @@ -1753,7 +1752,7 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o if ((node = (fifo_node_t *) val)) { if (node->outbound_priority == 0) node->outbound_priority = 5; if (node->has_outbound && node->ready && !node->busy && node->outbound_priority == cur_priority) { - ppl_waiting = node_consumer_wait_count(node); + ppl_waiting = node_caller_count(node); consumer_total = node->consumer_count; idle_consumers = node_idle_consumers(node); @@ -1831,7 +1830,7 @@ static void check_cancel(fifo_node_t *node) return; } - ppl_waiting = node_consumer_wait_count(node); + ppl_waiting = node_caller_count(node); if (node->ring_consumer_count > 0 && ppl_waiting < 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound call count (%d) exceeds required value for queue %s (%d), " @@ -1855,7 +1854,7 @@ static void send_presence(fifo_node_t *node) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "park"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", node->name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", node->name); - if ((wait_count = node_consumer_wait_count(node)) > 0) { + if ((wait_count = node_caller_count(node)) > 0) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d waiting)", wait_count); } else { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Idle"); @@ -1990,6 +1989,11 @@ static void dec_use_count(switch_core_session_t *session, switch_bool_t send_eve if ((outbound_id = switch_channel_get_variable(channel, "fifo_outbound_uuid"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s untracking call on uuid %s!\n", switch_channel_get_name(channel), outbound_id); + + sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(session)); + fifo_execute_sql(sql, globals.sql_mutex); + switch_safe_free(sql); + del_bridge_call(outbound_id); sql = switch_mprintf("update fifo_outbound set use_count=use_count-1, stop_time=%ld, next_avail=%ld + lag + 1 where use_count > 0 and uuid='%q'", now, now, outbound_id); @@ -2043,7 +2047,7 @@ SWITCH_STANDARD_APP(fifo_track_call_function) add_bridge_call(data); - switch_channel_set_app_flag(channel, FIFO_APP_TRACKING); + switch_channel_set_app_flag_key(__FILE__, channel, FIFO_APP_TRACKING); switch_channel_set_variable(channel, "fifo_outbound_uuid", data); switch_channel_set_variable(channel, "fifo_track_call", "true"); @@ -2296,7 +2300,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_answer(channel); switch_thread_rwlock_wrlock(node->rwlock); - node->caller_count++; if ((pri = switch_channel_get_variable(channel, "fifo_priority"))) { p = atoi(pri); @@ -2306,7 +2309,7 @@ SWITCH_STANDARD_APP(fifo_function) p = MAX_PRI - 1; } - if (!node_consumer_wait_count(node)) { + if (!node_caller_count(node)) { node->start_waiting = switch_micro_time_now(); } @@ -2343,7 +2346,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(channel, "fifo_timestamp", date); switch_channel_set_variable(channel, "fifo_serviced_uuid", NULL); - switch_channel_set_app_flag(channel, FIFO_APP_BRIDGE_TAG); + switch_channel_set_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG); if (chime_list) { char *list_dup = switch_core_session_strdup(session, chime_list); @@ -2416,10 +2419,10 @@ SWITCH_STANDARD_APP(fifo_function) } } - switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG); + abort: + + switch_channel_clear_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG); - abort: - fifo_caller_del(switch_core_session_get_uuid(session)); if (!aborted && switch_channel_ready(channel)) { @@ -2442,7 +2445,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_mutex_lock(globals.mutex); switch_thread_rwlock_wrlock(node->rwlock); node_remove_uuid(node, uuid); - node->caller_count--; switch_thread_rwlock_unlock(node->rwlock); send_presence(node); check_cancel(node); @@ -2583,7 +2585,7 @@ SWITCH_STANDARD_APP(fifo_function) continue; } - if ((waiting = node_consumer_wait_count(node))) { + if ((waiting = node_caller_count(node))) { if (!importance || node->importance > importance) { if (strat == STRAT_WAITING_LONGER) { @@ -2671,7 +2673,7 @@ SWITCH_STANDARD_APP(fifo_function) } } - if (pop && !node_consumer_wait_count(node)) { + if (pop && !node_caller_count(node)) { switch_thread_rwlock_wrlock(node->rwlock); node->start_waiting = 0; switch_thread_rwlock_unlock(node->rwlock); @@ -2775,7 +2777,8 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_flag(other_channel, CF_BREAK); - while (switch_channel_ready(channel) && switch_channel_ready(other_channel) && switch_channel_test_app_flag(other_channel, FIFO_APP_BRIDGE_TAG)) { + while (switch_channel_ready(channel) && switch_channel_ready(other_channel) && + switch_channel_test_app_flag(other_channel, FIFO_APP_BRIDGE_TAG)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { break; @@ -2787,9 +2790,6 @@ SWITCH_STANDARD_APP(fifo_function) const char *arg = switch_channel_get_variable(other_channel, "current_application_data"); switch_caller_extension_t *extension = NULL; - switch_thread_rwlock_wrlock(node->rwlock); - node->caller_count--; - switch_thread_rwlock_unlock(node->rwlock); send_presence(node); check_cancel(node); @@ -2955,9 +2955,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(other_channel, "fifo_status", "DONE"); switch_channel_set_variable(other_channel, "fifo_timestamp", date); - switch_thread_rwlock_wrlock(node->rwlock); - node->caller_count--; - switch_thread_rwlock_unlock(node->rwlock); send_presence(node); check_cancel(node); switch_core_session_rwunlock(other_session); @@ -3070,7 +3067,7 @@ SWITCH_STANDARD_APP(fifo_function) done: switch_mutex_lock(globals.mutex); - if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node->caller_count == 0) { + if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node_caller_count(node) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name); switch_core_hash_delete(globals.fifo_hash, node->name); switch_thread_rwlock_wrlock(node->rwlock); @@ -3085,7 +3082,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_mutex_unlock(globals.mutex); - switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG); + switch_channel_clear_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG); switch_core_media_bug_resume(session); @@ -3505,9 +3502,9 @@ static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int ve switch_xml_set_attr_d(x_fifo, "name", node->name); switch_snprintf(tmp, sizeof(buffer), "%d", node->consumer_count); switch_xml_set_attr_d(x_fifo, "consumer_count", tmp); - switch_snprintf(tmp, sizeof(buffer), "%d", node->caller_count); + switch_snprintf(tmp, sizeof(buffer), "%d", node_caller_count(node)); switch_xml_set_attr_d(x_fifo, "caller_count", tmp); - switch_snprintf(tmp, sizeof(buffer), "%d", node_consumer_wait_count(node)); + switch_snprintf(tmp, sizeof(buffer), "%d", node_caller_count(node)); switch_xml_set_attr_d(x_fifo, "waiting_count", tmp); switch_snprintf(tmp, sizeof(buffer), "%u", node->importance); switch_xml_set_attr_d(x_fifo, "importance", tmp); @@ -3569,7 +3566,7 @@ void node_dump(switch_stream_handle_t *stream) node->outbound_priority, node->busy, node->ready, - node_consumer_wait_count(node) + node_caller_count(node) ); } @@ -3687,9 +3684,9 @@ SWITCH_STANDARD_API(fifo_api_function) for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); - stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node->caller_count, len); + stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node_caller_count(node), len); switch_thread_rwlock_unlock(node->rwlock); x++; } @@ -3698,9 +3695,9 @@ SWITCH_STANDARD_API(fifo_api_function) stream->write_function(stream, "none\n"); } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); - stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node->caller_count, len); + stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node_caller_count(node), len); switch_thread_rwlock_unlock(node->rwlock); } else { stream->write_function(stream, "none\n"); @@ -3710,7 +3707,7 @@ SWITCH_STANDARD_API(fifo_api_function) for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); stream->write_function(stream, "%s:%d\n", (char *) var, node->has_outbound); switch_thread_rwlock_unlock(node->rwlock); @@ -3721,7 +3718,7 @@ SWITCH_STANDARD_API(fifo_api_function) stream->write_function(stream, "none\n"); } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); stream->write_function(stream, "%s:%d\n", argv[1], node->has_outbound); switch_thread_rwlock_unlock(node->rwlock); @@ -4072,7 +4069,7 @@ static switch_status_t load_config(int reload, int del_all) continue; } - if (node_consumer_wait_count(node) || node->consumer_count || node_idle_consumers(node)) { + if (node_caller_count(node) || node->consumer_count || node_idle_consumers(node)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s removal delayed, still in use.\n", node->name); node->ready = FIFO_DELAY_DESTROY; } else { diff --git a/src/mod/applications/mod_hash/mod_hash.c b/src/mod/applications/mod_hash/mod_hash.c index 3a65528ea3..29a056104f 100644 --- a/src/mod/applications/mod_hash/mod_hash.c +++ b/src/mod/applications/mod_hash/mod_hash.c @@ -852,7 +852,8 @@ static void do_config(switch_bool_t reload) const char *username = switch_xml_attr(x_list, "username"); const char *password = switch_xml_attr(x_list, "password"); const char *szinterval = switch_xml_attr(x_list, "interval"); - int port = 0, interval = 0; + uint16_t port = 0; + int interval = 0; limit_remote_t *remote; switch_threadattr_t *thd_attr = NULL; @@ -866,7 +867,7 @@ static void do_config(switch_bool_t reload) } if (!zstr(szport)) { - port = atoi(szport); + port = (uint16_t)atoi(szport); } if (!zstr(szinterval)) { @@ -949,7 +950,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_hash_shutdown) /* Kill remote connections, destroy needs a wrlock so we unlock after finding a pointer */ while(remote_clean) { void *val; - const void *key; + const void *key = NULL; switch_ssize_t keylen; limit_remote_t *item = NULL; diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 105576ce14..cc93707367 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -167,7 +167,7 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha switch_channel_t *channel = NULL; if (!zstr(cid)) { - len = strlen(cid); + len = (uint32_t)strlen(cid); } else { goto done; } @@ -506,7 +506,7 @@ static char *expand_digits(switch_memory_pool_t *pool, char *digits, switch_bool int digit_len; SWITCH_STANDARD_STREAM(dig_stream); - digit_len = strlen(digits); + digit_len = (int)strlen(digits); digits_copy = switch_core_strdup(pool, digits); for (n = digit_len; n > 0; n--) { diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index 06bc7d0abd..42369f5d0b 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -419,10 +419,10 @@ static switch_status_t do_billing(switch_core_session_t *session) billaccount = switch_channel_get_variable(channel, "nibble_account"); if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) { - nobal_amt = atof(switch_channel_get_variable(channel, "nobal_amt")); + nobal_amt = (float)atof(switch_channel_get_variable(channel, "nobal_amt")); } if (!zstr(switch_channel_get_variable(channel, "lowbal_amt"))) { - lowbal_amt = atof(switch_channel_get_variable(channel, "lowbal_amt")); + lowbal_amt = (float)atof(switch_channel_get_variable(channel, "lowbal_amt")); } /* Return if there's no billing information on this session */ diff --git a/src/mod/applications/mod_redis/mod_redis.c b/src/mod/applications/mod_redis/mod_redis.c index 75dfd6fdd7..d20ab934f3 100755 --- a/src/mod/applications/mod_redis/mod_redis.c +++ b/src/mod/applications/mod_redis/mod_redis.c @@ -34,7 +34,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_redis_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_redis_shutdown); -SWITCH_MODULE_DEFINITION(mod_redis, mod_redis_load, NULL, mod_redis_shutdown); +SWITCH_MODULE_DEFINITION(mod_redis, mod_redis_load, mod_redis_shutdown, NULL); static struct{ char *host; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c index 096d967ff0..aa7d05cf9e 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c @@ -549,8 +549,8 @@ static switch_status_t do_config(void) if (id == -1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to add tone_descriptor: %s, tone: %s. (too many tones)\n", name, tone_name); return SWITCH_STATUS_FALSE; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding tone_descriptor: %s, tone: %s(%d)\n", name, tone_name, id);} + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding tone_descriptor: %s, tone: %s(%d)\n", name, tone_name, id); /* add elements to tone */ for (element = switch_xml_child(tone, "element"); element; element = switch_xml_next(element)) { const char *freq1_attr = switch_xml_attr(element, "freq1"); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 2ea3eb00a3..27878246f0 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -203,9 +203,9 @@ static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void * goto end; } - while(t38_state_list.thread_running) { + switch_mutex_lock(globals.cond_mutex); - switch_mutex_lock(globals.cond_mutex); + while(t38_state_list.thread_running) { switch_mutex_lock(t38_state_list.mutex); @@ -226,6 +226,8 @@ static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void * switch_core_timer_next(&timer); } + + switch_mutex_unlock(globals.cond_mutex); end: @@ -789,9 +791,9 @@ static t38_mode_t negotiate_t38(pvt_t *pvt) t38_options->T38FaxRateManagement = "transferredTCF"; t38_options->T38FaxMaxBuffer = 2000; t38_options->T38FaxMaxDatagram = LOCAL_FAX_MAX_DATAGRAM; - if (strcasecmp(t38_options->T38FaxUdpEC, "t38UDPRedundancy") == 0 - || - strcasecmp(t38_options->T38FaxUdpEC, "t38UDPFEC") == 0) { + if (!zstr(t38_options->T38FaxUdpEC) && + (strcasecmp(t38_options->T38FaxUdpEC, "t38UDPRedundancy") == 0 || + strcasecmp(t38_options->T38FaxUdpEC, "t38UDPFEC") == 0)) { t38_options->T38FaxUdpEC = "t38UDPRedundancy"; } else { t38_options->T38FaxUdpEC = NULL; @@ -850,6 +852,12 @@ static t38_mode_t request_t38(pvt_t *pvt) insist = globals.enable_t38_insist; } + if ((t38_options = switch_channel_get_private(channel, "t38_options"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "%s already has T.38 data\n", switch_channel_get_name(channel)); + enabled = 0; + } + if (enabled) { t38_options = switch_core_session_alloc(session, sizeof(*t38_options)); @@ -992,6 +1000,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat switch_frame_t write_frame = { 0 }; switch_codec_implementation_t read_impl = { 0 }; int16_t *buf = NULL; + uint32_t req_counter = 0; switch_core_session_get_read_impl(session, &read_impl); @@ -1107,10 +1116,11 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat switch_ivr_sleep(session, 250, SWITCH_TRUE, NULL); - - /* If you have the means, I highly recommend picking one up. ...*/ - request_t38(pvt); - + if (pvt->app_mode == FUNCTION_TX) { + req_counter = 100; + } else { + req_counter = 50; + } while (switch_channel_ready(channel)) { int tx = 0; @@ -1154,6 +1164,13 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat break; case T38_MODE_UNKNOWN: { + if (req_counter) { + if (!--req_counter) { + /* If you have the means, I highly recommend picking one up. ...*/ + request_t38(pvt); + } + } + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { if (negotiate_t38(pvt) == T38_MODE_NEGOTIATED) { /* is is safe to call this again, it was already called above in AUDIO_MODE */ diff --git a/src/mod/applications/mod_spandsp/udptl.c b/src/mod/applications/mod_spandsp/udptl.c index a2651513f0..f5b3be2445 100644 --- a/src/mod/applications/mod_spandsp/udptl.c +++ b/src/mod/applications/mod_spandsp/udptl.c @@ -93,7 +93,7 @@ static int encode_length(uint8_t *buf, int *len, int value) if (value < 0x80) { /* 1 octet */ - buf[(*len)++] = value; + buf[(*len)++] = (uint8_t)value; return value; } if (value < 0x4000) { @@ -106,7 +106,7 @@ static int encode_length(uint8_t *buf, int *len, int value) /* Fragmentation */ multiplier = (value < 0x10000) ? (value >> 14) : 4; /* Set the first 2 bits of the octet */ - buf[(*len)++] = 0xC0 | multiplier; + buf[(*len)++] = (uint8_t) (0xC0 | multiplier); return multiplier << 14; } @@ -419,10 +419,10 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int /* Span is defined as an inconstrained integer, which it dumb. It will only ever be a small value. Treat it as such. */ buf[len++] = 1; - buf[len++] = span; + buf[len++] = (uint8_t)span; /* The number of entries is defined as a length, but will only ever be a small value. Treat it as such. */ - buf[len++] = entries; + buf[len++] = (uint8_t)entries; for (m = 0; m < entries; m++) { /* Make an XOR'ed entry the maximum length */ limit = (entry + m) & UDPTL_BUF_MASK; diff --git a/src/mod/applications/mod_valet_parking/mod_valet_parking.c b/src/mod/applications/mod_valet_parking/mod_valet_parking.c index aee49c76e9..b6f13a93e9 100644 --- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c +++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c @@ -203,7 +203,7 @@ SWITCH_STANDARD_APP(valet_parking_function) } do { - status = switch_ivr_read(session, min, max, prompt, NULL, dtmf_buf, sizeof(dtmf_buf), to, "#"); + status = switch_ivr_read(session, min, max, prompt, NULL, dtmf_buf, sizeof(dtmf_buf), to, "#", 0); } while (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_FALSE); if (status == SWITCH_STATUS_SUCCESS) { @@ -233,7 +233,17 @@ SWITCH_STANDARD_APP(valet_parking_function) } } - dest = switch_core_session_sprintf(session, "sleep:1000,valet_park:%s %s", lot_name, ext); + if (!(tmp = switch_channel_get_variable(channel, "valet_hold_music"))) { + tmp = switch_channel_get_variable(channel, "hold_music"); + } + if (tmp) + music = tmp; + + if (!strcasecmp(music, "silence")) { + music = "silence_stream://-1"; + } + + dest = switch_core_session_sprintf(session, "set:valet_hold_music=%s,sleep:1000,valet_park:%s %s", music, lot_name, ext); switch_channel_set_variable(channel, "inline_destination", dest); if (is_auto) { @@ -266,12 +276,6 @@ SWITCH_STANDARD_APP(valet_parking_function) } - if (!(tmp = switch_channel_get_variable(channel, "valet_hold_music"))) { - tmp = switch_channel_get_variable(channel, "hold_music"); - } - if (tmp) - music = tmp; - switch_core_hash_insert(lot->hash, ext, switch_core_session_get_uuid(session)); args.input_callback = valet_on_dtmf; @@ -280,9 +284,6 @@ SWITCH_STANDARD_APP(valet_parking_function) switch_mutex_unlock(lot->mutex); - if (!strcasecmp(music, "silence")) { - music = "silence_stream://-1"; - } while(switch_channel_ready(channel)) { switch_status_t pstatus = switch_ivr_play_file(session, NULL, music, &args); diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 069cfd8d9f..758e5dcf25 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1422,6 +1422,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t char cid_buf[1024] = ""; if (switch_channel_ready(channel)) { + const char *vm_announce_cid = NULL; switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", cbt->cid_number, cbt->cid_name); @@ -1429,7 +1430,13 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t msg.string_arg = cid_buf; msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY; switch_core_session_receive_message(session, &msg); - + + if (!zstr(cbt->cid_number) && (vm_announce_cid = switch_channel_get_variable(channel, "vm_announce_cid"))) { + switch_ivr_play_file(session, NULL, vm_announce_cid, NULL); + switch_ivr_sleep(session, 500, SWITCH_TRUE, NULL); + switch_ivr_say(session, cbt->cid_number, NULL, "name_spelled", "pronounced", NULL, NULL); + } + args.input_callback = cancel_on_dtmf; switch_snprintf(key_buf, sizeof(key_buf), "%s:%s:%s:%s:%s:%s%s%s", profile->listen_file_key, profile->save_file_key, @@ -1524,7 +1531,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t vm_cc[0] = '\0'; TRY_CODE(switch_ivr_read - (session, 0, sizeof(vm_cc), macro_buf, NULL, vm_cc, sizeof(vm_cc), profile->digit_timeout, profile->terminator_key)); + (session, 0, sizeof(vm_cc), macro_buf, NULL, vm_cc, sizeof(vm_cc), profile->digit_timeout, profile->terminator_key, 0)); cmd = switch_core_session_sprintf(session, "%s@%s %s %s '%s'", vm_cc, cbt->domain, new_file_path, cbt->cid_number, cbt->cid_name); @@ -1988,7 +1995,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p switch_xml_t xx_user, xx_domain, xx_domain_root; switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", VM_ENTER_PASS_MACRO, profile->terminator_key); - TRY_CODE(switch_ivr_read(session, 0, 255, macro, NULL, buf, sizeof(buf), 10000, profile->terminator_key)); + TRY_CODE(switch_ivr_read(session, 0, 255, macro, NULL, buf, sizeof(buf), 10000, profile->terminator_key, 0)); sql = switch_mprintf("update voicemail_prefs set password='%s' where username='%s' and domain='%s'", buf, myid, domain_name); vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(file_path); @@ -2310,7 +2317,7 @@ static switch_status_t deliver_vm(vm_profile_t *profile, const char *caller_id_name, const char *caller_id_number, const char *forwarded_by, - switch_bool_t copy, const char *use_uuid) + switch_bool_t copy, const char *use_uuid, switch_core_session_t *session) { char *file_path = NULL, *dir_path = NULL; const char *myid = switch_xml_attr(x_user, "id"); @@ -2335,7 +2342,9 @@ static switch_status_t deliver_vm(vm_profile_t *profile, switch_status_t ret = SWITCH_STATUS_SUCCESS; char *convert_cmd = profile->convert_cmd; char *convert_ext = profile->convert_ext; + int del_file = 0; + if (!params) { switch_event_create(&local_event, SWITCH_EVENT_REQUEST_PARAMS); params = local_event; @@ -2627,14 +2636,35 @@ static switch_status_t deliver_vm(vm_profile_t *profile, } if (!insert_db) { - if (unlink(file_path) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete file [%s]\n", file_path); + del_file = 1; + } + } + + if (session) { + switch_channel_t *channel = switch_core_session_get_channel(session); + const char *vm_cc; + + if ((vm_cc = switch_channel_get_variable(channel, "vm_cc"))) { + char *cmd = switch_core_session_sprintf(session, "%s %s %s '%s' %s@%s %s", + vm_cc, file_path, caller_id_number, caller_id_name, myid, domain_name, read_flags); + + if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Sent Carbon Copy to %s\n", vm_cc); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to Carbon Copy to %s\n", vm_cc); } } } + failed: + if (del_file && file_path) { + if (unlink(file_path) != 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete file [%s]\n", file_path); + } + } + switch_event_destroy(&local_event); switch_safe_free(dir_path); @@ -2778,7 +2808,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS); status = deliver_vm(profile, ux, domain, path, 0, read_flags, my_params, pool, cid_name, cid_num, forwarded_by, - SWITCH_TRUE, session ? switch_core_session_get_uuid(session) : NULL); + SWITCH_TRUE, session ? switch_core_session_get_uuid(session) : NULL, NULL); switch_event_destroy(&my_params); } continue; @@ -2787,7 +2817,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS); status = deliver_vm(profile, ut, domain, path, 0, read_flags, my_params, pool, cid_name, cid_num, forwarded_by, SWITCH_TRUE, - session ? switch_core_session_get_uuid(session) : NULL); + session ? switch_core_session_get_uuid(session) : NULL, NULL); switch_event_destroy(&my_params); } } @@ -2810,7 +2840,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS); status = deliver_vm(profile, ut, domain, path, 0, read_flags, my_params, pool, cid_name, cid_num, forwarded_by, SWITCH_TRUE, - session ? switch_core_session_get_uuid(session) : NULL); + session ? switch_core_session_get_uuid(session) : NULL, NULL); switch_event_destroy(&my_params); } } @@ -2824,7 +2854,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS); status = deliver_vm(profile, ut, domain, path, 0, read_flags, my_params, pool, cid_name, cid_num, forwarded_by, SWITCH_TRUE, - session ? switch_core_session_get_uuid(session) : NULL); + session ? switch_core_session_get_uuid(session) : NULL, NULL); switch_event_destroy(&my_params); } else { status = SWITCH_STATUS_FALSE; @@ -2882,7 +2912,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p const char *caller_id_number = NULL; switch_xml_t x_user = NULL, x_params = NULL, x_param = NULL; switch_event_t *vars = NULL; - const char *vm_cc = NULL, *vtmp, *vm_ext = NULL; + const char *vtmp, *vm_ext = NULL; int disk_quota = 0; switch_bool_t skip_greeting = switch_true(switch_channel_get_variable(channel, "skip_greeting")); switch_bool_t skip_instructions = switch_true(switch_channel_get_variable(channel, "skip_instructions")); @@ -3168,20 +3198,9 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p switch_channel_get_variables(channel, &vars); status = deliver_vm(profile, x_user, domain_name, file_path, message_len, read_flags, vars, switch_core_session_get_pool(session), caller_id_name, caller_id_number, NULL, SWITCH_FALSE, - session ? switch_core_session_get_uuid(session) : NULL); + session ? switch_core_session_get_uuid(session) : NULL, session); switch_event_destroy(&vars); - if (status == SWITCH_STATUS_SUCCESS) { - if ((vm_cc = switch_channel_get_variable(channel, "vm_cc"))) { - char *cmd = switch_core_session_sprintf(session, "%s %s %s '%s' %s@%s %s", - vm_cc, file_path, caller_id_number, caller_id_name, id, domain_name, read_flags); - - if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Sent Carbon Copy to %s\n", vm_cc); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to Carbon Copy to %s\n", vm_cc); - } - } - } else { + if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to deliver message\n"); TRY_CODE(switch_ivr_phrase_macro(session, VM_ACK_MACRO, "deleted", NULL, NULL)); } @@ -3206,7 +3225,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p #define VM_DESC "voicemail" -#define VM_USAGE "[check|auth] []" +#define VM_USAGE "[check] [auth] []" SWITCH_STANDARD_APP(voicemail_function) { @@ -3678,7 +3697,7 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames) const char *fmt = "%a, %e %b %Y %T %z"; char heard[80]; char title_b4[128] = ""; - char title_aft[128 * 3] = ""; + char title_aft[128 * 3 + 1] = ""; if (argc > 0) { l_created = switch_time_make(atol(argv[0]), 0); diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index 139fe217a3..4b36e1435e 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -2724,7 +2724,7 @@ static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec name++; name = switch_core_sprintf(ah->memory_pool, "%s ASR-%d", name, speech_channel_number); } else { - name = switch_core_sprintf(ah->memory_pool, "ASR-%d", name, speech_channel_number); + name = switch_core_sprintf(ah->memory_pool, "ASR-%d", speech_channel_number); } /* Allocate the channel */ diff --git a/src/mod/codecs/mod_amr/mod_amr.c b/src/mod/codecs/mod_amr/mod_amr.c index a864254e28..e8925c4581 100644 --- a/src/mod/codecs/mod_amr/mod_amr.c +++ b/src/mod/codecs/mod_amr/mod_amr.c @@ -98,11 +98,8 @@ typedef enum { AMR_DTX_ENABLED } amr_dtx_t; -struct amr_context { - void *encoder_state; - void *decoder_state; - switch_byte_t enc_modes; - switch_byte_t enc_mode; +/*! \brief Various codec settings */ +struct amr_codec_settings { int dtx_mode; uint32_t change_period; switch_byte_t max_ptime; @@ -110,6 +107,24 @@ struct amr_context { switch_byte_t channels; switch_byte_t flags; }; +typedef struct amr_codec_settings amr_codec_settings_t; + +static amr_codec_settings_t default_codec_settings = { + /*.dtx_mode */ AMR_DTX_ENABLED, + /*.change_period */ 0, + /*.max_ptime */ 0, + /*.ptime */ 0, + /*.channels */ 0, + /*.flags */ 0, +}; + + +struct amr_context { + void *encoder_state; + void *decoder_state; + switch_byte_t enc_modes; + switch_byte_t enc_mode; +}; #define AMR_DEFAULT_BITRATE AMR_BITRATE_1220 @@ -117,6 +132,88 @@ static struct { switch_byte_t default_bitrate; } globals; +static switch_status_t switch_amr_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + amr_codec_settings_t *codec_settings = NULL; + if (codec_fmtp->private_info) { + codec_settings = codec_fmtp->private_info; + memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); + } + + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + + argc = switch_separate_string((char *) fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + /* + if (!strcasecmp(data, "bitrate")) { + bit_rate = atoi(arg); + } + */ + if (codec_settings) { + if (!strcasecmp(data, "octet-align")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_OCTET_ALIGN); + } + } else if (!strcasecmp(data, "mode-change-neighbor")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_MODE_CHANGE_NEIGHBOR); + } + } else if (!strcasecmp(data, "crc")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_CRC); + } + } else if (!strcasecmp(data, "robust-sorting")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_ROBUST_SORTING); + } + } else if (!strcasecmp(data, "interveaving")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_INTERLEAVING); + } + } else if (!strcasecmp(data, "mode-change-period")) { + codec_settings->change_period = atoi(arg); + } else if (!strcasecmp(data, "ptime")) { + codec_settings->ptime = (switch_byte_t) atoi(arg); + } else if (!strcasecmp(data, "channels")) { + codec_settings->channels = (switch_byte_t) atoi(arg); + } else if (!strcasecmp(data, "maxptime")) { + codec_settings->max_ptime = (switch_byte_t) atoi(arg); + } else if (!strcasecmp(data, "mode-set")) { + int y, m_argc; + char *m_argv[7]; + m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); + for (y = 0; y < m_argc; y++) { + codec_settings->enc_modes |= (1 << atoi(m_argv[y])); + } + } else if (!strcasecmp(data, "dtx")) { + codec_settings->dtx_mode = (atoi(arg)) ? AMR_DTX_ENABLED : AMR_DTX_DISABLED; + } + } + + } + } + free(fmtp_dup); + } + //codec_fmtp->bits_per_second = bit_rate; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + #endif static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) @@ -128,7 +225,10 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ } return SWITCH_STATUS_SUCCESS; #else + struct amr_context *context = NULL; + switch_codec_fmtp_t codec_fmtp; + amr_codec_settings_t amr_codec_settings; int encoding, decoding; int x, i, argc; char *argv[10]; @@ -141,58 +241,9 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ return SWITCH_STATUS_FALSE; } else { - context->dtx_mode = AMR_DTX_ENABLED; - if (codec->fmtp_in) { - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - while (*data && *data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "octet-align")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_OCTET_ALIGN); - } - } else if (!strcasecmp(data, "mode-change-neighbor")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_MODE_CHANGE_NEIGHBOR); - } - } else if (!strcasecmp(data, "crc")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_CRC); - } - } else if (!strcasecmp(data, "robust-sorting")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_ROBUST_SORTING); - } - } else if (!strcasecmp(data, "interveaving")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_INTERLEAVING); - } - } else if (!strcasecmp(data, "mode-change-period")) { - context->change_period = atoi(arg); - } else if (!strcasecmp(data, "ptime")) { - context->ptime = (switch_byte_t) atoi(arg); - } else if (!strcasecmp(data, "channels")) { - context->channels = (switch_byte_t) atoi(arg); - } else if (!strcasecmp(data, "maxptime")) { - context->max_ptime = (switch_byte_t) atoi(arg); - } else if (!strcasecmp(data, "mode-set")) { - int y, m_argc; - char *m_argv[7]; - m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); - for (y = 0; y < m_argc; y++) { - context->enc_modes |= (1 << atoi(m_argv[y])); - } - } else if (!strcasecmp(data, "dtx")) { - context->dtx_mode = (atoi(arg)) ? AMR_DTX_ENABLED : AMR_DTX_DISABLED; - } - } - } - } + memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + codec_fmtp.private_info = &amr_codec_settings; + switch_amr_fmtp_parse(codec->fmtp_in, &codec_fmtp); if (context->enc_modes) { for (i = 7; i > -1; i++) { @@ -321,6 +372,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amr_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "AMR"); +#ifndef AMR_PASSTHROUGH + codec_interface->parse_fmtp = switch_amr_fmtp_parse; +#endif switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 96, /* the IANA code number */ "AMR", /* the IANA code name */ diff --git a/src/mod/codecs/mod_codec2/Makefile b/src/mod/codecs/mod_codec2/Makefile new file mode 100644 index 0000000000..568df9c64d --- /dev/null +++ b/src/mod/codecs/mod_codec2/Makefile @@ -0,0 +1,14 @@ +BASE=../../../.. + +CODEC2_DIR=$(switch_srcdir)/libs/libcodec2 +CODEC2_BUILDDIR=$(switch_builddir)/libs/libcodec2 +CODEC2LA=$(CODEC2_BUILDDIR)/src/libcodec2.la + +LOCAL_CFLAGS=-I$(CODEC2_DIR)/include -I$(CODEC2_BUILDDIR)/src +LOCAL_LIBADD=$(CODEC2LA) +include $(BASE)/build/modmake.rules + +$(CODEC2LA): $(CODEC2_DIR) $(CODEC2_DIR)/.update + cd $(CODEC2_BUILDDIR) && $(MAKE) + $(TOUCH_TARGET) + diff --git a/src/mod/codecs/mod_codec2/mod_codec2.c b/src/mod/codecs/mod_codec2/mod_codec2.c new file mode 100644 index 0000000000..e7aa645090 --- /dev/null +++ b/src/mod/codecs/mod_codec2/mod_codec2.c @@ -0,0 +1,264 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2010, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library + * + * The Initial Developer of the Original Code is + * Brian West + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mathieu Rene + * + * mod_codec2 -- FreeSWITCH CODEC2 Module + * + */ + +#include +#include + +/* Uncomment to log input/output data for debugging +#define LOG_DATA +#define CODEC2_DEBUG +*/ + +#ifdef CODEC2_DEBUG +#define codec2_assert(_x) switch_assert(_x) +#else +#define codec2_assert(_x) +#endif + +SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load); + +SWITCH_MODULE_DEFINITION(mod_codec2, mod_codec2_load, NULL, NULL); + +struct codec2_context { + void *encoder; + void *decoder; +#ifdef LOG_DATA + FILE *encoder_in; + FILE *encoder_out; + FILE *encoder_out_unpacked; + FILE *decoder_in; + FILE *decoder_in_unpacked; + FILE *decoder_out; +#endif +}; + +#ifdef LOG_DATA +static int c2_count = 0; +#endif + +static switch_status_t switch_codec2_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) +{ + uint32_t encoding, decoding; + struct codec2_context *context = NULL; + + encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); + decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + + if (!(encoding || decoding)) { + return SWITCH_STATUS_FALSE; + } + + if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) { + return SWITCH_STATUS_FALSE; + } + + if (encoding) { + context->encoder = codec2_create(); + } + + if (decoding) { + context->decoder = codec2_create(); + } + + codec->private_info = context; + +#ifdef LOG_DATA + { + + int c = c2_count++; + char buf[1024]; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Logging as /tmp/c2-%d-*\n", c); + + if (encoding) { + snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-in", c); + context->encoder_in = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-out", c); + context->encoder_out = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-out-unpacked", c); + context->encoder_out_unpacked = fopen(buf, "w"); + } + if (decoding) { + snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-in", c); + context->decoder_in = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-out", c); + context->decoder_out = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-out-unpacked", c); + context->decoder_in_unpacked = fopen(buf, "w"); + } + } +#endif + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_codec2_encode(switch_codec_t *codec, switch_codec_t *other_codec, + void *decoded_data, + uint32_t decoded_data_len, + uint32_t decoded_rate, + void *encoded_data, + uint32_t *encoded_data_len, + uint32_t *encoded_rate, + unsigned int *flag) +{ + struct codec2_context *context = codec->private_info; + + codec2_assert(decoded_data_len == CODEC2_SAMPLES_PER_FRAME * 2); + +#ifdef LOG_DATA + fwrite(decoded_data, decoded_data_len, 1, context->encoder_in); + fflush(context->encoder_in); +#endif + + codec2_encode(context->encoder, encoded_data, decoded_data); + +#ifdef LOG_DATA + fwrite(encode_buf, sizeof(encode_buf), 1, context->encoder_out_unpacked); + fflush(context->encoder_out_unpacked); + fwrite(encoded_data, 8, 1, context->encoder_out); + fflush(context->encoder_out); +#endif + + *encoded_data_len = 8; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_codec2_decode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *encoded_data, + uint32_t encoded_data_len, + uint32_t encoded_rate, + void *decoded_data, + uint32_t *decoded_data_len, + uint32_t *decoded_rate, + unsigned int *flag) +{ + struct codec2_context *context = codec->private_info; + + codec2_assert(encoded_data_len == 8 /* aligned to 8 */); + +#ifdef LOG_DATA + fwrite(encoded_data, encoded_data_len, 1, context->decoder_in); + fflush(context->decoder_in); + fwrite(bits, sizeof(bits), 1, context->decoder_in_unpacked); + fflush(context->decoder_in_unpacked); +#endif + + codec2_decode(context->decoder, decoded_data, encoded_data); + +#ifdef LOG_DATA + fwrite(decoded_data, CODEC2_SAMPLES_PER_FRAME, 2, context->decoder_out); + fflush(context->decoder_out); +#endif + + *decoded_data_len = CODEC2_SAMPLES_PER_FRAME * 2; /* 160 samples */ + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_codec2_destroy(switch_codec_t *codec) +{ + struct codec2_context *context = codec->private_info; + + codec2_destroy(context->encoder); + codec2_destroy(context->decoder); + + context->encoder = NULL; + context->decoder = NULL; + +#ifdef LOG_DATA + if (context->encoder_in) { + fclose(context->encoder_in); + } + if (context->encoder_out) { + fclose(context->encoder_out); + } + if (context->encoder_out_unpacked) { + fclose(context->encoder_out_unpacked); + } + if (context->decoder_in) { + fclose(context->decoder_in); + } + if (context->decoder_in_unpacked) { + fclose(context->decoder_in_unpacked); + } + if (context->decoder_out) { + fclose(context->decoder_out); + } +#endif + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load) +{ + switch_codec_interface_t *codec_interface; + + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_CODEC(codec_interface, "CODEC2 2550bps"); + + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, + 111, + "CODEC2", + NULL, + 8000, /* samples/sec */ + 8000, /* samples/sec */ + 2550, /* bps */ + 20000, /* ptime */ + CODEC2_SAMPLES_PER_FRAME, /* samples decoded */ + CODEC2_SAMPLES_PER_FRAME*2, /* bytes decoded */ + 0, /* bytes encoded */ + 1, /* channels */ + 1, /* frames/packet */ + switch_codec2_init, + switch_codec2_encode, + switch_codec2_decode, + switch_codec2_destroy); + + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/codecs/mod_ilbc/mod_ilbc.c b/src/mod/codecs/mod_ilbc/mod_ilbc.c index b37056c393..85298375db 100644 --- a/src/mod/codecs/mod_ilbc/mod_ilbc.c +++ b/src/mod/codecs/mod_ilbc/mod_ilbc.c @@ -40,6 +40,27 @@ struct ilbc_context { ilbc_decode_state_t decoder_object; }; +static switch_status_t switch_ilbc_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + char *mode = NULL; + int codec_ms = 0; + + memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + + if (fmtp && (mode = strstr(fmtp, "mode=")) && (mode + 5)) { + codec_ms = atoi(mode + 5); + } + if (!codec_ms) { + /* default to 30 when no mode is defined for ilbc ONLY */ + codec_ms = 30; + } + codec_fmtp->microseconds_per_packet = (codec_ms * 1000); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct ilbc_context *context; @@ -51,26 +72,6 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag return SWITCH_STATUS_FALSE; } - if (codec->fmtp_in) { - int x, argc; - char *argv[10]; - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - switch_assert(data); - while (*data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "mode")) { - mode = atoi(arg); - } - } - } - } - codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "mode=%d", mode); if (encoding) { @@ -136,6 +137,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_ilbc_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "iLBC"); + codec_interface->parse_fmtp = switch_ilbc_fmtp_parse; switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 98, /* the IANA code number */ diff --git a/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c b/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c index 3eae9016e5..c84dac4509 100644 --- a/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c +++ b/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c @@ -65,9 +65,6 @@ unsigned long long g_next_session_id = 0; /* hash of sessions (I think a linked list suits better here, but FS does not have the data type) */ static switch_hash_t *g_sessions_hash = NULL; -/* global memory pool provided by FS */ -static switch_memory_pool_t *g_pool = NULL; - typedef struct vocallo_codec_s { int codec_id; /* vocallo codec ID */ int iana; /* IANA code to register in FS */ @@ -128,6 +125,9 @@ struct codec_data { long lastrxseqno; unsigned long rxlost; + /* discarded silence packets */ + unsigned long rxdiscarded; + /* avg Rx time */ switch_time_t avgrxus; switch_time_t last_rx_time; @@ -196,6 +196,8 @@ static int sangoma_create_rtp_port(void *usr_priv, uint32_t host_ip, uint32_t *p static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_req_leg, sngtc_codec_reply_leg_t* codec_reply_leg, void **rtp_fd) { + switch_status_t status; + switch_memory_pool_t *sesspool = NULL; switch_rtp_t *rtp_session = NULL; char codec_ip[255]; switch_rtp_flag_t flags = 0; @@ -205,6 +207,18 @@ static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_r char local_ip[255]; switch_port_t rtp_port; struct sangoma_transcoding_session *sess = usr_priv; + + /* + * We *MUST* use a new pool + * Do not use the session pool since the session may go away while the RTP socket should linger around + * until sangoma_transcode decides to kill it (possibly because the same RTP session is used for a different call) + * also do not use the module pool otherwise memory would keep growing because switch_rtp_destroy does not + * free the memory used (is assumed it'll be freed when the pool is destroyed) + */ + status = switch_core_new_memory_pool(&sesspool); + if (status != SWITCH_STATUS_SUCCESS) { + return -1; + } rtp_port = (switch_port_t)(long)*rtp_fd; @@ -219,20 +233,20 @@ static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_r local_ip, rtp_port, codec_ip, codec_reply_leg->codec_udp_port, iana, codec_req_leg->ms*1000, sess->sessid); - /* create the RTP socket, dont use the session pool since the session may go away while the RTP socket should linger around - * until sangoma_transcode decides to kill it (possibly because the same RTP session is used for a different call) */ + /* create the RTP socket */ rtp_session = switch_rtp_new(local_ip, rtp_port, codec_ip, codec_reply_leg->codec_udp_port, iana, sess->impl->samples_per_packet, codec_req_leg->ms * 1000, /* microseconds per packet */ - flags, NULL, &err, g_pool); + flags, NULL, &err, sesspool); if (!rtp_session) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create switch rtp session: %s\n", err); + switch_core_destroy_memory_pool(&sesspool); return -1; } - + switch_rtp_set_private(rtp_session, sesspool); *rtp_fd = rtp_session; return 0; @@ -240,8 +254,11 @@ static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_r static int sangoma_destroy_rtp(void *usr_priv, void *fd) { + switch_memory_pool_t *sesspool; switch_rtp_t *rtp = fd; + sesspool = switch_rtp_get_private(rtp); switch_rtp_destroy(&rtp); + switch_core_destroy_memory_pool(&sesspool); return 0; } @@ -404,45 +421,57 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec /* do the reading */ memset(&encoded_frame, 0, sizeof(encoded_frame)); - sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK); - if (sres == SWITCH_STATUS_GENERR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session: %d\n", sres); - return SWITCH_STATUS_FALSE; - } - - if (0 == encoded_frame.datalen) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on Sangoma encoder RTP session.\n"); - return SWITCH_STATUS_SUCCESS; - } - - if (encoded_frame.payload != codec->implementation->ianacode - && encoded_frame.payload != IANACODE_CN) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting %d\n", - encoded_frame.payload, codec->implementation->ianacode); - return SWITCH_STATUS_FALSE; - } - memcpy(encoded_data, encoded_frame.data, encoded_frame.datalen); - *encoded_data_len = encoded_frame.datalen; - - /* update encoding stats */ - sess->encoder.rx++; - - now_time = switch_micro_time_now(); - if (!sess->encoder.last_rx_time) { - sess->encoder.last_rx_time = now_time; - } else { - difftime = now_time - sess->encoder.last_rx_time; - sess->encoder.avgrxus = sess->encoder.avgrxus ? ((sess->encoder.avgrxus + difftime)/2) : difftime; - sess->encoder.last_rx_time = now_time; - } - - /* check sequence and bump lost rx packets count if needed */ - if (sess->encoder.lastrxseqno >= 0) { - if (encoded_frame.seq > (sess->encoder.lastrxseqno + 2) ) { - sess->encoder.rxlost += encoded_frame.seq - sess->encoder.lastrxseqno - 1; + for ( ; ; ) { + sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK); + if (sres == SWITCH_STATUS_GENERR) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session: %d\n", sres); + return SWITCH_STATUS_FALSE; } + + if (0 == encoded_frame.datalen) { + break; + } + + if (encoded_frame.payload != codec->implementation->ianacode + && encoded_frame.payload != IANACODE_CN) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting %d\n", + encoded_frame.payload, codec->implementation->ianacode); + break; + } + + if (*encoded_data_len) { + sess->encoder.rxdiscarded++; + } + + memcpy(encoded_data, encoded_frame.data, encoded_frame.datalen); + *encoded_data_len = encoded_frame.datalen; + } + + /* update encoding stats if we received a frame */ + if (*encoded_data_len) { + if (*encoded_data_len != codec->implementation->encoded_bytes_per_packet) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Returning odd encoded frame of %d bytes intead of %d bytes\n", *encoded_data_len, codec->implementation->encoded_bytes_per_packet); + } + sess->encoder.rx++; + now_time = switch_micro_time_now(); + if (!sess->encoder.last_rx_time) { + sess->encoder.last_rx_time = now_time; + } else { + difftime = now_time - sess->encoder.last_rx_time; + sess->encoder.avgrxus = sess->encoder.avgrxus ? ((sess->encoder.avgrxus + difftime)/2) : difftime; + sess->encoder.last_rx_time = now_time; + } + + /* check sequence and bump lost rx packets count if needed */ + if (sess->encoder.lastrxseqno >= 0) { + if (encoded_frame.seq > (sess->encoder.lastrxseqno + 2) ) { + sess->encoder.rxlost += encoded_frame.seq - sess->encoder.lastrxseqno - 1; + } + } + sess->encoder.lastrxseqno = encoded_frame.seq; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output from sangoma encoder\n"); } - sess->encoder.lastrxseqno = encoded_frame.seq; return SWITCH_STATUS_SUCCESS; } @@ -518,49 +547,63 @@ static switch_status_t switch_sangoma_decode(switch_codec_t *codec, /* codec ses /* do the reading */ memset(&ulaw_frame, 0, sizeof(ulaw_frame)); - sres = switch_rtp_zerocopy_read_frame(sess->decoder.rxrtp, &ulaw_frame, SWITCH_IO_FLAG_NOBLOCK); - if (sres == SWITCH_STATUS_GENERR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma decoder RTP session: %d\n", sres); - return SWITCH_STATUS_FALSE; - } - - if (0 == ulaw_frame.datalen) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on Sangoma decoder RTP session.\n"); - return SWITCH_STATUS_SUCCESS; - } - - if (ulaw_frame.payload != IANA_ULAW - && ulaw_frame.payload != IANACODE_CN) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma decoder RTP session, expecting %d\n", - ulaw_frame.payload, IANA_ULAW); - return SWITCH_STATUS_FALSE; - } - - /* transcode to linear */ - for (i = 0; i < ulaw_frame.datalen; i++) { - dbuf_linear[i] = ulaw_to_linear(((char *)ulaw_frame.data)[i]); - } - *decoded_data_len = i * 2; - - /* update decoding stats */ - sess->decoder.rx++; - - now_time = switch_micro_time_now(); - if (!sess->decoder.last_rx_time) { - sess->decoder.last_rx_time = now_time; - } else { - difftime = now_time - sess->decoder.last_rx_time; - sess->decoder.avgrxus = sess->decoder.avgrxus ? ((sess->decoder.avgrxus + difftime)/2) : difftime; - sess->decoder.last_rx_time = now_time; - } - - /* check sequence and bump lost rx packets count if needed */ - if (sess->decoder.lastrxseqno >= 0) { - if (ulaw_frame.seq > (sess->decoder.lastrxseqno + 2) ) { - sess->decoder.rxlost += ulaw_frame.seq - sess->decoder.lastrxseqno - 1; + for ( ; ; ) { + sres = switch_rtp_zerocopy_read_frame(sess->decoder.rxrtp, &ulaw_frame, SWITCH_IO_FLAG_NOBLOCK); + if (sres == SWITCH_STATUS_GENERR) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma decoder RTP session: %d\n", sres); + return SWITCH_STATUS_FALSE; } + + if (0 == ulaw_frame.datalen) { + break; + } + + if (ulaw_frame.payload != IANA_ULAW + && ulaw_frame.payload != IANACODE_CN) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma decoder RTP session, expecting %d\n", + ulaw_frame.payload, IANA_ULAW); + break; + } + + if (*decoded_data_len) { + sess->decoder.rxdiscarded++; + } + + /* transcode to linear */ + for (i = 0; i < ulaw_frame.datalen; i++) { + dbuf_linear[i] = ulaw_to_linear(((char *)ulaw_frame.data)[i]); + } + *decoded_data_len = i * 2; + } + + if (*decoded_data_len) { + if (*decoded_data_len != codec->implementation->decoded_bytes_per_packet) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Returning odd decoded frame of %d bytes intead of %d bytes\n", *decoded_data_len, codec->implementation->decoded_bytes_per_packet); + } + /* update decoding stats */ + sess->decoder.rx++; + + now_time = switch_micro_time_now(); + if (!sess->decoder.last_rx_time) { + sess->decoder.last_rx_time = now_time; + } else { + difftime = now_time - sess->decoder.last_rx_time; + sess->decoder.avgrxus = sess->decoder.avgrxus ? ((sess->decoder.avgrxus + difftime)/2) : difftime; + sess->decoder.last_rx_time = now_time; + } + + /* check sequence and bump lost rx packets count if needed */ + if (sess->decoder.lastrxseqno >= 0) { + if (ulaw_frame.seq > (sess->decoder.lastrxseqno + 2) ) { + sess->decoder.rxlost += ulaw_frame.seq - sess->decoder.lastrxseqno - 1; + } + } + sess->decoder.lastrxseqno = ulaw_frame.seq; + } else { + *decoded_data_len = codec->implementation->decoded_bytes_per_packet; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output from sangoma decoder, returning silent frame of %d bytes\n", *decoded_data_len); + memset(dbuf_linear, 0, *decoded_data_len); } - sess->decoder.lastrxseqno = ulaw_frame.seq; return SWITCH_STATUS_SUCCESS; } @@ -709,27 +752,41 @@ SWITCH_STANDARD_API(sangoma_function) stream->write_function(stream, "Failed to find session %lu\n", sessid); goto done; } - stream->write_function(stream, "Session: %lu\n", sessid); + stream->write_function(stream, "Stats for transcoding session: %lu\n", sessid); if (sess->encoder.rxrtp) { stats = switch_rtp_get_stats(sess->encoder.rxrtp, NULL); + stream->write_function(stream, "=== Encoder ===\n"); + + stream->write_function(stream, "Remote address: %s:%d\n\n", switch_rtp_get_remote_host(sess->encoder.rxrtp), switch_rtp_get_remote_port(sess->encoder.rxrtp)); + stream->write_function(stream, "-- Encoder Inbound Stats --\n"); + stream->write_function(stream, "Rx Discarded: %lu\n", sess->encoder.rxdiscarded); sangoma_print_stats(stream, &stats->inbound); stats = switch_rtp_get_stats(sess->encoder.txrtp, NULL); stream->write_function(stream, "-- Encoder Outbound Stats --\n"); sangoma_print_stats(stream, &stats->outbound); + } else { + stream->write_function(stream, "\n=== No Encoder ===\n\n"); } if (sess->decoder.rxrtp) { stats = switch_rtp_get_stats(sess->decoder.rxrtp, NULL); + + stream->write_function(stream, "=== Decoder ===\n"); + stream->write_function(stream, "Remote address: %s:%d\n\n", switch_rtp_get_remote_host(sess->decoder.rxrtp), switch_rtp_get_remote_port(sess->decoder.rxrtp)); + stream->write_function(stream, "-- Decoder Inbound Stats --\n"); + stream->write_function(stream, "Rx Discarded: %lu\n", sess->decoder.rxdiscarded); sangoma_print_stats(stream, &stats->inbound); stats = switch_rtp_get_stats(sess->decoder.txrtp, NULL); stream->write_function(stream, "-- Decoder Outbound Stats --\n"); sangoma_print_stats(stream, &stats->outbound); + } else { + stream->write_function(stream, "\n=== No Decoder ===\n\n"); } } else { stream->write_function(stream, "Unknown Command [%s]\n", argv[0]); @@ -861,8 +918,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sangoma_codec_load) return SWITCH_STATUS_FALSE; } - g_pool = pool; - g_init_cfg.log = sangoma_logger; g_init_cfg.create_rtp = sangoma_create_rtp; g_init_cfg.create_rtp_port = sangoma_create_rtp_port; diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index 9d0abcdf8b..934c9ebe32 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -41,6 +41,22 @@ SWITCH_MODULE_DEFINITION(mod_silk, mod_silk_load, NULL, NULL); #define MAX_LBRR_DELAY 2 #define MAX_FRAME_LENGTH 480 +/*! \brief Various codec settings */ +struct silk_codec_settings { + SKP_int useinbandfec; + SKP_int usedtx; + SKP_int maxaveragebitrate; + SKP_int plpct; +}; +typedef struct silk_codec_settings silk_codec_settings_t; + +static silk_codec_settings_t default_codec_settings = { + /*.useinbandfec */ 0, + /*.usedtx */ 0, + /*.maxaveragebitrate */ 0, + /*.plpct */ 10, // 10% for now +}; + struct silk_context { SKP_SILK_SDK_EncControlStruct encoder_object; SKP_SILK_SDK_DecControlStruct decoder_object; @@ -48,12 +64,105 @@ struct silk_context { void *dec_state; }; +static switch_status_t switch_silk_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + silk_codec_settings_t *codec_settings = NULL; + + if (codec_fmtp->private_info) { + codec_settings = codec_fmtp->private_info; + memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); + } + + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + if (codec_settings) { + if (!strcasecmp(data, "useinbandfec")) { + if (switch_true(arg)) { + codec_settings->useinbandfec = 1; + } + } + if (!strcasecmp(data, "usedtx")) { + if (switch_true(arg)) { + codec_settings->usedtx = 1; + } + } + if (!strcasecmp(data, "maxaveragebitrate")) { + codec_settings->maxaveragebitrate = atoi(arg); + switch(codec_fmtp->actual_samples_per_second) { + case 8000: + { + if(codec_settings->maxaveragebitrate < 6000 || codec_settings->maxaveragebitrate > 20000) { + codec_settings->maxaveragebitrate = 20000; + } + break; + } + case 12000: + { + if(codec_settings->maxaveragebitrate < 7000 || codec_settings->maxaveragebitrate > 25000) { + codec_settings->maxaveragebitrate = 25000; + } + break; + } + case 16000: + { + if(codec_settings->maxaveragebitrate < 8000 || codec_settings->maxaveragebitrate > 30000) { + codec_settings->maxaveragebitrate = 30000; + } + break; + } + case 24000: + { + if(codec_settings->maxaveragebitrate < 12000 || codec_settings->maxaveragebitrate > 40000) { + codec_settings->maxaveragebitrate = 40000; + } + break; + } + + default: + /* this should never happen but 20000 is common among all rates */ + codec_settings->maxaveragebitrate = 20000; + break; + } + + } + + } + } + } + free(fmtp_dup); + } + //codec_fmtp->bits_per_second = bit_rate; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + + + + static switch_status_t switch_silk_init(switch_codec_t *codec, switch_codec_flag_t freeswitch_flags, const switch_codec_settings_t *codec_settings) { struct silk_context *context = NULL; - SKP_int useinbandfec = 0, usedtx = 0, maxaveragebitrate = 0, plpct =0; + switch_codec_fmtp_t codec_fmtp; + silk_codec_settings_t silk_codec_settings; SKP_int32 encSizeBytes; SKP_int32 decSizeBytes; int encoding = (freeswitch_flags & SWITCH_CODEC_FLAG_ENCODE); @@ -62,78 +171,15 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } - - if (codec->fmtp_in) { - int x, argc; - char *argv[10]; - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - switch_assert(data); - while (*data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "useinbandfec")) { - if (switch_true(arg)) { - useinbandfec = 1; - plpct = 10;// 10% for now - } - } - if (!strcasecmp(data, "usedtx")) { - if (switch_true(arg)) { - usedtx = 1; - } - } - if (!strcasecmp(data, "maxaveragebitrate")) { - maxaveragebitrate = atoi(arg); - switch(codec->implementation->actual_samples_per_second) { - case 8000: - { - if(maxaveragebitrate < 6000 || maxaveragebitrate > 20000) { - maxaveragebitrate = 20000; - } - break; - } - case 12000: - { - if(maxaveragebitrate < 7000 || maxaveragebitrate > 25000) { - maxaveragebitrate = 25000; - } - break; - } - case 16000: - { - if(maxaveragebitrate < 8000 || maxaveragebitrate > 30000) { - maxaveragebitrate = 30000; - } - break; - } - case 24000: - { - if(maxaveragebitrate < 12000 || maxaveragebitrate > 40000) { - maxaveragebitrate = 40000; - } - break; - } - - default: - /* this should never happen but 20000 is common among all rates */ - maxaveragebitrate = 20000; - break; - } - - } - } - } - } + + memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + codec_fmtp.private_info = &silk_codec_settings; + switch_silk_fmtp_parse(codec->fmtp_in, &codec_fmtp); codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "useinbandfec=%s; usedtx=%s; maxaveragebitrate=%d", - useinbandfec ? "1" : "0", - usedtx ? "1" : "0", - maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second); + silk_codec_settings.useinbandfec ? "1" : "0", + silk_codec_settings.usedtx ? "1" : "0", + silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second); if (encoding) { if (SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes)) { @@ -148,11 +194,11 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, context->encoder_object.sampleRate = codec->implementation->actual_samples_per_second; context->encoder_object.packetSize = codec->implementation->samples_per_packet; - context->encoder_object.useInBandFEC = useinbandfec; + context->encoder_object.useInBandFEC = silk_codec_settings.useinbandfec; context->encoder_object.complexity = 0; - context->encoder_object.bitRate = maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second; - context->encoder_object.useDTX = usedtx; - context->encoder_object.packetLossPercentage = plpct;; + context->encoder_object.bitRate = silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second; + context->encoder_object.useDTX = silk_codec_settings.usedtx; + context->encoder_object.packetLossPercentage = silk_codec_settings.plpct; } if (decoding) { @@ -174,7 +220,7 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, static switch_status_t switch_silk_destroy(switch_codec_t *codec) { - codec->private_info = NULL; + codec->private_info = NULL; return SWITCH_STATUS_SUCCESS; } @@ -299,6 +345,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_silk_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "SILK"); + codec_interface->parse_fmtp = switch_silk_fmtp_parse; switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 117, /* the IANA code number */ diff --git a/src/mod/codecs/mod_siren/mod_siren.c b/src/mod/codecs/mod_siren/mod_siren.c index 1ccd36eafb..4646ffc5ae 100644 --- a/src/mod/codecs/mod_siren/mod_siren.c +++ b/src/mod/codecs/mod_siren/mod_siren.c @@ -47,6 +47,40 @@ struct siren_context { g722_1_encode_state_t encoder_object; }; +static switch_status_t switch_siren_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + int bit_rate = 0; + memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + if (!strcasecmp(data, "bitrate")) { + bit_rate = atoi(arg); + } + } + } + free(fmtp_dup); + } + codec_fmtp->bits_per_second = bit_rate; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct siren_context *context = NULL; @@ -58,26 +92,6 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla return SWITCH_STATUS_FALSE; } - if (codec->fmtp_in) { - int x, argc; - char *argv[10]; - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - switch_assert(data); - while (*data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "bitrate")) { - bit_rate = atoi(arg); - } - } - } - } - codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate); if (encoding) { @@ -145,6 +159,28 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_siren_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "Polycom(R) G722.1/G722.1C"); + codec_interface->parse_fmtp = switch_siren_fmtp_parse; + + spf = 320, bpf = 640; + for (count = 3; count > 0; count--) { + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 107, /* the IANA code number */ + "G7221", /* the IANA code name */ + "bitrate=24000", /* default fmtp to send (can be overridden by the init function) */ + 16000, /* samples transferred per second */ + 16000, /* actual samples transferred per second */ + 24000, /* bits transferred per second */ + mpf * count, /* number of microseconds per frame */ + spf * count, /* number of samples per frame */ + bpf * count, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_siren_init, /* function to initialize a codec handle using this implementation */ + switch_siren_encode, /* function to encode raw data into encoded data */ + switch_siren_decode, /* function to decode encoded data into raw data */ + switch_siren_destroy); /* deinitalize a codec handle using this implementation */ + } spf = 320, bpf = 640; for (count = 3; count > 0; count--) { diff --git a/src/mod/codecs/mod_speex/mod_speex.c b/src/mod/codecs/mod_speex/mod_speex.c index 1d4a0409b8..a951b12d84 100644 --- a/src/mod/codecs/mod_speex/mod_speex.c +++ b/src/mod/codecs/mod_speex/mod_speex.c @@ -37,7 +37,46 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load); SWITCH_MODULE_DEFINITION(mod_speex, mod_speex_load, NULL, NULL); -static switch_codec_settings_t default_codec_settings = { +/* nobody has more setting than speex so we will let them set the standard */ +/*! \brief Various codec settings (currently only relevant to speex) */ +struct speex_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; +}; + +typedef struct speex_codec_settings speex_codec_settings_t; + +static speex_codec_settings_t default_codec_settings = { /*.quality */ 5, /*.complexity */ 5, /*.enhancement */ 1, @@ -58,6 +97,7 @@ static switch_codec_settings_t default_codec_settings = { struct speex_context { switch_codec_t *codec; + speex_codec_settings_t codec_settings; unsigned int flags; /* Encoder */ @@ -74,6 +114,56 @@ struct speex_context { int decoder_mode; }; +static switch_status_t switch_speex_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + speex_codec_settings_t *codec_settings = NULL; + if (codec_fmtp->private_info) { + codec_settings = codec_fmtp->private_info; + memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); + } + + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + /* + if (!strcasecmp(data, "bitrate")) { + bit_rate = atoi(arg); + } + */ + /* + if (codec_settings) { + if (!strcasecmp(data, "vad")) { + bit_rate = atoi(arg); + } + } + */ + } + } + free(fmtp_dup); + } + /*codec_fmtp->bits_per_second = bit_rate;*/ + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + + static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct speex_context *context = NULL; @@ -82,16 +172,18 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - if (!codec_settings) { - codec_settings = &default_codec_settings; - } - - memcpy(&codec->codec_settings, codec_settings, sizeof(codec->codec_settings)); - if (!(encoding || decoding) || ((context = switch_core_alloc(codec->memory_pool, sizeof(*context))) == 0)) { return SWITCH_STATUS_FALSE; } else { const SpeexMode *mode = NULL; + switch_codec_fmtp_t codec_fmtp; + speex_codec_settings_t codec_settings; + + memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + codec_fmtp.private_info = &codec_settings; + switch_speex_fmtp_parse(codec->fmtp_in, &codec_fmtp); + + memcpy(&context->codec_settings, &codec_settings, sizeof(context->codec_settings)); context->codec = codec; if (codec->implementation->actual_samples_per_second == 8000) { @@ -110,41 +202,41 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla speex_bits_init(&context->encoder_bits); context->encoder_state = speex_encoder_init(mode); speex_encoder_ctl(context->encoder_state, SPEEX_GET_FRAME_SIZE, &context->encoder_frame_size); - speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &codec->codec_settings.complexity); - if (codec->codec_settings.preproc) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &context->codec_settings.complexity); + if (context->codec_settings.preproc) { context->pp = speex_preprocess_state_init(context->encoder_frame_size, codec->implementation->actual_samples_per_second); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &codec->codec_settings.pp_vad); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &codec->codec_settings.pp_agc); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &codec->codec_settings.pp_agc_level); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &codec->codec_settings.pp_denoise); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &codec->codec_settings.pp_dereverb); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &codec->codec_settings.pp_dereverb_decay); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &codec->codec_settings.pp_dereverb_level); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &context->codec_settings.pp_vad); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &context->codec_settings.pp_agc); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &context->codec_settings.pp_agc_level); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &context->codec_settings.pp_denoise); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &context->codec_settings.pp_dereverb); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &context->codec_settings.pp_dereverb_decay); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &context->codec_settings.pp_dereverb_level); } - if (!codec->codec_settings.abr && !codec->codec_settings.vbr) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &codec->codec_settings.quality); - if (codec->codec_settings.vad) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &codec->codec_settings.vad); + if (!context->codec_settings.abr && !context->codec_settings.vbr) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &context->codec_settings.quality); + if (context->codec_settings.vad) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &context->codec_settings.vad); } } - if (codec->codec_settings.vbr) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &codec->codec_settings.vbr); - speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &codec->codec_settings.vbr_quality); + if (context->codec_settings.vbr) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &context->codec_settings.vbr); + speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &context->codec_settings.vbr_quality); } - if (codec->codec_settings.abr) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &codec->codec_settings.abr); + if (context->codec_settings.abr) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &context->codec_settings.abr); } - if (codec->codec_settings.dtx) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &codec->codec_settings.dtx); + if (context->codec_settings.dtx) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &context->codec_settings.dtx); } } if (decoding) { speex_bits_init(&context->decoder_bits); context->decoder_state = speex_decoder_init(mode); - if (codec->codec_settings.enhancement) { - speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &codec->codec_settings.enhancement); + if (context->codec_settings.enhancement) { + speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &context->codec_settings.enhancement); } } @@ -178,7 +270,7 @@ static switch_status_t switch_speex_encode(switch_codec_t *codec, if (is_speech) { is_speech = speex_encode_int(context->encoder_state, buf, &context->encoder_bits) - || !context->codec->codec_settings.dtx; + || !context->codec_settings.dtx; } else { speex_bits_pack(&context->encoder_bits, 0, 5); } @@ -270,6 +362,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load) /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "Speex"); + codec_interface->parse_fmtp = switch_speex_fmtp_parse; for (counta = 1; counta <= 3; counta++) { for (countb = 1; countb > 0; countb--) { switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 8275893be8..ab4db6a1b0 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -52,7 +52,8 @@ typedef enum { TFLAG_BRIDGE = (1 << 4), TFLAG_BOWOUT = (1 << 5), TFLAG_BLEG = (1 << 6), - TFLAG_APP = (1 << 7) + TFLAG_APP = (1 << 7), + TFLAG_BOWOUT_USED = (1 << 8) } TFLAGS; struct private_object { @@ -635,7 +636,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); - if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || switch_test_flag(tech_pvt, TFLAG_BOWOUT)) { + if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { return SWITCH_STATUS_SUCCESS; } @@ -662,6 +663,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc switch_clear_flag_locked(tech_pvt, TFLAG_WRITE); switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE); + switch_set_flag_locked(tech_pvt, TFLAG_BOWOUT_USED); + switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_BOWOUT_USED); + if (a_uuid && b_uuid) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s detected bridge on both ends, attempting direct connection.\n", switch_channel_get_name(channel)); diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 165815078b..2df8937647 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -1343,19 +1343,6 @@ static switch_status_t kill_listener(listener_t *listener, void *pvt) return SWITCH_STATUS_SUCCESS; } -static switch_status_t kill_expired_listener(listener_t *listener, void *pvt) -{ - switch_event_t *event = NULL; - - if(listener->expire_time < switch_epoch_time_now(NULL)) { - /* skinny::expire event */ - skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE); - switch_event_fire(&event); - return kill_listener(listener, pvt); - } - return SWITCH_STATUS_SUCCESS; -} - switch_status_t keepalive_listener(listener_t *listener, void *pvt) { skinny_profile_t *profile; @@ -1414,6 +1401,13 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) case SWITCH_STATUS_TIMEOUT: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Communication Time Out with %s:%d.\n", listener->remote_ip, listener->remote_port); + + if(listener->expire_time < switch_epoch_time_now(NULL)) { + switch_event_t *event = NULL; + /* skinny::expire event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE); + switch_event_fire(&event); + } break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Communication Error with %s:%d.\n", @@ -1917,9 +1911,57 @@ static switch_status_t load_skinny_config(void) return SWITCH_STATUS_SUCCESS; } -static void skinny_heartbeat_event_handler(switch_event_t *event) +static void skinny_user_to_device_event_handler(switch_event_t *event) { - walk_listeners(kill_expired_listener, NULL); + char *profile_name = switch_event_get_header_nil(event, "Skinny-Profile-Name"); + skinny_profile_t *profile; + + if ((profile = skinny_find_profile(profile_name))) { + char *device_name = switch_event_get_header_nil(event, "Skinny-Device-Name"); + uint32_t device_instance = atoi(switch_event_get_header_nil(event, "Skinny-Station-Instance")); + listener_t *listener = NULL; + skinny_profile_find_listener_by_device_name_and_instance(profile, device_name, device_instance, &listener); + if(listener) { + uint32_t message_type = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id")); + uint32_t application_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Application-Id")); + uint32_t line_instance = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Line-Instance")); + uint32_t call_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Call-Id")); + uint32_t transaction_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Transaction-Id")); + uint32_t data_length = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Data-Length")); + uint32_t sequence_flag = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Sequence-Flag")); + uint32_t display_priority = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Display-Priority")); + uint32_t conference_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Conference-Id")); + uint32_t app_instance_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-App-Instance-Id")); + uint32_t routing_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Routing-Id")); + char *data = switch_event_get_body(event); + if (message_type == 0) { + message_type = skinny_str2message_type(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id-String")); + } + switch(message_type) { + case USER_TO_DEVICE_DATA_MESSAGE: + data_length = strlen(data); /* we ignore data_length sent */ + send_data(listener, message_type, + application_id, line_instance, call_id, transaction_id, data_length, + data); + case USER_TO_DEVICE_DATA_VERSION1_MESSAGE: + data_length = strlen(data); /* we ignore data_length sent */ + send_extended_data(listener, message_type, + application_id, line_instance, call_id, transaction_id, data_length, + sequence_flag, display_priority, conference_id, app_instance_id, routing_id, + data); + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Incorrect message type %s (%d).\n", skinny_message_type2str(message_type), message_type); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Device %s:%d in profile '%s' not found.\n", device_name, device_instance, profile_name); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Profile '%s' not found.\n", profile_name); + } } static void skinny_call_state_event_handler(switch_event_t *event) @@ -2129,10 +2171,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) return SWITCH_STATUS_TERM; } /* bind to events */ - if ((switch_event_bind_removable(modname, SWITCH_EVENT_HEARTBEAT, NULL, skinny_heartbeat_event_handler, NULL, &globals.heartbeat_node) != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our heartbeat handler!\n"); - /* Not such severe to prevent loading */ - } if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_CALL_STATE, skinny_call_state_event_handler, NULL, &globals.call_state_node) != SWITCH_STATUS_SUCCESS)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our call_state handler!\n"); return SWITCH_STATUS_TERM; @@ -2145,6 +2183,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our trap handler!\n"); /* Not such severe to prevent loading */ } + if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE, skinny_user_to_device_event_handler, NULL, &globals.user_to_device_node) != SWITCH_STATUS_SUCCESS)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our user_to_device handler!\n"); + /* Not such severe to prevent loading */ + } /* reserve events */ if (switch_event_reserve_subclass(SKINNY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) { @@ -2167,6 +2209,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_CALL_STATE); return SWITCH_STATUS_TERM; } + if (switch_event_reserve_subclass(SKINNY_EVENT_USER_TO_DEVICE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_USER_TO_DEVICE); + return SWITCH_STATUS_TERM; + } + if (switch_event_reserve_subclass(SKINNY_EVENT_DEVICE_TO_USER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_DEVICE_TO_USER); + return SWITCH_STATUS_TERM; + } /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(globals.pool, modname); @@ -2205,7 +2255,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown) skinny_api_unregister(); /* release events */ - switch_event_unbind(&globals.heartbeat_node); + switch_event_unbind(&globals.user_to_device_node); switch_event_unbind(&globals.call_state_node); switch_event_unbind(&globals.message_waiting_node); switch_event_unbind(&globals.trap_node); @@ -2214,6 +2264,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown) switch_event_free_subclass(SKINNY_EVENT_EXPIRE); switch_event_free_subclass(SKINNY_EVENT_ALARM); switch_event_free_subclass(SKINNY_EVENT_CALL_STATE); + switch_event_free_subclass(SKINNY_EVENT_USER_TO_DEVICE); + switch_event_free_subclass(SKINNY_EVENT_DEVICE_TO_USER); switch_mutex_lock(mutex); diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index bbd318b746..b5cc96b7ae 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -43,13 +43,15 @@ #define SKINNY_EVENT_EXPIRE "skinny::expire" #define SKINNY_EVENT_ALARM "skinny::alarm" #define SKINNY_EVENT_CALL_STATE "skinny::call_state" +#define SKINNY_EVENT_USER_TO_DEVICE "skinny::user_to_device" +#define SKINNY_EVENT_DEVICE_TO_USER "skinny::device_to_user" struct skinny_globals { int running; switch_memory_pool_t *pool; switch_mutex_t *mutex; switch_hash_t *profile_hash; - switch_event_node_t *heartbeat_node; + switch_event_node_t *user_to_device_node; switch_event_node_t *call_state_node; switch_event_node_t *message_waiting_node; switch_event_node_t *trap_node; diff --git a/src/mod/endpoints/mod_skinny/skinny_api.c b/src/mod/endpoints/mod_skinny/skinny_api.c index 90699d1ad2..7bbb27afd3 100644 --- a/src/mod/endpoints/mod_skinny/skinny_api.c +++ b/src/mod/endpoints/mod_skinny/skinny_api.c @@ -366,6 +366,62 @@ static switch_status_t skinny_api_cmd_profile_device_send_reset_message(const ch return SWITCH_STATUS_SUCCESS; } +static switch_status_t skinny_api_cmd_profile_device_send_data(const char *profile_name, const char *device_name, const char *message_type, char *params, const char *body, switch_stream_handle_t *stream) +{ + skinny_profile_t *profile; + + if ((profile = skinny_find_profile(profile_name))) { + listener_t *listener = NULL; + skinny_profile_find_listener_by_device_name(profile, device_name, &listener); + if(listener) { + switch_event_t *event = NULL; + char *argv[64] = { 0 }; + int argc = 0; + int x = 0; + /* skinny::user_to_device event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Message-Id-String", "%s", message_type); + argc = switch_separate_string(params, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *var_name, *var_value = NULL; + var_name = argv[x]; + if (var_name && (var_value = strchr(var_name, '='))) { + *var_value++ = '\0'; + } + if (zstr(var_name)) { + stream->write_function(stream, "-ERR No variable specified\n"); + } else { + char *tmp = switch_mprintf("Skinny-UserToDevice-%s", var_name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, tmp, "%s", var_value); + switch_safe_free(tmp); + /* + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Application-Id", "%d", request->data.extended_data.application_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Line-Instance", "%d", request->data.extended_data.line_instance); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Call-Id", "%d", request->data.extended_data.call_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Transaction-Id", "%d", request->data.extended_data.transaction_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Data-Length", "%d", request->data.extended_data.data_length); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Sequence-Flag", "%d", request->data.extended_data.sequence_flag); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Display-Priority", "%d", request->data.extended_data.display_priority); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Conference-Id", "%d", request->data.extended_data.conference_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-App-Instance-Id", "%d", request->data.extended_data.app_instance_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Routing-Id", "%d", request->data.extended_data.routing_id); + */ + } + } + switch_event_add_body(event, "%s", body); + switch_event_fire(&event); + stream->write_function(stream, "+OK\n"); + } else { + stream->write_function(stream, "Listener not found!\n"); + } + } else { + stream->write_function(stream, "Profile not found!\n"); + } + + return SWITCH_STATUS_SUCCESS; +} + + static switch_status_t skinny_api_cmd_profile_set(const char *profile_name, const char *name, const char *value, switch_stream_handle_t *stream) { skinny_profile_t *profile; @@ -403,6 +459,7 @@ SWITCH_STANDARD_API(skinny_function) "skinny profile device send SetLampMessage \n" "skinny profile device send SetSpeakerModeMessage \n" "skinny profile device send CallStateMessage \n" + "skinny profile device send [ =;... ] \n" "skinny profile set \n" "--------------------------------------------------------------------------------\n"; if (session) { @@ -465,6 +522,16 @@ SWITCH_STANDARD_API(skinny_function) status = skinny_api_cmd_profile_device_send_reset_message(argv[1], argv[3], argv[6], stream); } break; + case USER_TO_DEVICE_DATA_MESSAGE: + case USER_TO_DEVICE_DATA_VERSION1_MESSAGE: + if(argc == 8) { + /* [ =;... ] */ + status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], argv[6], argv[7], stream); + } else if(argc == 7) { + /* */ + status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], "", argv[6], stream); + } + break; default: stream->write_function(stream, "Unhandled message %s\n", argv[5]); } @@ -495,6 +562,8 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_ switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetLampMessage ::skinny::list_stimuli ::skinny::list_stimulus_instances ::skinny::list_stimulus_modes"); switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetSpeakerModeMessage ::skinny::list_speaker_modes"); switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send CallStateMessage ::skinny::list_call_states ::skinny::list_line_instances ::skinny::list_call_ids"); + switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataMessage"); + switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataVersion1Message"); switch_console_set_complete("add skinny profile ::skinny::list_profiles set ::skinny::list_settings"); switch_console_add_complete_func("::skinny::list_profiles", skinny_api_list_profiles); diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 1aea812574..743514d98c 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -135,6 +135,10 @@ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req) status = switch_socket_recv(listener->sock, ptr, &mlen); + if (listener->expire_time && listener->expire_time < switch_epoch_time_now(NULL)) { + return SWITCH_STATUS_TIMEOUT; + } + if (!listener_is_ready(listener)) { break; } @@ -898,6 +902,68 @@ switch_status_t send_reset(listener_t *listener, uint32_t reset_type) return skinny_send_reply(listener, message); } +switch_status_t send_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + const char *data) +{ + skinny_message_t *message; + switch_assert(data_length == strlen(data)); + /* data_length should be a multiple of 4 */ + if ((data_length % 4) != 0) { + data_length = (data_length / 4 + 1) * 4; + } + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.data)+data_length-1); + message->type = message_type; + message->length = 4 + sizeof(message->data.data)+data_length-1; + message->data.data.application_id = application_id; + message->data.data.line_instance = line_instance; + message->data.data.call_id = call_id; + message->data.data.transaction_id = transaction_id; + message->data.data.data_length = data_length; + strncpy(message->data.data.data, data, data_length); + return skinny_send_reply(listener, message); +} + +switch_status_t send_extended_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + uint32_t sequence_flag, + uint32_t display_priority, + uint32_t conference_id, + uint32_t app_instance_id, + uint32_t routing_id, + const char *data) +{ + skinny_message_t *message; + switch_assert(data_length == strlen(data)); + /* data_length should be a multiple of 4 */ + if ((data_length % 4) != 0) { + data_length = (data_length / 4 + 1) * 4; + } + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.extended_data)+data_length-1); + message->type = message_type; + message->length = 4 + sizeof(message->data.extended_data)+data_length-1; + message->data.extended_data.application_id = application_id; + message->data.extended_data.line_instance = line_instance; + message->data.extended_data.call_id = call_id; + message->data.extended_data.transaction_id = transaction_id; + message->data.extended_data.data_length = data_length; + message->data.extended_data.sequence_flag = sequence_flag; + message->data.extended_data.display_priority = display_priority; + message->data.extended_data.conference_id = conference_id; + message->data.extended_data.app_instance_id = app_instance_id; + message->data.extended_data.routing_id = routing_id; + strncpy(message->data.extended_data.data, data, data_length); + return skinny_send_reply(listener, message); +} + switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file, const char *func, int line, skinny_message_t *reply) { char *ptr; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 236c667509..d85a190ba8 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -174,6 +174,21 @@ struct PACKED register_available_lines_message { uint32_t count; }; +/* DeviceToUserDataMessage */ +#define DEVICE_TO_USER_DATA_MESSAGE 0x002E +struct PACKED data_message { + uint32_t application_id; + uint32_t line_instance; + uint32_t call_id; + uint32_t transaction_id; + uint32_t data_length; + char data[1]; +}; + +/* DeviceToUserDataResponseMessage */ +#define DEVICE_TO_USER_DATA_RESPONSE_MESSAGE 0x002F +/* See struct PACKED data_message */ + /* ServiceUrlStatReqMessage */ #define SERVICE_URL_STAT_REQ_MESSAGE 0x0033 struct PACKED service_url_stat_req_message { @@ -186,6 +201,26 @@ struct PACKED feature_stat_req_message { uint32_t feature_index; }; +/* DeviceToUserDataVersion1Message */ +#define DEVICE_TO_USER_DATA_VERSION1_MESSAGE 0x0041 +struct PACKED extended_data_message { + uint32_t application_id; + uint32_t line_instance; + uint32_t call_id; + uint32_t transaction_id; + uint32_t data_length; + uint32_t sequence_flag; + uint32_t display_priority; + uint32_t conference_id; + uint32_t app_instance_id; + uint32_t routing_id; + char data[1]; +}; + +/* DeviceToUserDataResponseVersion1Message */ +#define DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE 0x0042 +/* See struct PACKED extended_data_message */ + /* RegisterAckMessage */ #define REGISTER_ACK_MESSAGE 0x0081 struct PACKED register_ack_message { @@ -479,6 +514,10 @@ struct PACKED dialed_number_message { uint32_t call_id; }; +/* UserToDeviceDataMessage */ +#define USER_TO_DEVICE_DATA_MESSAGE 0x011E +/* See struct PACKED data_message */ + /* FeatureStatMessage */ #define FEATURE_STAT_RES_MESSAGE 0x011F struct PACKED feature_stat_res_message { @@ -504,6 +543,10 @@ struct PACKED service_url_stat_res_message { char display_name[40]; }; +/* UserToDeviceDataVersion1Message */ +#define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F +/* See struct PACKED extended_data_message */ + /*****************************************************************************/ /* SKINNY MESSAGE */ /*****************************************************************************/ @@ -512,6 +555,7 @@ struct PACKED service_url_stat_res_message { #define SKINNY_MESSAGE_MAXSIZE 1000 union skinny_data { + /* no data for KEEP_ALIVE_MESSAGE */ struct register_message reg; struct port_message port; struct keypad_button_message keypad_button; @@ -520,14 +564,25 @@ union skinny_data { struct on_hook_message on_hook; struct speed_dial_stat_req_message speed_dial_req; struct line_stat_req_message line_req; + /* no data for CONFIG_STAT_REQ_MESSAGE */ + /* no data for TIME_DATE_REQ_MESSAGE */ + /* no data for BUTTON_TEMPLATE_REQ_MESSAGE */ + /* no data for VERSION_REQ_MESSAGE */ struct capabilities_res_message cap_res; struct alarm_message alarm; struct open_receive_channel_ack_message open_receive_channel_ack; + /* no data for SOFT_KEY_SET_REQ_MESSAGE */ struct soft_key_event_message soft_key_event; - struct service_url_stat_req_message service_url_req; - struct feature_stat_req_message feature_req; + /* no data for UNREGISTER_MESSAGE */ + /* no data for SOFT_KEY_TEMPLATE_REQ_MESSAGE */ struct headset_status_message headset_status; struct register_available_lines_message reg_lines; + /* see field "data" for DEVICE_TO_USER_DATA_MESSAGE */ + /* see field "data" for DEVICE_TO_USER_DATA_RESPONSE_MESSAGE */ + struct service_url_stat_req_message service_url_req; + struct feature_stat_req_message feature_req; + /* see field "extended_data" for DEVICE_TO_USER_DATA_VERSION1_MESSAGE */ + /* see field "extended_data" for DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE */ struct register_ack_message reg_ack; struct start_tone_message start_tone; struct stop_tone_message stop_tone; @@ -543,8 +598,10 @@ union skinny_data { struct define_time_date_message define_time_date; struct button_template_message button_template; struct version_message version; + /* no data for CAPABILITIES_REQ_MESSAGE */ struct register_reject_message reg_rej; struct reset_message reset; + /* no data for KEEP_ALIVE_ACK_MESSAGE */ struct open_receive_channel_message open_receive_channel; struct close_receive_channel_message close_receive_channel; struct soft_key_template_res_message soft_key_template; @@ -557,9 +614,14 @@ union skinny_data { struct unregister_ack_message unregister_ack; struct back_space_req_message back_space_req; struct dialed_number_message dialed_number; + /* see field "data" for USER_TO_DEVICE_DATA_MESSAGE */ struct feature_stat_res_message feature_res; struct display_pri_notify_message display_pri_notify; struct service_url_stat_res_message service_url_res; + /* see field "extended_data" for USER_TO_DEVICE_DATA_VERSION1_MESSAGE */ + + struct data_message data; + struct extended_data_message extended_data; uint16_t as_uint16; char as_char; @@ -777,6 +839,27 @@ switch_status_t send_display_pri_notify(listener_t *listener, switch_status_t send_reset(listener_t *listener, uint32_t reset_type); +switch_status_t send_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + const char *data); + +switch_status_t send_extended_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + uint32_t sequence_flag, + uint32_t display_priority, + uint32_t conference_id, + uint32_t app_instance_id, + uint32_t routing_id, + const char *data); + #endif /* _SKINNY_PROTOCOL_H */ /* For Emacs: diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 3fa4aab6c4..cfafea6f01 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1864,6 +1864,33 @@ switch_status_t skinny_handle_register_available_lines_message(listener_t *liste return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_data_message(listener_t *listener, skinny_message_t *request) +{ + switch_event_t *event = NULL; + char *tmp = NULL; + skinny_check_data_length(request, sizeof(request->data.data)); + skinny_check_data_length(request, sizeof(request->data.data) + request->data.data.data_length - 1); + + /* skinny::device_to_user event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.data.application_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.data.line_instance); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.data.call_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.data.transaction_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.data.data_length); + /* Ensure that the body is null-terminated */ + tmp = malloc(request->data.data.data_length + 1); + memcpy(tmp, request->data.data.data, request->data.data.data_length); + tmp[request->data.data.data_length] = '\0'; + switch_event_add_body(event, "%s", tmp); + switch_safe_free(tmp); + switch_event_fire(&event); + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request) { skinny_message_t *message; @@ -1904,6 +1931,38 @@ switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_ return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny_message_t *request) +{ + switch_event_t *event = NULL; + char *tmp = NULL; + skinny_check_data_length(request, sizeof(request->data.extended_data)); + skinny_check_data_length(request, sizeof(request->data.extended_data)+request->data.extended_data.data_length-1); + + /* skinny::device_to_user event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.extended_data.application_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.extended_data.line_instance); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.extended_data.call_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.extended_data.transaction_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.extended_data.data_length); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Sequence-Flag", "%d", request->data.extended_data.sequence_flag); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Display-Priority", "%d", request->data.extended_data.display_priority); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Conference-Id", "%d", request->data.extended_data.conference_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-App-Instance-Id", "%d", request->data.extended_data.app_instance_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Routing-Id", "%d", request->data.extended_data.routing_id); + /* Ensure that the body is null-terminated */ + tmp = malloc(request->data.data.data_length + 1); + memcpy(tmp, request->data.data.data, request->data.data.data_length); + tmp[request->data.data.data_length] = '\0'; + switch_event_add_body(event, "%s", tmp); + switch_safe_free(tmp); + switch_event_fire(&event); + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request) { if (listener->profile->debug >= 10 || request->type != KEEP_ALIVE_MESSAGE) { @@ -1961,10 +2020,18 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_headset_status_message(listener, request); case REGISTER_AVAILABLE_LINES_MESSAGE: return skinny_handle_register_available_lines_message(listener, request); + case DEVICE_TO_USER_DATA_MESSAGE: + return skinny_handle_data_message(listener, request); + case DEVICE_TO_USER_DATA_RESPONSE_MESSAGE: + return skinny_handle_data_message(listener, request); case SERVICE_URL_STAT_REQ_MESSAGE: return skinny_handle_service_url_stat_request(listener, request); case FEATURE_STAT_REQ_MESSAGE: return skinny_handle_feature_stat_request(listener, request); + case DEVICE_TO_USER_DATA_VERSION1_MESSAGE: + return skinny_handle_extended_data_message(listener, request); + case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE: + return skinny_handle_extended_data_message(listener, request); default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 43b2290560..0a27ad76c4 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -55,10 +55,14 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"SoftKeyEventMessage", SOFT_KEY_EVENT_MESSAGE}, {"UnregisterMessage", UNREGISTER_MESSAGE}, {"SoftKeyTemplateReqMessage", SOFT_KEY_TEMPLATE_REQ_MESSAGE}, - {"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE}, - {"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE}, {"HeadsetStatusMessage", HEADSET_STATUS_MESSAGE}, {"RegisterAvailableLinesMessage", REGISTER_AVAILABLE_LINES_MESSAGE}, + {"DeviceToUserDataMessage", DEVICE_TO_USER_DATA_MESSAGE}, + {"DeviceToUserDataResponseMessage", DEVICE_TO_USER_DATA_RESPONSE_MESSAGE}, + {"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE}, + {"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE}, + {"DeviceToUserDataVersion1Message", DEVICE_TO_USER_DATA_VERSION1_MESSAGE}, + {"DeviceToUserDataResponseVersion1Message", DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE}, {"RegisterAckMessage", REGISTER_ACK_MESSAGE}, {"StartToneMessage", START_TONE_MESSAGE}, {"StopToneMessage", STOP_TONE_MESSAGE}, @@ -90,9 +94,11 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE}, {"BackSpaceReqMessage", BACK_SPACE_REQ_MESSAGE}, {"DialedNumberMessage", DIALED_NUMBER_MESSAGE}, + {"UserToDeviceDataMessage", USER_TO_DEVICE_DATA_MESSAGE}, {"FeatureResMessage", FEATURE_STAT_RES_MESSAGE}, {"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE}, {"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE}, + {"UserToDeviceDataVersion1Message", USER_TO_DEVICE_DATA_VERSION1_MESSAGE}, {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage") diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 1747360264..14962b8b78 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -87,7 +87,7 @@ uint32_t func(const char *str)\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[59]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[65]; const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 1e8876e638..36954d2904 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -242,19 +242,18 @@ static switch_status_t sofia_on_execute(switch_core_session_t *session) return SWITCH_STATUS_SUCCESS; } -char *generate_pai_str(switch_core_session_t *session) +char *generate_pai_str(private_object_t *tech_pvt) { - private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); + switch_core_session_t *session = tech_pvt->session; const char *callee_name = NULL, *callee_number = NULL; const char *var, *header, *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent"); char *pai = NULL; - if (!sofia_test_pflag(tech_pvt->profile, PFLAG_CID_IN_1XX) || + if (!sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_CALLEE_ID) || !sofia_test_pflag(tech_pvt->profile, PFLAG_CID_IN_1XX) || ((var = switch_channel_get_variable(tech_pvt->channel, "sip_cid_in_1xx")) && switch_false(var))) { return NULL; } - if (zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_name"))) && zstr((callee_name = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_name")))) { callee_name = switch_channel_get_variable(tech_pvt->channel, "callee_id_name"); @@ -521,7 +520,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) switch_channel_set_variable(channel, "sip_hangup_disposition", "send_refuse"); } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { - char *cid = generate_pai_str(session); + char *cid = generate_pai_str(tech_pvt); nua_respond(tech_pvt->nh, sip_cause, sip_status_phrase(sip_cause), TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), @@ -703,9 +702,9 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX); char *cid = NULL; - if (sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_CALLEE_ID)) { - cid = generate_pai_str(session); - } + + cid = generate_pai_str(tech_pvt); + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp && strcmp(tech_pvt->early_sdp, tech_pvt->local_sdp_str)) { /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless @@ -1238,7 +1237,12 @@ static void start_udptl(private_object_t *tech_pvt, switch_t38_options_t *t38_op switch_rtp_udptl_mode(tech_pvt->rtp_session); - if (remote_host && remote_port && !strcmp(remote_host, t38_options->remote_ip) && remote_port == t38_options->remote_port) { + if (!t38_options || !t38_options->remote_ip) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "No remote address\n"); + return; + } + + if (remote_host && remote_port && remote_port == t38_options->remote_port && !strcmp(remote_host, t38_options->remote_ip)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n", t38_options->remote_ip, t38_options->remote_port); return; @@ -1477,12 +1481,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: { - const char *pl = - "\r\n" - " \r\n" - " \r\n" - " \r\n" - " \r\n" " \r\n" " \r\n" " \r\n" " \r\n"; + const char *pl = ""; + + if (!zstr(msg->string_arg)) { + pl = msg->string_arg; + } nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); @@ -1771,7 +1774,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi nua_update(tech_pvt->nh, TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); - } else if ((ua && (switch_stristr("cisco", ua)))) { + } else if ((ua && (switch_stristr("cisco/spa50", ua) || switch_stristr("cisco/spa525", ua)))) { snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" ", name, number, tech_pvt->profile->sipip); sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY); @@ -1964,7 +1967,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } else if (code == 484 && msg->numeric_arg) { const char *to = switch_channel_get_variable(channel, "sip_to_uri"); const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE); - char *cid = generate_pai_str(session); + char *cid = generate_pai_str(tech_pvt); char *to_uri = NULL; if (to) { @@ -2011,6 +2014,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options"); if (t38_options) { sofia_glue_set_image_sdp(tech_pvt, t38_options, 0); + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_udptl_mode(tech_pvt->rtp_session); + } } } else { sofia_glue_tech_set_local_sdp(tech_pvt, sdp, SWITCH_TRUE); @@ -2059,7 +2065,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi !switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED)) { char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX); const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full"); - char *cid = generate_pai_str(session); + char *cid = generate_pai_str(tech_pvt); switch (ring_ready_val) { @@ -2096,6 +2102,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; case SWITCH_MESSAGE_INDICATE_ANSWER: status = sofia_answer_channel(session); + if (switch_channel_test_flag(tech_pvt->channel, CF_VIDEO)) { + sofia_glue_build_vid_refresh_message(session, NULL); + } break; case SWITCH_MESSAGE_INDICATE_PROGRESS: { @@ -2177,9 +2186,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi char *extra_header = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX); char *cid = NULL; - if (sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_CALLEE_ID)) { - cid = generate_pai_str(session); - } + cid = generate_pai_str(tech_pvt); + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp && strcmp(tech_pvt->early_sdp, tech_pvt->local_sdp_str)) { @@ -2321,7 +2329,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam switch_time_t etime = atoi(argv[6]); switch_size_t retsize; - exp_secs = etime - now; + exp_secs = (int)(etime - now); switch_time_exp_lt(&tm, switch_time_from_sec(etime)); switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm); } @@ -2361,7 +2369,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum switch_time_t etime = atoi(argv[6]); switch_size_t retsize; - exp_secs = etime - now; + exp_secs = (int)(etime - now); switch_time_exp_lt(&tm, switch_time_from_sec(etime)); switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm); } @@ -2428,7 +2436,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t ob_failed += gp->ob_failed_calls; ob += gp->ob_calls; - stream->write_function(stream, "%25s\t%32s\t%s\t%ld/%ld\t%ld/%ld", + stream->write_function(stream, "%25s\t%32s\t%s\t%u/%u\t%u/%u", pkey, gp->register_to, sofia_state_names[gp->state], gp->ib_failed_calls, gp->ib_calls, gp->ob_failed_calls, gp->ob_calls); @@ -2447,8 +2455,8 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t } switch_mutex_unlock(mod_sofia_globals.hash_mutex); stream->write_function(stream, "%s\n", line); - stream->write_function(stream, "%d gateway%s: Inound(Failed/Total): %ld/%ld," - "Outbound(Failed/Total):%ld/%ld\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob); + stream->write_function(stream, "%d gateway%s: Inbound(Failed/Total): %u/%u," + "Outbound(Failed/Total):%u/%u\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob); return SWITCH_STATUS_SUCCESS; } @@ -2477,10 +2485,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t stream->write_function(stream, "PingState\t%d/%d/%d\n", gp->ping_min, gp->ping_count, gp->ping_max); stream->write_function(stream, "State \t%s\n", sofia_state_names[gp->state]); stream->write_function(stream, "Status \t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); - stream->write_function(stream, "CallsIN \t%d\n", gp->ib_calls); - stream->write_function(stream, "CallsOUT\t%d\n", gp->ob_calls); - stream->write_function(stream, "FailedCallsIN\t%d\n", gp->ib_failed_calls); - stream->write_function(stream, "FailedCallsOUT\t%d\n", gp->ob_failed_calls); + stream->write_function(stream, "CallsIN \t%u\n", gp->ib_calls); + stream->write_function(stream, "CallsOUT\t%u\n", gp->ob_calls); + stream->write_function(stream, "FailedCallsIN\t%u\n", gp->ib_failed_calls); + stream->write_function(stream, "FailedCallsOUT\t%u\n", gp->ob_failed_calls); stream->write_function(stream, "%s\n", line); sofia_reg_release_gateway(gp); } else { @@ -2489,7 +2497,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t } else if (!strcasecmp(argv[0], "profile")) { struct cb_helper cb; char *sql = NULL; - int x = 0; + uint32_t x = 0; cb.row_process = 0; @@ -2554,10 +2562,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t if (profile->max_registrations_perext > 0) { stream->write_function(stream, "MAX-REG-PEREXT \t%d\n", profile->max_registrations_perext); } - stream->write_function(stream, "CALLS-IN \t%d\n", profile->ib_calls); - stream->write_function(stream, "FAILED-CALLS-IN \t%d\n", profile->ib_failed_calls); - stream->write_function(stream, "CALLS-OUT \t%d\n", profile->ob_calls); - stream->write_function(stream, "FAILED-CALLS-OUT \t%d\n", profile->ob_failed_calls); + stream->write_function(stream, "CALLS-IN \t%u\n", profile->ib_calls); + stream->write_function(stream, "FAILED-CALLS-IN \t%u\n", profile->ib_failed_calls); + stream->write_function(stream, "CALLS-OUT \t%u\n", profile->ob_calls); + stream->write_function(stream, "FAILED-CALLS-OUT \t%u\n", profile->ob_failed_calls); } stream->write_function(stream, "\nRegistrations:\n%s\n", line); @@ -2703,10 +2711,10 @@ static void xml_gateway_status(sofia_gateway_t *gp, switch_stream_handle_t *stre stream->write_function(stream, " %d\n", gp->ping_freq); stream->write_function(stream, " %s\n", sofia_state_names[gp->state]); stream->write_function(stream, " %s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); - stream->write_function(stream, " %d\n", gp->ib_calls); - stream->write_function(stream, " %d\n", gp->ob_calls); - stream->write_function(stream, " %d\n", gp->ib_failed_calls); - stream->write_function(stream, " %d\n", gp->ob_failed_calls); + stream->write_function(stream, " %u\n", gp->ib_calls); + stream->write_function(stream, " %u\n", gp->ob_calls); + stream->write_function(stream, " %u\n", gp->ib_failed_calls); + stream->write_function(stream, " %u\n", gp->ob_failed_calls); if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) { time_t now = switch_epoch_time_now(NULL); @@ -2769,7 +2777,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl } else if (!strcasecmp(argv[0], "profile")) { struct cb_helper cb; char *sql = NULL; - int x = 0; + uint32_t x = 0; cb.row_process = 0; @@ -2825,10 +2833,10 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl stream->write_function(stream, " %s\n", switch_str_nil(profile->user_agent_filter)); stream->write_function(stream, " %d\n", profile->max_registrations_perext); - stream->write_function(stream, " %d\n", profile->ib_calls); - stream->write_function(stream, " %d\n", profile->ob_calls); - stream->write_function(stream, " %d\n", profile->ib_failed_calls); - stream->write_function(stream, " %d\n", profile->ob_failed_calls); + stream->write_function(stream, " %u\n", profile->ib_calls); + stream->write_function(stream, " %u\n", profile->ob_calls); + stream->write_function(stream, " %u\n", profile->ib_failed_calls); + stream->write_function(stream, " %u\n", profile->ob_failed_calls); stream->write_function(stream, " \n"); } stream->write_function(stream, " \n"); @@ -3166,6 +3174,17 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t goto done; } + if (!strcasecmp(argv[1], "watchdog")) { + if (argc > 2) { + int value = switch_true(argv[2]); + profile->watchdog_enabled = value; + stream->write_function(stream, "%s sip debugging on %s", value ? "Enabled" : "Disabled", profile->name); + } else { + stream->write_function(stream, "Usage: sofia profile watchdog \n"); + } + goto done; + } + if (!strcasecmp(argv[1], "gwlist")) { int up = 1; @@ -3502,17 +3521,16 @@ SWITCH_STANDARD_API(sofia_function) "[register|unregister] [|all]|" "killgw |" "[stun-auto-disable|stun-enabled] [true|false]]|" - "siptrace [on|off]\n" + "siptrace |" + "watchdog \n" "sofia status|xmlstatus profile [ reg ] | [ pres ] | [ user ]\n" "sofia status|xmlstatus gateway \n" "sofia loglevel [0-9]\n" "sofia tracelevel \n" + "sofia global siptrace |" + "watchdog \n" "--------------------------------------------------------------------------------\n"; - if (session) { - return SWITCH_STATUS_FALSE; - } - if (zstr(cmd)) { stream->write_function(stream, "%s", usage_string); goto done; @@ -3562,6 +3580,35 @@ SWITCH_STANDARD_API(sofia_function) } else if (!strcasecmp(argv[0], "help")) { stream->write_function(stream, "%s", usage_string); goto done; + } else if (!strcasecmp(argv[0], "global")) { + int ston = -1; + int wdon = -1; + + if (argc > 1) { + if (!strcasecmp(argv[1], "siptrace")) { + if (argc > 2) { + ston = switch_true(argv[2]); + } + } + if (!strcasecmp(argv[1], "watchdog")) { + if (argc > 2) { + wdon = switch_true(argv[2]); + } + } + } + + if (ston != -1) { + sofia_glue_global_siptrace(ston); + stream->write_function(stream, "+OK Global siptrace %s", ston ? "on" : "off"); + } else if (wdon != -1) { + sofia_glue_global_watchdog(wdon); + stream->write_function(stream, "+OK Global watchdog %s", wdon ? "on" : "off"); + } else { + stream->write_function(stream, "-ERR Usage: siptrace |watchdog "); + } + + goto done; + } else if (!strcasecmp(argv[0], "recover")) { if (argv[1] && !strcasecmp(argv[1], "flush")) { sofia_glue_recover(SWITCH_TRUE); @@ -4363,7 +4410,8 @@ static void general_event_handler(switch_event_t *event) switch_mutex_lock(mod_sofia_globals.hash_mutex); if (mod_sofia_globals.profile_hash) { for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { - int rb = 0, x = 0; + int rb = 0; + uint32_t x = 0; switch_hash_this(hi, &var, NULL, &val); if ((profile = (sofia_profile_t *) val) && profile->auto_restart) { if (!strcmp(profile->sipip, old_ip4)) { @@ -4637,6 +4685,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_console_set_complete("add sofia loglevel ::[all:default:tport:iptsec:nea:nta:nth_client:nth_server:nua:soa:sresolv:stun ::[0:1:2:3:4:5:6:7:8:9"); switch_console_set_complete("add sofia tracelevel ::[console:alert:crit:err:warning:notice:info:debug"); + switch_console_set_complete("add sofia global siptrace ::[on:off"); + switch_console_set_complete("add sofia global watchdog ::[on:off"); + switch_console_set_complete("add sofia profile"); switch_console_set_complete("add sofia profile restart all"); @@ -4651,6 +4702,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_console_set_complete("add sofia profile ::sofia::list_profiles killgw ::sofia::list_profile_gateway"); switch_console_set_complete("add sofia profile ::sofia::list_profiles siptrace on"); switch_console_set_complete("add sofia profile ::sofia::list_profiles siptrace off"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles watchdog on"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles watchdog off"); switch_console_set_complete("add sofia profile ::sofia::list_profiles gwlist up"); switch_console_set_complete("add sofia profile ::sofia::list_profiles gwlist down"); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 5a6995806a..cf4b9a3759 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -220,6 +220,7 @@ typedef enum { PFLAG_T38_PASSTHRU, PFLAG_CID_IN_1XX, PFLAG_IN_DIALOG_CHAT, + PFLAG_DEL_SUBS_ON_REG, /* No new flags below this line */ PFLAG_MAX } PFLAGS; @@ -561,6 +562,11 @@ struct sofia_profile { char *contact_user; char *local_network; uint32_t trans_timeout; + switch_time_t last_sip_event; + switch_time_t last_root_step; + uint32_t step_timeout; + uint32_t event_timeout; + int watchdog_enabled; }; struct private_object { @@ -577,6 +583,7 @@ struct private_object { switch_codec_t read_codec; switch_codec_t write_codec; uint32_t codec_ms; + uint32_t bitrate; switch_caller_profile_t *caller_profile; uint32_t timestamp_send; switch_rtp_t *rtp_session; @@ -926,6 +933,7 @@ sofia_transport_t sofia_glue_str2transport(const char *str); const char *sofia_glue_transport2str(const sofia_transport_t tp); char *sofia_glue_find_parameter(const char *str, const char *param); +char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param); char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport); char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport); char *sofia_glue_strip_uri(const char *str); @@ -1012,3 +1020,8 @@ char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefi void sofia_glue_tech_simplify(private_object_t *tech_pvt); switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host); switch_bool_t sofia_glue_profile_exists(const char *key); +void sofia_glue_global_siptrace(switch_bool_t on); +void sofia_glue_global_watchdog(switch_bool_t on); +void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp); +switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt); +void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl); diff --git a/src/mod/endpoints/mod_sofia/sip-dig.c b/src/mod/endpoints/mod_sofia/sip-dig.c index f4714bccda..d0c9aa6aff 100644 --- a/src/mod/endpoints/mod_sofia/sip-dig.c +++ b/src/mod/endpoints/mod_sofia/sip-dig.c @@ -785,7 +785,7 @@ int dig_addr(struct dig *dig, char const *tport2 = NULL; sres_record_t **answers1 = NULL, **answers2 = NULL; unsigned count1 = 0, count2 = 0, tcount = 0; - int type1 = 0, type2 = 0, family1 = 0, family2 = 0; + uint16_t type1 = 0, type2 = 0, family1 = 0, family2 = 0; if (dig->ip6 > dig->ip4) { type1 = sres_type_aaaa, family1 = AF_INET6; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index e8bbb6f76e..0d69bdb4bb 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -731,6 +731,7 @@ void sofia_event_callback(nua_event_t event, int locked = 0; int check_destroy = 1; + profile->last_sip_event = switch_time_now(); /* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be freed whenever the request is done */ @@ -1268,7 +1269,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread iterations++; if (len + newlen + 10 > sql_len) { - int new_mlen = len + newlen + 10 + 10240; + switch_size_t new_mlen = len + newlen + 10 + 10240; if (new_mlen < SQLLEN) { sql_len = new_mlen; @@ -1309,6 +1310,40 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread } if (++loops >= 1000) { + + + + if (profile->watchdog_enabled) { + uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0; + + if (profile->step_timeout) { + step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000); + + if (step_diff > profile->step_timeout) { + step_fail = 1; + } + } + + if (profile->event_timeout) { + event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000); + + if (event_diff > profile->event_timeout) { + event_fail = 1; + } + } + + if (step_fail && profile->event_timeout && !event_fail) { + step_fail = 0; + } + + if (event_fail || step_fail) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED!\n" + "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name); + switch_yield(2000); + abort(); + } + } + if (++ireg_loops >= IREG_SECONDS) { time_t now = switch_epoch_time_now(NULL); sofia_reg_check_expire(profile, now, 0); @@ -1548,6 +1583,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void while (mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING) && sofia_test_pflag(profile, PFLAG_WORKER_RUNNING)) { su_root_step(profile->s_root, 1000); + profile->last_root_step = switch_time_now(); } sofia_clear_pflag_locked(profile, PFLAG_RUNNING); @@ -2223,6 +2259,35 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) goto done; } + if ((settings = switch_xml_child(cfg, "global_settings"))) { + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + if (!strcasecmp(var, "log-level")) { + su_log_set_level(NULL, atoi(val)); + } else if (!strcasecmp(var, "tracelevel")) { + mod_sofia_globals.tracelevel = switch_log_str2level(val); + } else if (!strcasecmp(var, "debug-presence")) { + mod_sofia_globals.debug_presence = atoi(val); + } else if (!strcasecmp(var, "debug-sla")) { + mod_sofia_globals.debug_sla = atoi(val); + } else if (!strcasecmp(var, "auto-restart")) { + mod_sofia_globals.auto_restart = switch_true(val); + } else if (!strcasecmp(var, "rewrite-multicasted-fs-path")) { + if( (!strcasecmp(val, "to_host")) || (!strcasecmp(val, "1")) ) { + /* old behaviour */ + mod_sofia_globals.rewrite_multicasted_fs_path = 1; + } else if (!strcasecmp(val, "original_server_host")) { + mod_sofia_globals.rewrite_multicasted_fs_path = 2; + } else if (!strcasecmp(val, "original_hostname")) { + mod_sofia_globals.rewrite_multicasted_fs_path = 3; + } else { + mod_sofia_globals.rewrite_multicasted_fs_path = SWITCH_FALSE; + } + } + } + } + if ((profiles = switch_xml_child(cfg, "profiles"))) { for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) { char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name"); @@ -2257,14 +2322,24 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) profile->debug = atoi(val); } else if (!strcasecmp(var, "shutdown-on-fail")) { profile->shutdown_type = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "tracelevel")) { - mod_sofia_globals.tracelevel = switch_log_str2level(val); } else if (!strcasecmp(var, "pass-callee-id")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); } else { sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID); } + } else if (!strcasecmp(var, "delete-subs-on-register")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } else { + sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } + } else if (!strcasecmp(var, "watchdog-enabled")) { + profile->watchdog_enabled = switch_true(val); + } else if (!strcasecmp(var, "watchdog-step-timeout")) { + profile->step_timeout = (unsigned long) atol(val); + } else if (!strcasecmp(var, "watchdog-event-timeout")) { + profile->event_timeout = (unsigned long) atol(val); } else if (!strcasecmp(var, "in-dialog-chat")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT); @@ -2312,12 +2387,6 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); } - } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); - } else { - sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); - } } else if (!strcasecmp(var, "t38-passthru")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_T38_PASSTHRU); @@ -2444,7 +2513,7 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) sofia_clear_pflag(profile, PFLAG_STUN_AUTO_DISABLE); } } else if (!strcasecmp(var, "apply-nat-acl")) { - if (profile->acl_count < SOFIA_MAX_ACL) { + if (profile->nat_acl_count < SOFIA_MAX_ACL) { if (!profile->extsipip && switch_check_network_list_ip(profile->sipip, val)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val); } else { @@ -2817,6 +2886,8 @@ switch_status_t config_sofia(int reload, char *profile_name) char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "log-level")) { su_log_set_level(NULL, atoi(val)); + } else if (!strcasecmp(var, "tracelevel")) { + mod_sofia_globals.tracelevel = switch_log_str2level(val); } else if (!strcasecmp(var, "debug-presence")) { mod_sofia_globals.debug_presence = atoi(val); } else if (!strcasecmp(var, "debug-sla")) { @@ -2933,6 +3004,12 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); } + } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } else { + sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } } else if (!strcasecmp(var, "user-agent-string")) { profile->user_agent = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "auto-restart")) { @@ -2943,12 +3020,25 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL); } + } else if (!strcasecmp(var, "watchdog-enabled")) { + profile->watchdog_enabled = switch_true(val); + } else if (!strcasecmp(var, "watchdog-step-timeout")) { + profile->step_timeout = atoi(val); + } else if (!strcasecmp(var, "watchdog-event-timeout")) { + profile->event_timeout = atoi(val); + } else if (!strcasecmp(var, "in-dialog-chat")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT); } else { sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT); } + } else if (!strcasecmp(var, "delete-subs-on-register")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } else { + sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } } else if (!strcasecmp(var, "t38-passthru")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_T38_PASSTHRU); @@ -3431,7 +3521,7 @@ switch_status_t config_sofia(int reload, char *profile_name) } else if (!strcasecmp(var, "context")) { profile->context = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "apply-nat-acl")) { - if (profile->acl_count < SOFIA_MAX_ACL) { + if (profile->nat_acl_count < SOFIA_MAX_ACL) { if (!profile->extsipip && profile->sipip && switch_check_network_list_ip(profile->sipip, val)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not adding acl %s because it's the local network\n", val); } else { @@ -3933,6 +4023,23 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } } +#if 0 + if (status == 200 && switch_channel_test_flag(channel, CF_PROXY_MEDIA) && + sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(tech_pvt->iananame, "PROXY")) { + switch_core_session_t *other_session; + + sofia_glue_proxy_codec(session, sip->sip_payload->pl_data); + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_compare(session, other_session)) { + sofia_glue_proxy_codec(other_session, sip->sip_payload->pl_data); + } + switch_core_session_rwunlock(other_session); + } + } +#endif + + if ((status == 180 || status == 183 || status == 200)) { const char *x_freeswitch_support; @@ -3959,7 +4066,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } - if (channel && sip && (status == 300 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) { sip_contact_t *p_contact = sip->sip_contact; int i = 0; char var_name[80]; @@ -4138,6 +4245,36 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) { if (sip->sip_payload && sip->sip_payload->pl_data) { switch_t38_options_t *t38_options = sofia_glue_extract_t38_options(session, sip->sip_payload->pl_data); + char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session); + switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session); + char tmp[32] = ""; + + tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, t38_options->remote_ip); + tech_pvt->remote_sdp_audio_port = t38_options->remote_port; + + if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && + remote_port == tech_pvt->remote_sdp_audio_port) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "Audio params are unchanged for %s.\n", + switch_channel_get_name(tech_pvt->channel)); + } else { + const char *err = NULL; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "Audio params changed for %s from %s:%d to %s:%d\n", + switch_channel_get_name(tech_pvt->channel), + remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port); + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); + if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); + } + } + if (t38_options) { sofia_glue_copy_t38_options(t38_options, other_session); @@ -4167,14 +4304,11 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) { if (switch_rtp_ready(tech_pvt->rtp_session) && switch_rtp_ready(other_tech_pvt->rtp_session)) { switch_rtp_udptl_mode(tech_pvt->rtp_session); - switch_rtp_udptl_mode(other_tech_pvt->rtp_session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n"); } - switch_core_session_receive_message(other_session, msg); - } else { - switch_core_session_queue_message(other_session, msg); } + switch_core_session_queue_message(other_session, msg); switch_core_session_rwunlock(other_session); } @@ -4394,7 +4528,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (ss_state == nua_callstate_terminated) { - if ((status == 300 || status == 302 || status == 305) && session) { + if ((status == 300 || status == 301 || status == 302 || status == 305) && session) { channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); @@ -4467,6 +4601,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } + + state_process: switch ((enum nua_callstate) ss_state) { @@ -4941,10 +5077,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (channel) { - if (sofia_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) { + if (sofia_test_flag(tech_pvt, TFLAG_EARLY_MEDIA) && !sofia_test_flag(tech_pvt, TFLAG_ANS)) { sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag(tech_pvt, TFLAG_SDP); switch_channel_mark_answered(channel); + if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) { @@ -4965,6 +5102,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag_locked(tech_pvt, TFLAG_SDP); switch_channel_mark_answered(channel); + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) { goto done; @@ -5070,6 +5208,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } done: + if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) { sofia_glue_tech_simplify(tech_pvt); @@ -5221,7 +5360,6 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces) } - void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]) { /* Incoming refer */ @@ -5794,7 +5932,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype && sip->sip_payload && sip->sip_payload->pl_data) { - if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) { + if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) { + switch_core_session_t *other_session; + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data); + switch_core_session_rwunlock(other_session); + } else { + sofia_glue_build_vid_refresh_message(session, sip->sip_payload->pl_data); + } + + } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) { /* Try and find signal information in the payload */ if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) { int tmp; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 4018407961..cb8b257e58 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -41,11 +41,16 @@ switch_cache_db_handle_t *sofia_glue_get_db_handle(sofia_profile_t *profile); void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options, int insist) { - char buf[2048]; + char buf[2048] = ""; + char max_buf[128] = ""; + char max_data[128] = ""; const char *ip = t38_options->local_ip; uint32_t port = t38_options->local_port; const char *family = "IP4"; const char *username = tech_pvt->profile->username; + char MMR[32] = ""; + char JBIG[32] = ""; + char FILLBIT[32] = ""; //sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); @@ -89,6 +94,56 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * "o=%s %010u %010u IN %s %s\n" "s=%s\n" "c=IN %s %s\n" "t=0 0\n", username, tech_pvt->owner_id, tech_pvt->session_id, family, ip, username, family, ip); + if(t38_options->T38FaxFillBitRemoval) { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval"))) { + switch_snprintf(FILLBIT, sizeof(FILLBIT), "a=T38FaxFillBitRemoval:1\n"); + } else { + switch_set_string(FILLBIT, "a=T38FaxFillBitRemoval\n"); + } + } else { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval"))) { + switch_snprintf(FILLBIT, sizeof(FILLBIT), "a=T38FaxFillBitRemoval:0\n"); + } else { + switch_set_string(FILLBIT, ""); + } + } + + if( t38_options->T38FaxTranscodingMMR) { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR"))) { + switch_snprintf(MMR, sizeof(MMR), "a=T38FaxTranscodingMMR:1\n"); + } else { + switch_set_string(MMR, "a=T38FaxTranscodingMMR\n"); + } + } else { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR"))) { + switch_snprintf(MMR, sizeof(MMR), "a=T38FaxTranscodingMMR:0\n"); + } else { + switch_set_string(MMR, ""); + } + } + + if( t38_options->T38FaxTranscodingJBIG) { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG"))) { + switch_snprintf(JBIG, sizeof(JBIG), "a=T38FaxTranscodingJBIG:1\n"); + } else { + switch_set_string(JBIG, "a=T38FaxTranscodingJBIG\n"); + } + } else { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG"))) { + switch_snprintf(JBIG, sizeof(JBIG), "a=T38FaxTranscodingJBIG:0\n"); + } else { + switch_set_string(JBIG, ""); + } + } + + if (t38_options->T38FaxMaxBuffer) { + switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer); + }; + + if (t38_options->T38FaxMaxDatagram) { + switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\n", t38_options->T38FaxMaxDatagram); + }; + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=image %d udptl t38\n" @@ -98,19 +153,20 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * "%s" "%s" "a=T38FaxRateManagement:%s\n" - "a=T38FaxMaxBuffer:%d\n" - "a=T38FaxMaxDatagram:%d\n" + "%s" + "%s" "a=T38FaxUdpEC:%s\n", //"a=T38VendorInfo:%s\n", port, t38_options->T38FaxVersion, t38_options->T38MaxBitRate, - t38_options->T38FaxFillBitRemoval ? "a=T38FaxFillBitRemoval\n" : "", - t38_options->T38FaxTranscodingMMR ? "a=T38FaxTranscodingMMR\n" : "", - t38_options->T38FaxTranscodingJBIG ? "a=T38FaxTranscodingJBIG\n" : "", + FILLBIT, + MMR, + JBIG, t38_options->T38FaxRateManagement, - t38_options->T38FaxMaxBuffer, - t38_options->T38FaxMaxDatagram, t38_options->T38FaxUdpEC + max_buf, + max_data, + t38_options->T38FaxUdpEC //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0" ); @@ -146,6 +202,13 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 const char *username = tech_pvt->profile->username; const char *fmtp_out = tech_pvt->fmtp_out; const char *fmtp_out_var = switch_channel_get_variable(tech_pvt->channel, "sip_force_audio_fmtp"); + switch_event_t *map = NULL, *ptmap = NULL; + const char *b_sdp = NULL; + + if (!tech_pvt->rm_encoding && (b_sdp = switch_channel_get_variable(tech_pvt->channel, SWITCH_B_SDP_VARIABLE))) { + sofia_glue_sdp_map(b_sdp, &map, &ptmap); + } + if (fmtp_out_var) { fmtp_out = fmtp_out_var; @@ -274,7 +337,8 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 int already_did[128] = { 0 }; for (i = 0; i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; - + char *fmtp = imp->fmtp; + if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) { continue; } @@ -289,9 +353,20 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 rate = imp->samples_per_second; + if (map) { + char key[128] = ""; + char *check = NULL; + switch_snprintf(key, sizeof(key), "%s:%u", imp->iananame, imp->bits_per_second); + + if ((check = switch_event_get_header(map, key)) || (check = switch_event_get_header(map, imp->iananame))) { + fmtp = check; + } + } + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", imp->ianacode, imp->iananame, rate); - if (imp->fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, imp->fmtp); + + if (fmtp) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, fmtp); } } } @@ -423,38 +498,87 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 int i; int already_did[128] = { 0 }; +#if 0 + switch_event_t *event; + char *buf; + int level = SWITCH_LOG_INFO; + + if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(switch_core_session_get_channel(tech_pvt->session), event); + switch_event_serialize(event, &buf, SWITCH_FALSE); + switch_assert(buf); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), level, "CHANNEL_DATA:\n%s\n", buf); + switch_event_destroy(&event); + free(buf); + } +#endif + for (i = 0; i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; + char *fmtp = NULL; + uint32_t ianacode = imp->ianacode; +#if 0 + const char *str; + + + if ((str = switch_event_get_header(ptmap, imp->iananame))) { + int tmp = atoi(str); + if (tmp > 0) { + ianacode = tmp; + } + } +#endif if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { continue; } - if (imp->ianacode < 128) { - if (already_did[imp->ianacode]) { + if (ianacode < 128) { + if (already_did[ianacode]) { continue; } - already_did[imp->ianacode] = 1; + already_did[ianacode] = 1; } if (!rate) { rate = imp->samples_per_second; } - - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", imp->ianacode, imp->iananame, + + + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", ianacode, imp->iananame, imp->samples_per_second); - if (imp->fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, imp->fmtp); + + if (!zstr(ov_fmtp)) { + fmtp = (char *) ov_fmtp; } else { - if (pass_fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, pass_fmtp); + + if (map) { + fmtp = switch_event_get_header(map, imp->iananame); } + + if (zstr(fmtp)) fmtp = imp->fmtp; + + if (zstr(fmtp)) fmtp = (char *) pass_fmtp; + } + + if (!zstr(fmtp) && strcasecmp(fmtp, "_blank_")) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, fmtp); } } + } } } + + if (map) { + switch_event_destroy(&map); + } + + if (ptmap) { + switch_event_destroy(&ptmap); + } + sofia_glue_tech_set_local_sdp(tech_pvt, buf, SWITCH_TRUE); } @@ -748,32 +872,30 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc sdp_port = tech_pvt->local_sdp_audio_port; - if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_audio_ip")) - && !zstr(tech_pvt->profile->extrtpip)) { - use_ip = tech_pvt->profile->extrtpip; - } + /* Check if NAT is detected */ + if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + /* Yes, map the port through switch_nat */ + switch_nat_add_mapping(tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); + switch_nat_add_mapping(tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP, &rtcp_port, SWITCH_FALSE); - if (use_ip) { - if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, - use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ - return SWITCH_STATUS_FALSE; - } else { - if (lookup_rtpip == use_ip) { - /* sofia_glue_ext_address_lookup didn't return any error, but the return IP is the same as the original one, - which means no lookup was necessary. Check if NAT is detected */ - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { - /* Yes, map the port through switch_nat */ - switch_nat_add_mapping(tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); - switch_nat_add_mapping(tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP, &rtcp_port, SWITCH_FALSE); - } else { - /* No NAT detected */ - use_ip = tech_pvt->rtpip; - } + /* Find an IP address to use */ + if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_audio_ip")) + && !zstr(tech_pvt->profile->extrtpip)) { + use_ip = tech_pvt->profile->extrtpip; + } + + if (use_ip) { + if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, + use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { + /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ + return SWITCH_STATUS_FALSE; } else { /* Address properly resolved, use it as external ip */ use_ip = lookup_rtpip; } + } else { + /* No external ip found, use the profile's rtp ip */ + use_ip = tech_pvt->rtpip; } } else { /* No NAT traversal required, use the profile's rtp ip */ @@ -817,31 +939,29 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in sdp_port = tech_pvt->local_sdp_video_port; - if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_video_ip")) - && !zstr(tech_pvt->profile->extrtpip)) { - use_ip = tech_pvt->profile->extrtpip; - } + /* Check if NAT is detected */ + if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + /* Yes, map the port through switch_nat */ + switch_nat_add_mapping(tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); - if (use_ip) { - if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, - use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ - return SWITCH_STATUS_FALSE; - } else { - if (lookup_rtpip == use_ip) { - /* sofia_glue_ext_address_lookup didn't return any error, but the return IP is the same as the original one, - which means no lookup was necessary. Check if NAT is detected */ - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { - /* Yes, map the port through switch_nat */ - switch_nat_add_mapping(tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); - } else { - /* No NAT detected */ - use_ip = tech_pvt->rtpip; - } + /* Find an IP address to use */ + if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_video_ip")) + && !zstr(tech_pvt->profile->extrtpip)) { + use_ip = tech_pvt->profile->extrtpip; + } + + if (use_ip) { + if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, + use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { + /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ + return SWITCH_STATUS_FALSE; } else { /* Address properly resolved, use it as external ip */ use_ip = lookup_rtpip; } + } else { + /* No external ip found, use the profile's rtp ip */ + use_ip = tech_pvt->rtpip; } } else { /* No NAT traversal required, use the profile's rtp ip */ @@ -870,6 +990,34 @@ sofia_transport_t sofia_glue_str2transport(const char *str) return SOFIA_TRANSPORT_UNKNOWN; } +char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param) +{ + const char *param_ptr; + char *param_value; + char *tmp; + switch_size_t param_len; + + if (zstr(str) || zstr(param) || !session) return NULL; + + if (end_of(param) != '=') { + param = switch_core_session_sprintf(session, "%s=", param); + if (zstr(param)) return NULL; + } + + param_len = strlen(param); + param_ptr = sofia_glue_find_parameter(str, param); + + if (zstr(param_ptr)) return NULL; + + param_value = switch_core_session_strdup(session, param_ptr + param_len); + + if (zstr(param_value)) return NULL; + + if ((tmp = strchr(param_value, ';'))) *tmp = '\0'; + + return param_value; +} + char *sofia_glue_find_parameter(const char *str, const char *param) { char *ptr = NULL; @@ -1162,7 +1310,7 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) switch_port_t remote_rtcp_port = 0; if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } @@ -1198,7 +1346,7 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) } if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } @@ -1277,9 +1425,12 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt) } if (tech_pvt->adv_sdp_audio_ip && !strncmp("c=IN IP", p, 7)) { - strncpy(q, p, 9); - p += 9; - q += 9; + strncpy(q, p, 7); + p += 7; + q += 7; + strncpy(q, strchr(tech_pvt->adv_sdp_audio_ip, ':') ? "6 " : "4 ", 2); + p +=2; + q +=2; strncpy(q, tech_pvt->adv_sdp_audio_ip, strlen(tech_pvt->adv_sdp_audio_ip)); q += strlen(tech_pvt->adv_sdp_audio_ip); @@ -1516,7 +1667,11 @@ char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefi if (!strncasecmp(name, prefix, strlen(prefix))) { const char *hname = name + strlen(prefix); - stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n\n%s\n", boundary, hname, strlen(value) + 1, value); + if (*value == '~') { + stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n%s\n", boundary, hname, strlen(value), value + 1); + } else { + stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n\n%s\n", boundary, hname, strlen(value) + 1, value); + } x++; } } @@ -1868,10 +2023,22 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) switch_channel_set_variable(channel, "sip_req_uri", s); } - tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL, - NUTAG_URL(url_str), - TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)), - SIPTAG_TO_STR(to_str), SIPTAG_FROM_STR(from_str), SIPTAG_CONTACT_STR(invite_contact), TAG_END()); + if (!(tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL, + NUTAG_URL(url_str), + TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)), + SIPTAG_TO_STR(to_str), SIPTAG_FROM_STR(from_str), SIPTAG_CONTACT_STR(invite_contact), TAG_END()))) { + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, + "Error creating HANDLE!\nurl_str=[%s]\ncall_id=[%s]\nto_str=[%s]\nfrom_str=[%s]\ninvite_contact=[%s]\n", + url_str, + call_id ? call_id : "N/A", + to_str, + from_str, + invite_contact); + + switch_safe_free(d_url); + return SWITCH_STATUS_FALSE; + } if (tech_pvt->dest && (strstr(tech_pvt->dest, ";fs_nat") || strstr(tech_pvt->dest, ";received") || ((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val)))) { @@ -2401,24 +2568,26 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) } } - if (switch_core_codec_init(&tech_pvt->read_codec, + if (switch_core_codec_init_with_bitrate(&tech_pvt->read_codec, tech_pvt->iananame, tech_pvt->rm_fmtp, tech_pvt->rm_rate, tech_pvt->codec_ms, 1, + tech_pvt->bitrate, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags, NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); switch_goto_status(SWITCH_STATUS_FALSE, end); } - if (switch_core_codec_init(&tech_pvt->write_codec, + if (switch_core_codec_init_with_bitrate(&tech_pvt->write_codec, tech_pvt->iananame, tech_pvt->rm_fmtp, tech_pvt->rm_rate, tech_pvt->codec_ms, 1, + tech_pvt->bitrate, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags, NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -2442,9 +2611,10 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) if (switch_rtp_ready(tech_pvt->rtp_session)) { switch_assert(tech_pvt->read_codec.implementation); - + if (switch_rtp_change_interval(tech_pvt->rtp_session, - tech_pvt->read_impl.microseconds_per_packet, tech_pvt->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) { + tech_pvt->read_impl.microseconds_per_packet, + tech_pvt->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_goto_status(SWITCH_STATUS_FALSE, end); } @@ -2458,9 +2628,9 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) switch_goto_status(SWITCH_STATUS_FALSE, end); } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples %d bits\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->iananame, tech_pvt->rm_rate, tech_pvt->codec_ms, - tech_pvt->read_impl.samples_per_packet); + tech_pvt->read_impl.samples_per_packet, tech_pvt->read_impl.bits_per_second); tech_pvt->read_frame.codec = &tech_pvt->read_codec; tech_pvt->write_codec.agreed_pt = tech_pvt->agreed_pt; @@ -2704,6 +2874,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->local_sdp_audio_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt); + } } switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_audio_port); @@ -2717,7 +2891,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, @@ -2756,6 +2930,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt); + } + } else { timer_name = tech_pvt->profile->timer_name; @@ -2848,7 +3026,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"); switch_port_t remote_port = 0; if (rport) { - remote_port = atoi(rport); + remote_port = (switch_port_t)atoi(rport); } if (!strcasecmp(val, "passthru")) { switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port); @@ -2946,13 +3124,14 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f sofia_glue_check_video_codecs(tech_pvt); if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && tech_pvt->video_rm_encoding && tech_pvt->remote_sdp_video_port) { - + /******************************************************************************************/ if (tech_pvt->video_rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { //const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE); //const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE); char *remote_host = switch_rtp_get_remote_host(tech_pvt->video_rtp_session); switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->video_rtp_session); + if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_video_ip) && remote_port == tech_pvt->remote_sdp_video_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n", @@ -2970,8 +3149,12 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_audio_ip, tech_pvt->local_sdp_video_port, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); - } + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } + } + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_video_port); switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip); switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp); @@ -2983,7 +3166,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } if (switch_rtp_set_remote_address @@ -2998,6 +3181,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f /* Reactivate the NAT buster flag. */ switch_rtp_set_flag(tech_pvt->video_rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } + } goto video_up; } @@ -3023,6 +3207,9 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } } else { timer_name = tech_pvt->profile->timer_name; @@ -3073,6 +3260,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, 0, switch_rtp_ready(tech_pvt->video_rtp_session) ? "SUCCESS" : err); + + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { const char *ssrc; switch_channel_set_flag(tech_pvt->channel, CF_VIDEO); @@ -3091,7 +3283,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"); switch_port_t remote_port = 0; if (rport) { - remote_port = atoi(rport); + remote_port = (switch_port_t)atoi(rport); } if (!strcasecmp(val, "passthru")) { switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port); @@ -3433,11 +3625,11 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ t38_options = switch_core_session_alloc(tech_pvt->session, sizeof(switch_t38_options_t)); } - t38_options->remote_port = m->m_port; + t38_options->remote_port = (switch_port_t)m->m_port; - if (m->m_connections) { + if (m->m_connections && m->m_connections->c_address) { t38_options->remote_ip = switch_core_session_strdup(tech_pvt->session, m->m_connections->c_address); - } else if (sdp && sdp->sdp_connection) { + } else if (sdp && sdp->sdp_connection && sdp->sdp_connection->c_address) { t38_options->remote_ip = switch_core_session_strdup(tech_pvt->session, sdp->sdp_connection->c_address); } @@ -3447,11 +3639,41 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ } else if (!strcasecmp(attr->a_name, "T38MaxBitRate") && attr->a_value) { t38_options->T38MaxBitRate = (uint32_t) atoi(attr->a_value); } else if (!strcasecmp(attr->a_name, "T38FaxFillBitRemoval")) { - t38_options->T38FaxFillBitRemoval = SWITCH_TRUE; + if (switch_stristr("T38FaxFillBitRemoval:", tech_pvt->remote_sdp_str)) { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval", "true"); + if (atoi(attr->a_value) == 0) { + t38_options->T38FaxFillBitRemoval = SWITCH_FALSE; + } else { + t38_options->T38FaxFillBitRemoval = SWITCH_TRUE; + } + } else { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval", "false"); + t38_options->T38FaxFillBitRemoval = SWITCH_TRUE; + } } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingMMR")) { - t38_options->T38FaxTranscodingMMR = SWITCH_TRUE; + if (switch_stristr("T38FaxTranscodingMMR:", tech_pvt->remote_sdp_str)) { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR", "true"); + if (atoi(attr->a_value) == 0) { + t38_options->T38FaxTranscodingMMR = SWITCH_FALSE; + } else { + t38_options->T38FaxTranscodingMMR = SWITCH_TRUE; + } + } else { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR", "false"); + t38_options->T38FaxTranscodingMMR = SWITCH_TRUE; + } } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingJBIG")) { - t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE; + if (switch_stristr("T38FaxTranscodingJBIG:", tech_pvt->remote_sdp_str)) { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG", "true"); + if (atoi(attr->a_value) == 0) { + t38_options->T38FaxTranscodingJBIG = SWITCH_FALSE; + } else { + t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE; + } + } else { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG", "false"); + t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE; + } } else if (!strcasecmp(attr->a_name, "T38FaxRateManagement") && attr->a_value) { t38_options->T38FaxRateManagement = switch_core_session_strdup(tech_pvt->session, attr->a_value); } else if (!strcasecmp(attr->a_name, "T38FaxMaxBuffer") && attr->a_value) { @@ -3472,6 +3694,131 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ return t38_options; } + +switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt) +{ + sdp_media_t *m; + sdp_parser_t *parser = NULL; + sdp_session_t *sdp; + + if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { + return SWITCH_STATUS_FALSE; + } + + if (!(sdp = sdp_session(parser))) { + sdp_parser_free(parser); + return SWITCH_STATUS_FALSE; + } + + switch_event_create(&(*fmtp), SWITCH_EVENT_REQUEST_PARAMS); + switch_event_create(&(*pt), SWITCH_EVENT_REQUEST_PARAMS); + + for (m = sdp->sdp_media; m; m = m->m_next) { + if (m->m_proto == sdp_proto_rtp) { + sdp_rtpmap_t *map; + + for (map = m->m_rtpmaps; map; map = map->rm_next) { + if (map->rm_encoding) { + char buf[25] = ""; + char key[128] = ""; + char *br = NULL; + + if (map->rm_fmtp) { + if ((br = strstr(map->rm_fmtp, "bitrate="))) { + br += 8; + } + } + + switch_snprintf(buf, sizeof(buf), "%d", map->rm_pt); + + if (br) { + switch_snprintf(key, sizeof(key), "%s:%s", map->rm_encoding, br); + } else { + switch_snprintf(key, sizeof(key), "%s", map->rm_encoding); + } + + switch_event_add_header_string(*pt, SWITCH_STACK_BOTTOM, key, buf); + + if (map->rm_fmtp) { + switch_event_add_header_string(*fmtp, SWITCH_STACK_BOTTOM, key, map->rm_fmtp); + } + } + } + } + } + + sdp_parser_free(parser); + + return SWITCH_STATUS_SUCCESS; + +} + + +void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) +{ + sdp_media_t *m; + sdp_parser_t *parser = NULL; + sdp_session_t *sdp; + private_object_t *tech_pvt = switch_core_session_get_private(session); + sdp_attribute_t *attr; + int ptime = 0, dptime = 0, dmaxptime = 0, maxptime = 0; + + if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { + return; + } + + if (!(sdp = sdp_session(parser))) { + sdp_parser_free(parser); + return; + } + + switch_assert(tech_pvt != NULL); + + + for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) { + if (zstr(attr->a_name)) { + continue; + } + + if (!strcasecmp(attr->a_name, "ptime")) { + dptime = atoi(attr->a_value); + } else if (!strcasecmp(attr->a_name, "maxptime")) { + dmaxptime = atoi(attr->a_value); + } + } + + + for (m = sdp->sdp_media; m; m = m->m_next) { + + ptime = dptime; + maxptime = dmaxptime; + + if (m->m_proto == sdp_proto_rtp) { + sdp_rtpmap_t *map; + for (attr = m->m_attributes; attr; attr = attr->a_next) { + if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { + ptime = atoi(attr->a_value); + } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) { + maxptime = atoi(attr->a_value); + } + } + + for (map = m->m_rtpmaps; map; map = map->rm_next) { + tech_pvt->iananame = switch_core_session_strdup(tech_pvt->session, map->rm_encoding); + tech_pvt->rm_rate = map->rm_rate; + tech_pvt->codec_ms = ptime; + sofia_glue_tech_set_codec(tech_pvt, 0); + break; + } + + break; + } + } + + sdp_parser_free(parser); + +} + switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *session, const char *r_sdp) { sdp_media_t *m; @@ -3513,7 +3860,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s sdp_attribute_t *attr; int first = 0, last = 0; int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0; - int codec_ms = 0; int sendonly = 0; int greedy = 0, x = 0, skip = 0, mine = 0; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -3619,7 +3965,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s if (got_udptl && m->m_type == sdp_media_image && m->m_port) { switch_t38_options_t *t38_options = tech_process_udptl(tech_pvt, sdp, m); - + if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) { match = 0; goto done; @@ -3634,10 +3980,46 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s if (sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU)) { pass = 0; } - + + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || + switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) || !switch_rtp_ready(tech_pvt->rtp_session)) { + pass = 0; + } + if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); switch_core_session_message_t *msg; + char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session); + switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session); + char tmp[32] = ""; + + tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, t38_options->remote_ip); + tech_pvt->remote_sdp_audio_port = t38_options->remote_port; + + if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", + switch_channel_get_name(tech_pvt->channel)); + } else { + const char *err = NULL; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n", + switch_channel_get_name(tech_pvt->channel), + remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port); + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); + + if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); + } + + } + + + sofia_glue_copy_t38_options(t38_options, other_session); sofia_set_flag(tech_pvt, TFLAG_T38_PASSTHRU); @@ -3799,6 +4181,9 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s uint32_t near_rate = 0; const switch_codec_implementation_t *mimp = NULL, *near_match = NULL; const char *rm_encoding; + uint32_t map_bit_rate = 0; + int codec_ms = 0; + switch_codec_fmtp_t codec_fmtp = { 0 }; if (x++ < skip) { continue; @@ -3839,40 +4224,46 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } if (!ptime) { - ptime = 20; + ptime = switch_default_ptime(rm_encoding, map->rm_pt); } - if (!strcasecmp((char *) rm_encoding, "ilbc")) { - char *mode = NULL; - if (map->rm_fmtp && (mode = strstr(map->rm_fmtp, "mode=")) && (mode + 5)) { - codec_ms = atoi(mode + 5); + map_bit_rate = switch_known_bitrate(map->rm_pt); + + if (!zstr(map->rm_fmtp)) { + if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) { + if (codec_fmtp.bits_per_second) { + map_bit_rate = codec_fmtp.bits_per_second; + } + if (codec_fmtp.microseconds_per_packet) { + ptime = (codec_fmtp.microseconds_per_packet / 1000); + } } - if (!codec_ms) { - /* default to 30 when no mode is defined for ilbc ONLY */ - codec_ms = 30; - } - } else { - codec_ms = ptime; } - - + + codec_ms = ptime; for (i = first; i < last && i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; + uint32_t bit_rate = imp->bits_per_second; uint32_t codec_rate = imp->samples_per_second; if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) { continue; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d]/[%s:%d:%u:%d]\n", - rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, - imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u]/[%s:%d:%u:%d:%u]\n", + rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, map_bit_rate, + imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate); if ((zstr(map->rm_encoding) || (tech_pvt->profile->ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { match = (map->rm_pt == imp->ianacode) ? 1 : 0; } else { match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1; } + if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate) { + /* nevermind */ + match = 0; + } + if (match) { if (scrooge) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, @@ -3934,6 +4325,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s tech_pvt->pt = (switch_payload_t) map->rm_pt; tech_pvt->rm_rate = map->rm_rate; tech_pvt->codec_ms = mimp->microseconds_per_packet / 1000; + tech_pvt->bitrate = mimp->bits_per_second; tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, (char *) connection->c_address); tech_pvt->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp); tech_pvt->remote_sdp_audio_port = (switch_port_t) m->m_port; @@ -4342,6 +4734,47 @@ void sofia_glue_restart_all_profiles(void) } + +void sofia_glue_global_siptrace(switch_bool_t on) +{ + switch_hash_index_t *hi; + const void *var; + void *val; + sofia_profile_t *pptr; + + switch_mutex_lock(mod_sofia_globals.hash_mutex); + if (mod_sofia_globals.profile_hash) { + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + if ((pptr = (sofia_profile_t *) val)) { + nua_set_params(pptr->nua, TPTAG_LOG(on), TAG_END()); + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + +} + +void sofia_glue_global_watchdog(switch_bool_t on) +{ + switch_hash_index_t *hi; + const void *var; + void *val; + sofia_profile_t *pptr; + + switch_mutex_lock(mod_sofia_globals.hash_mutex); + if (mod_sofia_globals.profile_hash) { + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + if ((pptr = (sofia_profile_t *) val)) { + pptr->watchdog_enabled = (on ? 1 : 0); + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + +} + void sofia_glue_del_profile(sofia_profile_t *profile) { sofia_gateway_t *gp; @@ -4495,13 +4928,13 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName } if ((tmp = switch_channel_get_variable(channel, "sip_use_pt"))) { - tech_pvt->pt = tech_pvt->agreed_pt = atoi(tmp); + tech_pvt->pt = tech_pvt->agreed_pt = (switch_payload_t)atoi(tmp); } sofia_glue_tech_set_codec(tech_pvt, 1); tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip; - tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = atoi(port); + tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = (switch_port_t)atoi(port); if ((tmp = switch_channel_get_variable(channel, "local_media_ip"))) { tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, tmp); @@ -4510,12 +4943,12 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName if (r_ip && r_port) { tech_pvt->remote_sdp_audio_ip = (char *) r_ip; - tech_pvt->remote_sdp_audio_port = atoi(r_port); + tech_pvt->remote_sdp_audio_port = (switch_port_t)atoi(r_port); } if (switch_channel_test_flag(channel, CF_VIDEO)) { if ((tmp = switch_channel_get_variable(channel, "sip_use_video_pt"))) { - tech_pvt->video_pt = tech_pvt->video_agreed_pt = atoi(tmp); + tech_pvt->video_pt = tech_pvt->video_agreed_pt = (switch_payload_t)atoi(tmp); } @@ -4537,11 +4970,11 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName tech_pvt->video_codec_ms = atoi(tmp); } - tech_pvt->adv_sdp_video_port = tech_pvt->local_sdp_video_port = atoi(port); + tech_pvt->adv_sdp_video_port = tech_pvt->local_sdp_video_port = (switch_port_t)atoi(port); if (r_ip && r_port) { tech_pvt->remote_sdp_video_ip = (char *) r_ip; - tech_pvt->remote_sdp_video_port = atoi(r_port); + tech_pvt->remote_sdp_video_port = (switch_port_t)atoi(r_port); } //sofia_glue_tech_set_video_codec(tech_pvt, 1); } @@ -4834,7 +5267,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile) " profile_name VARCHAR(255),\n" " hostname VARCHAR(255),\n" " network_port VARCHAR(6),\n" - " network_ip VARCHAR(255)\n" + " network_ip VARCHAR(255),\n" + " version INTEGER DEFAULT 0 NOT NULL\n" ");\n"; char auth_sql[] = @@ -4954,7 +5388,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile) free(test_sql); - test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and network_ip like '%%' and network_port like '%%'", + test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and version < 0 and network_ip like '%%' and network_port like '%%'", mod_sofia_globals.hostname); switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_subscriptions", sub_sql); @@ -5426,6 +5860,23 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt) } +void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl) +{ + switch_core_session_message_t *msg; + msg = switch_core_session_alloc(session, sizeof(*msg)); + MESSAGE_STAMP_FFL(msg); + msg->message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ; + if (pl) { + msg->string_arg = switch_core_session_strdup(session, pl); + } + msg->from = __FILE__; + + switch_core_session_queue_message(session, msg); +} + + + + /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 5eb71b37e9..55b0c5c5ca 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -571,7 +571,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) switch_safe_free(sql); - sql = switch_mprintf("select sip_registrations.sip_user, sip_registrations.orig_server_host, sip_registrations.status, " + sql = switch_mprintf("select sip_registrations.sip_user, sip_registrations.sip_host, sip_registrations.status, " "sip_registrations.rpid,'', sip_dialogs.uuid, sip_dialogs.state, sip_dialogs.direction, " "sip_dialogs.sip_to_user, sip_dialogs.sip_to_host, sip_presence.status,sip_presence.rpid,sip_presence.open_closed," "'%q','%q' " @@ -700,7 +700,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," "sip_subscriptions.accept,sip_subscriptions.profile_name" - ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q' " + ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',sip_subscriptions.version " "from sip_subscriptions " "left join sip_presence on " "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and " @@ -742,14 +742,21 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) } sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_presence_sub_callback, &helper); + switch_safe_free(sql); + + sql = switch_mprintf("update sip_subscriptions set version=version+1 where event='dialog' and sub_to_user='%q' " + "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " + "and (profile_name = '%q' or presence_hosts != sub_to_host)", + euser, host, host, profile->name); + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n", event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); } - switch_safe_free(sql); - if (!zstr((char *) helper.stream.data)) { char *this_sql = (char *) helper.stream.data; char *next = NULL; @@ -1193,7 +1200,8 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * int kill_handle = 0; char expires_str[10] = ""; char status_line[256] = ""; - + char *version = "0"; + //int i; //for(i = 0; i < argc; i++) { @@ -1213,6 +1221,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (argc > 20) { dialog_status = argv[20]; dialog_rpid = argv[21]; + version = argv[22]; } in = helper->event && helper->event->event_id == SWITCH_EVENT_PRESENCE_IN; @@ -1317,8 +1326,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * } if (is_dialog) { - char *version = switch_event_get_header(helper->event, "event_count"); - if (!version) { + if (zstr(version)) { version = "0"; } @@ -1983,12 +1991,20 @@ void sofia_presence_handle_sip_i_subscribe(int status, is_nat = NULL; } + if (zstr(contact_host)) { + is_nat = "No contact host"; + } + if (is_nat) { contact_host = network_ip; switch_snprintf(new_port, sizeof(new_port), ":%d", network_port); port = NULL; } + if (zstr(contact_host)) { + nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END()); + return; + } if (port) { switch_snprintf(new_port, sizeof(new_port), ":%s", port); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 3ffbc26c33..285dc8ae3a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -820,9 +820,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_event_t *auth_params = NULL; int r = 0; long reg_count = 0; - int delete_subs = 1; + int delete_subs; const char *agent = "unknown"; + delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG); /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */ switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL); @@ -841,10 +842,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (sip->sip_user_agent) { agent = sip->sip_user_agent->g_string; - - if (switch_stristr("snom", agent)) { - delete_subs = 0; - } } if (from) { @@ -934,7 +931,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (sip->sip_path) { path_val = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_path); - path_encoded_len = (strlen(path_val) * 3) + 1; + path_encoded_len = (int)(strlen(path_val) * 3) + 1; switch_zmalloc(path_encoded, path_encoded_len); switch_copy_string(path_encoded, ";fs_path=", 10); switch_url_encode(path_val, path_encoded + 9, path_encoded_len - 9); @@ -947,7 +944,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port); } - path_encoded_len = (strlen(my_contact_str) * 3) + 1; + path_encoded_len = (int)(strlen(my_contact_str) * 3) + 1; switch_zmalloc(path_encoded, path_encoded_len); switch_copy_string(path_encoded, ";fs_path=", 10); @@ -2126,7 +2123,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (auth_acl) { if (!switch_check_network_list_ip(ip, auth_acl)) { - int network_ip_is_proxy = 0, x = 0; + int network_ip_is_proxy = 0; + uint32_t x = 0; char *last_acl = NULL; if (profile->proxy_acl_count == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by user acl [%s] and no proxy acl present\n", ip, auth_acl); @@ -2223,7 +2221,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (max_registrations_perext > 0 && (sip && sip->sip_contact && (sip->sip_contact->m_expires == NULL || atol(sip->sip_contact->m_expires) > 0))) { /* if expires is null still process */ /* expires == 0 means the phone is going to unregiser, so don't count against max */ - int count = 0; + uint32_t count = 0; call_id = sip->sip_call_id->i_id; switch_assert(call_id); @@ -2498,7 +2496,7 @@ sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char switch_mutex_lock(mod_sofia_globals.hash_mutex); for (hi = switch_hash_first(NULL, mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); - if ((gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) { + if (key && (gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) { break; } else { gateway = NULL; diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index d3fa2e8a45..97f20b867a 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -1100,7 +1100,7 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames) { struct holder *holder = (struct holder *) pArg; char title_b4[128] = ""; - char title_aft[128 * 3] = ""; + char title_aft[128 * 3 + 1] = ""; char *mp3, *m3u; /* diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java index 2b9353c063..e7bcb56834 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java @@ -213,12 +213,12 @@ public class CoreSession { return freeswitchJNI.CoreSession_transfer(swigCPtr, this, extension, dialplan, context); } - public String read(int min_digits, int max_digits, String prompt_audio_file, int timeout, String valid_terminators) { - return freeswitchJNI.CoreSession_read(swigCPtr, this, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators); + public String read(int min_digits, int max_digits, String prompt_audio_file, int timeout, String valid_terminators, int digit_timeout) { + return freeswitchJNI.CoreSession_read(swigCPtr, this, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout); } - public String playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, String terminators, String audio_files, String bad_input_audio_files, String digits_regex, String var_name) { - return freeswitchJNI.CoreSession_playAndGetDigits(swigCPtr, this, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name); + public String playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, String terminators, String audio_files, String bad_input_audio_files, String digits_regex, String var_name, int digit_timeout) { + return freeswitchJNI.CoreSession_playAndGetDigits(swigCPtr, this, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout); } public int streamFile(String file, int starting_sample_count) { diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java index 541777840b..206103c4be 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java @@ -125,8 +125,8 @@ class freeswitchJNI { public final static native String CoreSession_getDigits__SWIG_0(long jarg1, CoreSession jarg1_, int jarg2, String jarg3, int jarg4); public final static native String CoreSession_getDigits__SWIG_1(long jarg1, CoreSession jarg1_, int jarg2, String jarg3, int jarg4, int jarg5); public final static native int CoreSession_transfer(long jarg1, CoreSession jarg1_, String jarg2, String jarg3, String jarg4); - public final static native String CoreSession_read(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, String jarg4, int jarg5, String jarg6); - public final static native String CoreSession_playAndGetDigits(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, int jarg4, int jarg5, String jarg6, String jarg7, String jarg8, String jarg9, String jarg10); + public final static native String CoreSession_read(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, String jarg4, int jarg5, String jarg6, int jarg7); + public final static native String CoreSession_playAndGetDigits(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, int jarg4, int jarg5, String jarg6, String jarg7, String jarg8, String jarg9, String jarg10, int jarg11); public final static native int CoreSession_streamFile(long jarg1, CoreSession jarg1_, String jarg2, int jarg3); public final static native int CoreSession_sleep(long jarg1, CoreSession jarg1_, int jarg2, int jarg3); public final static native int CoreSession_flushEvents(long jarg1, CoreSession jarg1_); diff --git a/src/mod/languages/mod_java/switch_swig_wrap.cpp b/src/mod/languages/mod_java/switch_swig_wrap.cpp index fc9d6c4681..b275b170d6 100644 --- a/src/mod/languages/mod_java/switch_swig_wrap.cpp +++ b/src/mod/languages/mod_java/switch_swig_wrap.cpp @@ -2405,7 +2405,7 @@ SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1tran } -SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1read(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jstring jarg4, jint jarg5, jstring jarg6) { +SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1read(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jstring jarg4, jint jarg5, jstring jarg6, jint jarg7) { jstring jresult = 0 ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -2413,6 +2413,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; (void)jenv; @@ -2432,7 +2433,8 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r arg6 = (char *)jenv->GetStringUTFChars(jarg6, 0); if (!arg6) return 0; } - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + arg7 = (int)jarg7; + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); if(result) jresult = jenv->NewStringUTF((const char *)result); if (arg4) jenv->ReleaseStringUTFChars(jarg4, (const char *)arg4); if (arg6) jenv->ReleaseStringUTFChars(jarg6, (const char *)arg6); @@ -2440,7 +2442,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r } -SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1playAndGetDigits(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jint jarg4, jint jarg5, jstring jarg6, jstring jarg7, jstring jarg8, jstring jarg9, jstring jarg10) { +SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1playAndGetDigits(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jint jarg4, jint jarg5, jstring jarg6, jstring jarg7, jstring jarg8, jstring jarg9, jstring jarg10, jint jarg11) { jstring jresult = 0 ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -2452,6 +2454,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1p char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; (void)jenv; @@ -2487,7 +2490,8 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1p arg10 = (char *)jenv->GetStringUTFChars(jarg10, 0); if (!arg10) return 0; } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + arg11 = (int)jarg11; + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); if(result) jresult = jenv->NewStringUTF((const char *)result); if (arg6) jenv->ReleaseStringUTFChars(jarg6, (const char *)arg6); if (arg7) jenv->ReleaseStringUTFChars(jarg7, (const char *)arg7); diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 4bf4b67154..5c189cd288 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -5175,15 +5175,17 @@ static int _wrap_CoreSession_read(lua_State* L) { char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; - SWIG_check_num_args("read",6,6) + SWIG_check_num_args("read",6,7) if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("read",1,"CoreSession *"); if(!lua_isnumber(L,2)) SWIG_fail_arg("read",2,"int"); if(!lua_isnumber(L,3)) SWIG_fail_arg("read",3,"int"); if(!lua_isstring(L,4)) SWIG_fail_arg("read",4,"char const *"); if(!lua_isnumber(L,5)) SWIG_fail_arg("read",5,"int"); if(!lua_isstring(L,6)) SWIG_fail_arg("read",6,"char const *"); + if(lua_gettop(L)>=7 && !lua_isnumber(L,7)) SWIG_fail_arg("read",7,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){ SWIG_fail_ptr("CoreSession_read",1,SWIGTYPE_p_CoreSession); @@ -5194,7 +5196,10 @@ static int _wrap_CoreSession_read(lua_State* L) { arg4 = (char *)lua_tostring(L, 4); arg5 = (int)lua_tonumber(L, 5); arg6 = (char *)lua_tostring(L, 6); - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + if(lua_gettop(L)>=7){ + arg7 = (int)lua_tonumber(L, 7); + } + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); SWIG_arg=0; lua_pushstring(L,(const char*)result); SWIG_arg++; return SWIG_arg; @@ -5219,9 +5224,10 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) { char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; - SWIG_check_num_args("playAndGetDigits",9,10) + SWIG_check_num_args("playAndGetDigits",9,11) if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("playAndGetDigits",1,"CoreSession *"); if(!lua_isnumber(L,2)) SWIG_fail_arg("playAndGetDigits",2,"int"); if(!lua_isnumber(L,3)) SWIG_fail_arg("playAndGetDigits",3,"int"); @@ -5232,6 +5238,7 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) { if(!lua_isstring(L,8)) SWIG_fail_arg("playAndGetDigits",8,"char *"); if(!lua_isstring(L,9)) SWIG_fail_arg("playAndGetDigits",9,"char *"); if(lua_gettop(L)>=10 && !lua_isstring(L,10)) SWIG_fail_arg("playAndGetDigits",10,"char const *"); + if(lua_gettop(L)>=11 && !lua_isnumber(L,11)) SWIG_fail_arg("playAndGetDigits",11,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){ SWIG_fail_ptr("CoreSession_playAndGetDigits",1,SWIGTYPE_p_CoreSession); @@ -5248,7 +5255,10 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) { if(lua_gettop(L)>=10){ arg10 = (char *)lua_tostring(L, 10); } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + if(lua_gettop(L)>=11){ + arg11 = (int)lua_tonumber(L, 11); + } + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); SWIG_arg=0; lua_pushstring(L,(const char*)result); SWIG_arg++; return SWIG_arg; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 04a2f3f967..5a2a757e57 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -1011,6 +1011,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABL } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("passthru_ptime_mismatch"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -1331,6 +1341,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_EXPORT_VARS_VARIABLE_get() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("bridge_export_vars"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_R_SDP_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -1675,6 +1695,28 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_dtmf_t_duration_get(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_dtmf_t_flags_set(void * jarg1, int jarg2) { + switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; + int32_t arg2 ; + + arg1 = (switch_dtmf_t *)jarg1; + arg2 = (int32_t)jarg2; + if (arg1) (arg1)->flags = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dtmf_t_flags_get(void * jarg1) { + int jresult ; + switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; + int32_t result; + + arg1 = (switch_dtmf_t *)jarg1; + result = (int32_t) ((arg1)->flags); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_dtmf_t() { void * jresult ; switch_dtmf_t *result = 0 ; @@ -3583,24 +3625,24 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_remote_ip_get(void * j } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->remote_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->remote_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->remote_port); + jresult = result; return jresult; } @@ -3634,24 +3676,24 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_local_ip_get(void * ja } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->local_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->local_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->local_port); + jresult = result; return jresult; } @@ -3850,6 +3892,151 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_console_callback_match(void * j } +SWIGEXPORT int SWIGSTDCALL CSharp_DMACHINE_MAX_DIGIT_LEN_get() { + int jresult ; + int result; + + result = (int)(512); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_dmachine_set(void * jarg1, void * jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + switch_ivr_dmachine_t *arg2 = (switch_ivr_dmachine_t *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (switch_ivr_dmachine_t *)jarg2; + if (arg1) (arg1)->dmachine = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_ivr_dmachine_match_dmachine_get(void * jarg1) { + void * jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + switch_ivr_dmachine_t *result = 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (switch_ivr_dmachine_t *) ((arg1)->dmachine); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_digits_set(void * jarg1, char * jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->match_digits = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->match_digits, (const char *)arg2); + } else { + arg1->match_digits = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_digits_get(void * jarg1) { + char * jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + char *result = 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (char *) ((arg1)->match_digits); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_key_set(void * jarg1, int jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + int32_t arg2 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (int32_t)jarg2; + if (arg1) (arg1)->match_key = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_key_get(void * jarg1) { + int jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + int32_t result; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (int32_t) ((arg1)->match_key); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_type_set(void * jarg1, int jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + dm_match_type_t arg2 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (dm_match_type_t)jarg2; + if (arg1) (arg1)->type = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_match_type_get(void * jarg1) { + int jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + dm_match_type_t result; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (dm_match_type_t) ((arg1)->type); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_user_data_set(void * jarg1, void * jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->user_data = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_ivr_dmachine_match_user_data_get(void * jarg1) { + void * jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + void *result = 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (void *) ((arg1)->user_data); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_ivr_dmachine_match() { + void * jresult ; + switch_ivr_dmachine_match *result = 0 ; + + result = (switch_ivr_dmachine_match *)new switch_ivr_dmachine_match(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_ivr_dmachine_match(void * jarg1) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_input_args_t_input_callback_set(void * jarg1, void * jarg2) { switch_input_args_t *arg1 = (switch_input_args_t *) 0 ; switch_input_callback_function_t arg2 = (switch_input_callback_function_t) 0 ; @@ -3960,6 +4147,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_input_args_t_user_data_get(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_input_args_t_dmachine_set(void * jarg1, void * jarg2) { + switch_input_args_t *arg1 = (switch_input_args_t *) 0 ; + switch_ivr_dmachine_t *arg2 = (switch_ivr_dmachine_t *) 0 ; + + arg1 = (switch_input_args_t *)jarg1; + arg2 = (switch_ivr_dmachine_t *)jarg2; + if (arg1) (arg1)->dmachine = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_input_args_t_dmachine_get(void * jarg1) { + void * jresult ; + switch_input_args_t *arg1 = (switch_input_args_t *) 0 ; + switch_ivr_dmachine_t *result = 0 ; + + arg1 = (switch_input_args_t *)jarg1; + result = (switch_ivr_dmachine_t *) ((arg1)->dmachine); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_input_args_t() { void * jresult ; switch_input_args_t *result = 0 ; @@ -4066,7 +4275,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_API_VERSION_get() { int jresult ; int result; - result = (int)(4); + result = (int)(5); jresult = result; return jresult; } @@ -6831,6 +7040,28 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_soft_unlock(void * jarg1) } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_set_dmachine(void * jarg1, void * jarg2) { + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_ivr_dmachine_t *arg2 = (switch_ivr_dmachine_t *) 0 ; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (switch_ivr_dmachine_t *)jarg2; + switch_core_session_set_dmachine(arg1,arg2); +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_dmachine(void * jarg1) { + void * jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_ivr_dmachine_t *result = 0 ; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_ivr_dmachine_t *)switch_core_session_get_dmachine(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_uuid() { char * jresult ; char *result = 0 ; @@ -7872,7 +8103,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_timer_destroy(void * jarg1) { } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, void * jarg8, void * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init_with_bitrate(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, unsigned long jarg8, void * jarg9, void * jarg10) { int jresult ; switch_codec_t *arg1 = (switch_codec_t *) 0 ; char *arg2 = (char *) 0 ; @@ -7881,8 +8112,9 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja int arg5 ; int arg6 ; uint32_t arg7 ; - switch_codec_settings_t *arg8 = (switch_codec_settings_t *) 0 ; - switch_memory_pool_t *arg9 = (switch_memory_pool_t *) 0 ; + uint32_t arg8 ; + switch_codec_settings_t *arg9 = (switch_codec_settings_t *) 0 ; + switch_memory_pool_t *arg10 = (switch_memory_pool_t *) 0 ; switch_status_t result; arg1 = (switch_codec_t *)jarg1; @@ -7892,9 +8124,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (uint32_t)jarg7; - arg8 = (switch_codec_settings_t *)jarg8; - arg9 = (switch_memory_pool_t *)jarg9; - result = (switch_status_t)switch_core_codec_init(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,(switch_codec_settings const *)arg8,arg9); + arg8 = (uint32_t)jarg8; + arg9 = (switch_codec_settings_t *)jarg9; + arg10 = (switch_memory_pool_t *)jarg10; + result = (switch_status_t)switch_core_codec_init_with_bitrate(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,arg8,(switch_codec_settings const *)arg9,arg10); jresult = result; return jresult; } @@ -7916,6 +8149,24 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_copy(void * jarg1, void * ja } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_parse_fmtp(char * jarg1, char * jarg2, unsigned long jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + uint32_t arg3 ; + switch_codec_fmtp_t *arg4 = (switch_codec_fmtp_t *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (uint32_t)jarg3; + arg4 = (switch_codec_fmtp_t *)jarg4; + result = (switch_status_t)switch_core_codec_parse_fmtp((char const *)arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_reset(void * jarg1) { int jresult ; switch_codec_t *arg1 = (switch_codec_t *) 0 ; @@ -10181,6 +10432,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_in_thread(void * jarg1) { } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_default_ptime(char * jarg1, unsigned long jarg2) { + unsigned long jresult ; + char *arg1 = (char *) 0 ; + uint32_t arg2 ; + uint32_t result; + + arg1 = (char *)jarg1; + arg2 = (uint32_t)jarg2; + result = (uint32_t)switch_default_ptime((char const *)arg1,arg2); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_set(void * jarg1, char * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; char *arg2 = (char *) 0 ; @@ -11527,6 +11792,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_digit_string(char * jarg1) { } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_known_bitrate(unsigned char jarg1) { + unsigned long jresult ; + switch_payload_t arg1 ; + uint32_t result; + + arg1 = (switch_payload_t)jarg1; + result = (uint32_t)switch_known_bitrate(arg1); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_switch_fd_read_line(int jarg1, char * jarg2, void * jarg3) { void * jresult ; int arg1 ; @@ -12397,6 +12674,44 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_network_list_validate_ip_token(void * j } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_dow_int2str(int jarg1) { + char * jresult ; + int arg1 ; + char *result = 0 ; + + arg1 = (int)jarg1; + result = (char *)switch_dow_int2str(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dow_str2int(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_dow_str2int((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dow_cmp(char * jarg1, int jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + int arg2 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (int)jarg2; + result = (int)switch_dow_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_number_cmp(char * jarg1, int jarg2) { int jresult ; char *arg1 = (char *) 0 ; @@ -12411,6 +12726,62 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_number_cmp(char * jarg1, int jarg2) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_tod_cmp(char * jarg1, int jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + int arg2 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (int)jarg2; + result = (int)switch_tod_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_fulldate_cmp(char * jarg1, void * jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_time_t *arg2 = (switch_time_t *) 0 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (switch_time_t *)jarg2; + result = (int)switch_fulldate_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_split_date(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { + char *arg1 = (char *) 0 ; + int *arg2 = (int *) 0 ; + int *arg3 = (int *) 0 ; + int *arg4 = (int *) 0 ; + + arg1 = (char *)jarg1; + arg2 = (int *)jarg2; + arg3 = (int *)jarg3; + arg4 = (int *)jarg4; + switch_split_date((char const *)arg1,arg2,arg3,arg4); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_split_time(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { + char *arg1 = (char *) 0 ; + int *arg2 = (int *) 0 ; + int *arg3 = (int *) 0 ; + int *arg4 = (int *) 0 ; + + arg1 = (char *)jarg1; + arg2 = (int *)jarg2; + arg3 = (int *)jarg3; + arg4 = (int *)jarg4; + switch_split_time((char const *)arg1,arg2,arg3,arg4); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_split_user_domain(char * jarg1, void * jarg2, void * jarg3) { int jresult ; char *arg1 = (char *) 0 ; @@ -19883,353 +20254,23 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_directory_handle(void * jarg1) } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_quality_set(void * jarg1, int jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_unused_set(void * jarg1, int jarg2) { switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int arg2 ; arg1 = (switch_codec_settings *)jarg1; arg2 = (int)jarg2; - if (arg1) (arg1)->quality = arg2; + if (arg1) (arg1)->unused = arg2; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_quality_get(void * jarg1) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_unused_get(void * jarg1) { int jresult ; switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int result; arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_complexity_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->complexity = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_complexity_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->complexity); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_enhancement_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->enhancement = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_enhancement_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->enhancement); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vad = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vbr = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vbr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vbr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->vbr_quality = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->vbr_quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_abr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->abr = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_abr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->abr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_dtx_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->dtx = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_dtx_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->dtx); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_preproc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->preproc = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_preproc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->preproc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_vad = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_agc = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_agc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_agc_level = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_agc_level); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_denoise = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_denoise); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_dereverb = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_dereverb); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_decay = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_decay); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_level = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_level); + result = (int) ((arg1)->unused); jresult = result; return jresult; } @@ -20253,6 +20294,112 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_settings(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_set(void * jarg1, unsigned long jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->actual_samples_per_second = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_get(void * jarg1) { + unsigned long jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (uint32_t) ((arg1)->actual_samples_per_second); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->bits_per_second = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->bits_per_second); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->microseconds_per_packet = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->microseconds_per_packet); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_set(void * jarg1, void * jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->private_info = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_get(void * jarg1) { + void * jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *result = 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (void *) ((arg1)->private_info); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec_fmtp() { + void * jresult ; + switch_codec_fmtp *result = 0 ; + + result = (switch_codec_fmtp *)new switch_codec_fmtp(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_fmtp(void * jarg1) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_interface_set(void * jarg1, void * jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; @@ -20357,28 +20504,6 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_codec_fmtp_out_get(void * jarg1) { } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_settings_set(void * jarg1, void * jarg2) { - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *arg2 = (switch_codec_settings_t *) 0 ; - - arg1 = (switch_codec *)jarg1; - arg2 = (switch_codec_settings_t *)jarg2; - if (arg1) (arg1)->codec_settings = *arg2; -} - - -SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_codec_settings_get(void * jarg1) { - void * jresult ; - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *result = 0 ; - - arg1 = (switch_codec *)jarg1; - result = (switch_codec_settings_t *)& ((arg1)->codec_settings); - jresult = (void *)result; - return jresult; -} - - SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_flags_set(void * jarg1, unsigned long jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; uint32_t arg2 ; @@ -21054,6 +21179,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_implementations_get( } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_set(void * jarg1, void * jarg2) { + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t arg2 = (switch_core_codec_fmtp_parse_func_t) 0 ; + + arg1 = (switch_codec_interface *)jarg1; + arg2 = (switch_core_codec_fmtp_parse_func_t)jarg2; + if (arg1) (arg1)->parse_fmtp = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_get(void * jarg1) { + void * jresult ; + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t result; + + arg1 = (switch_codec_interface *)jarg1; + result = (switch_core_codec_fmtp_parse_func_t) ((arg1)->parse_fmtp); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_codec_id_set(void * jarg1, unsigned long jarg2) { switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; uint32_t arg2 ; @@ -22461,36 +22608,54 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_variable_partner(void * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, int jarg4) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; - switch_bool_t arg4 ; + char *arg4 = (char *) 0 ; + switch_bool_t arg5 ; switch_status_t result; arg1 = (switch_channel_t *)jarg1; arg2 = (char *)jarg2; arg3 = (char *)jarg3; - arg4 = (switch_bool_t)jarg4; - result = (switch_status_t)switch_channel_export_variable_var_check(arg1,(char const *)arg2,(char const *)arg3,arg4); + arg4 = (char *)jarg4; + arg5 = (switch_bool_t)jarg5; + result = (switch_status_t)switch_channel_export_variable_var_check(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5); jresult = result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_printf(void * jarg1, char * jarg2, char * jarg3) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_process_export(void * jarg1, void * jarg2, void * jarg3, char * jarg4) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_channel_t *arg2 = (switch_channel_t *) 0 ; + switch_event_t *arg3 = (switch_event_t *) 0 ; + char *arg4 = (char *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (switch_channel_t *)jarg2; + arg3 = (switch_event_t *)jarg3; + arg4 = (char *)jarg4; + switch_channel_process_export(arg1,arg2,arg3,(char const *)arg4); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_printf(void * jarg1, char * jarg2, char * jarg3, char * jarg4) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; - void *arg4 = 0 ; + char *arg4 = (char *) 0 ; + void *arg5 = 0 ; switch_status_t result; arg1 = (switch_channel_t *)jarg1; arg2 = (char *)jarg2; arg3 = (char *)jarg3; - result = (switch_status_t)switch_channel_export_variable_printf(arg1,(char const *)arg2,(char const *)arg3,arg4); + arg4 = (char *)jarg4; + result = (switch_status_t)switch_channel_export_variable_printf(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5); jresult = result; return jresult; } @@ -26020,7 +26185,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_file(void * jarg1, void * ja } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12, unsigned long jarg13) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -26034,6 +26199,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig char *arg10 = (char *) 0 ; uint32_t arg11 ; char *arg12 = (char *) 0 ; + uint32_t arg13 ; switch_status_t result; arg1 = (switch_core_session_t *)jarg1; @@ -26048,7 +26214,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig arg10 = (char *)jarg10; arg11 = (uint32_t)jarg11; arg12 = (char *)jarg12; - result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12); + arg13 = (uint32_t)jarg13; + result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12,arg13); jresult = result; return jresult; } @@ -26420,6 +26587,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_broadcast(char * jarg1, char * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_broadcast_in_thread(void * jarg1, char * jarg2, int jarg3) { + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (int)jarg3; + switch_ivr_broadcast_in_thread(arg1,(char const *)arg2,arg3); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_transfer_variable(void * jarg1, void * jarg2, char * jarg3) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -26822,7 +27001,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_wait_for_answer(void * jarg1, void } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9, unsigned long jarg10) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -26833,6 +27012,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja switch_size_t arg7 ; uint32_t arg8 ; char *arg9 = (char *) 0 ; + uint32_t arg10 ; switch_size_t *argp7 ; switch_status_t result; @@ -26850,7 +27030,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja arg7 = *argp7; arg8 = (uint32_t)jarg8; arg9 = (char *)jarg9; - result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9); + arg10 = (uint32_t)jarg10; + result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9,arg10); jresult = result; return jresult; } @@ -27078,6 +27259,176 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_uuid_exists(char * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_create(void * jarg1, char * jarg2, void * jarg3, unsigned long jarg4, unsigned long jarg5, void * jarg6, void * jarg7, void * jarg8) { + int jresult ; + switch_ivr_dmachine_t **arg1 = (switch_ivr_dmachine_t **) 0 ; + char *arg2 = (char *) 0 ; + switch_memory_pool_t *arg3 = (switch_memory_pool_t *) 0 ; + uint32_t arg4 ; + uint32_t arg5 ; + switch_ivr_dmachine_callback_t arg6 = (switch_ivr_dmachine_callback_t) 0 ; + switch_ivr_dmachine_callback_t arg7 = (switch_ivr_dmachine_callback_t) 0 ; + void *arg8 = (void *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t **)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_memory_pool_t *)jarg3; + arg4 = (uint32_t)jarg4; + arg5 = (uint32_t)jarg5; + arg6 = (switch_ivr_dmachine_callback_t)jarg6; + arg7 = (switch_ivr_dmachine_callback_t)jarg7; + arg8 = (void *)jarg8; + result = (switch_status_t)switch_ivr_dmachine_create(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7,arg8); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_destroy(void * jarg1) { + switch_ivr_dmachine_t **arg1 = (switch_ivr_dmachine_t **) 0 ; + + arg1 = (switch_ivr_dmachine_t **)jarg1; + switch_ivr_dmachine_destroy(arg1); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_bind(void * jarg1, char * jarg2, char * jarg3, int jarg4, void * jarg5, void * jarg6) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + int32_t arg4 ; + switch_ivr_dmachine_callback_t arg5 = (switch_ivr_dmachine_callback_t) 0 ; + void *arg6 = (void *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (int32_t)jarg4; + arg5 = (switch_ivr_dmachine_callback_t)jarg5; + arg6 = (void *)jarg6; + result = (switch_status_t)switch_ivr_dmachine_bind(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_feed(void * jarg1, char * jarg2, void * jarg3) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_ivr_dmachine_match_t **arg3 = (switch_ivr_dmachine_match_t **) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_ivr_dmachine_match_t **)jarg3; + result = (switch_status_t)switch_ivr_dmachine_feed(arg1,(char const *)arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_clear(void * jarg1) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + result = (switch_status_t)switch_ivr_dmachine_clear(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_ping(void * jarg1, void * jarg2) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + switch_ivr_dmachine_match_t **arg2 = (switch_ivr_dmachine_match_t **) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (switch_ivr_dmachine_match_t **)jarg2; + result = (switch_status_t)switch_ivr_dmachine_ping(arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_ivr_dmachine_get_match(void * jarg1) { + void * jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + switch_ivr_dmachine_match_t *result = 0 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + result = (switch_ivr_dmachine_match_t *)switch_ivr_dmachine_get_match(arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_ivr_dmachine_get_failed_digits(void * jarg1) { + char * jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + result = (char *)switch_ivr_dmachine_get_failed_digits(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_set_digit_timeout_ms(void * jarg1, unsigned long jarg2) { + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (uint32_t)jarg2; + switch_ivr_dmachine_set_digit_timeout_ms(arg1,arg2); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_set_input_timeout_ms(void * jarg1, unsigned long jarg2) { + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (uint32_t)jarg2; + switch_ivr_dmachine_set_input_timeout_ms(arg1,arg2); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_clear_realm(void * jarg1, char * jarg2) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_dmachine_clear_realm(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_set_realm(void * jarg1, char * jarg2) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_dmachine_set_realm(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RTP_MAX_BUF_LEN_get() { int jresult ; int result; @@ -28057,6 +28408,18 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_stats(void * jarg1, void * j } +SWIGEXPORT unsigned char SWIGSTDCALL CSharp_switch_rtp_check_auto_adj(void * jarg1) { + unsigned char jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_byte_t result; + + arg1 = (switch_rtp_t *)jarg1; + result = (switch_byte_t)switch_rtp_check_auto_adj(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_log_node_t_data_set(void * jarg1, char * jarg2) { switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; char *arg2 = (char *) 0 ; @@ -29133,6 +29496,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_init(void * jarg1, void * jarg2) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_reload(void * jarg1) { + int jresult ; + char **arg1 = (char **) 0 ; + switch_status_t result; + + arg1 = (char **)jarg1; + result = (switch_status_t)switch_xml_reload((char const **)arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_destroy() { int jresult ; switch_status_t result; @@ -32717,7 +33092,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Transfer(void * jarg1, char * jarg } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6, int jarg7) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -32725,6 +33100,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -32733,13 +33109,14 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i arg4 = (char *)jarg4; arg5 = (int)jarg5; arg6 = (char *)jarg6; - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + arg7 = (int)jarg7; + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, int jarg11) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -32751,6 +33128,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -32763,7 +33141,8 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, arg8 = (char *)jarg8; arg9 = (char *)jarg9; arg10 = (char *)jarg10; - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + arg11 = (int)jarg11; + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index b4c7dddd27..82ad8ab61b 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -1070,6 +1070,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABL } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "passthru_ptime_mismatch"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -1422,6 +1433,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_EXPORT_VARS_VARIABLE_get() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "bridge_export_vars"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_R_SDP_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -1798,6 +1820,29 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_dtmf_t_duration_get(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_dtmf_t_flags_set(void * jarg1, int jarg2) { + switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; + int32_t arg2 ; + + arg1 = (switch_dtmf_t *)jarg1; + arg2 = (int32_t)jarg2; + if (arg1) (arg1)->flags = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dtmf_t_flags_get(void * jarg1) { + int jresult ; + switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; + int32_t result; + + arg1 = (switch_dtmf_t *)jarg1; + result = (int32_t) ((arg1)->flags); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_dtmf_t() { void * jresult ; switch_dtmf_t *result = 0 ; @@ -3776,25 +3821,25 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_remote_ip_get(void * j } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->remote_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->remote_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->remote_port); + jresult = result; return jresult; } @@ -3828,25 +3873,25 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_local_ip_get(void * ja } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->local_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->local_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->local_port); + jresult = result; return jresult; } @@ -4053,6 +4098,157 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_console_callback_match(void * j } +SWIGEXPORT int SWIGSTDCALL CSharp_DMACHINE_MAX_DIGIT_LEN_get() { + int jresult ; + int result; + + result = (int) 512; + + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_dmachine_set(void * jarg1, void * jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + switch_ivr_dmachine_t *arg2 = (switch_ivr_dmachine_t *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (switch_ivr_dmachine_t *)jarg2; + if (arg1) (arg1)->dmachine = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_ivr_dmachine_match_dmachine_get(void * jarg1) { + void * jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + switch_ivr_dmachine_t *result = 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (switch_ivr_dmachine_t *) ((arg1)->dmachine); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_digits_set(void * jarg1, char * jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->match_digits = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->match_digits, (const char *)arg2); + } else { + arg1->match_digits = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_digits_get(void * jarg1) { + char * jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + char *result = 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (char *) ((arg1)->match_digits); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_key_set(void * jarg1, int jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + int32_t arg2 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (int32_t)jarg2; + if (arg1) (arg1)->match_key = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_match_match_key_get(void * jarg1) { + int jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + int32_t result; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (int32_t) ((arg1)->match_key); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_type_set(void * jarg1, int jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + dm_match_type_t arg2 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (dm_match_type_t)jarg2; + if (arg1) (arg1)->type = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_match_type_get(void * jarg1) { + int jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + dm_match_type_t result; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (dm_match_type_t) ((arg1)->type); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_match_user_data_set(void * jarg1, void * jarg2) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->user_data = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_ivr_dmachine_match_user_data_get(void * jarg1) { + void * jresult ; + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + void *result = 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + result = (void *) ((arg1)->user_data); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_ivr_dmachine_match() { + void * jresult ; + switch_ivr_dmachine_match *result = 0 ; + + result = (switch_ivr_dmachine_match *)new switch_ivr_dmachine_match(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_ivr_dmachine_match(void * jarg1) { + switch_ivr_dmachine_match *arg1 = (switch_ivr_dmachine_match *) 0 ; + + arg1 = (switch_ivr_dmachine_match *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_input_args_t_input_callback_set(void * jarg1, void * jarg2) { switch_input_args_t *arg1 = (switch_input_args_t *) 0 ; switch_input_callback_function_t arg2 = (switch_input_callback_function_t) 0 ; @@ -4168,6 +4364,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_input_args_t_user_data_get(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_input_args_t_dmachine_set(void * jarg1, void * jarg2) { + switch_input_args_t *arg1 = (switch_input_args_t *) 0 ; + switch_ivr_dmachine_t *arg2 = (switch_ivr_dmachine_t *) 0 ; + + arg1 = (switch_input_args_t *)jarg1; + arg2 = (switch_ivr_dmachine_t *)jarg2; + if (arg1) (arg1)->dmachine = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_input_args_t_dmachine_get(void * jarg1) { + void * jresult ; + switch_input_args_t *arg1 = (switch_input_args_t *) 0 ; + switch_ivr_dmachine_t *result = 0 ; + + arg1 = (switch_input_args_t *)jarg1; + result = (switch_ivr_dmachine_t *) ((arg1)->dmachine); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_input_args_t() { void * jresult ; switch_input_args_t *result = 0 ; @@ -4279,7 +4498,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_API_VERSION_get() { int jresult ; int result; - result = (int) 4; + result = (int) 5; jresult = result; return jresult; @@ -7111,6 +7330,28 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_soft_unlock(void * jarg1) } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_set_dmachine(void * jarg1, void * jarg2) { + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_ivr_dmachine_t *arg2 = (switch_ivr_dmachine_t *) 0 ; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (switch_ivr_dmachine_t *)jarg2; + switch_core_session_set_dmachine(arg1,arg2); +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_dmachine(void * jarg1) { + void * jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_ivr_dmachine_t *result = 0 ; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_ivr_dmachine_t *)switch_core_session_get_dmachine(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_uuid() { char * jresult ; char *result = 0 ; @@ -8152,7 +8393,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_timer_destroy(void * jarg1) { } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, void * jarg8, void * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init_with_bitrate(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, unsigned long jarg8, void * jarg9, void * jarg10) { int jresult ; switch_codec_t *arg1 = (switch_codec_t *) 0 ; char *arg2 = (char *) 0 ; @@ -8161,8 +8402,9 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja int arg5 ; int arg6 ; uint32_t arg7 ; - switch_codec_settings_t *arg8 = (switch_codec_settings_t *) 0 ; - switch_memory_pool_t *arg9 = (switch_memory_pool_t *) 0 ; + uint32_t arg8 ; + switch_codec_settings_t *arg9 = (switch_codec_settings_t *) 0 ; + switch_memory_pool_t *arg10 = (switch_memory_pool_t *) 0 ; switch_status_t result; arg1 = (switch_codec_t *)jarg1; @@ -8172,9 +8414,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (uint32_t)jarg7; - arg8 = (switch_codec_settings_t *)jarg8; - arg9 = (switch_memory_pool_t *)jarg9; - result = (switch_status_t)switch_core_codec_init(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,(switch_codec_settings const *)arg8,arg9); + arg8 = (uint32_t)jarg8; + arg9 = (switch_codec_settings_t *)jarg9; + arg10 = (switch_memory_pool_t *)jarg10; + result = (switch_status_t)switch_core_codec_init_with_bitrate(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,arg8,(switch_codec_settings const *)arg9,arg10); jresult = result; return jresult; } @@ -8196,6 +8439,24 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_copy(void * jarg1, void * ja } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_parse_fmtp(char * jarg1, char * jarg2, unsigned long jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + uint32_t arg3 ; + switch_codec_fmtp_t *arg4 = (switch_codec_fmtp_t *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (uint32_t)jarg3; + arg4 = (switch_codec_fmtp_t *)jarg4; + result = (switch_status_t)switch_core_codec_parse_fmtp((char const *)arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_reset(void * jarg1) { int jresult ; switch_codec_t *arg1 = (switch_codec_t *) 0 ; @@ -10467,6 +10728,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_in_thread(void * jarg1) { } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_default_ptime(char * jarg1, unsigned long jarg2) { + unsigned long jresult ; + char *arg1 = (char *) 0 ; + uint32_t arg2 ; + uint32_t result; + + arg1 = (char *)jarg1; + arg2 = (uint32_t)jarg2; + result = (uint32_t)switch_default_ptime((char const *)arg1,arg2); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_set(void * jarg1, char * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; char *arg2 = (char *) 0 ; @@ -11834,6 +12109,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_digit_string(char * jarg1) { } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_known_bitrate(unsigned char jarg1) { + unsigned long jresult ; + switch_payload_t arg1 ; + uint32_t result; + + arg1 = (switch_payload_t)jarg1; + result = (uint32_t)switch_known_bitrate(arg1); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_switch_fd_read_line(int jarg1, char * jarg2, void * jarg3) { void * jresult ; int arg1 ; @@ -20549,369 +20836,24 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_directory_handle(void * jarg1) } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_quality_set(void * jarg1, int jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_unused_set(void * jarg1, int jarg2) { switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int arg2 ; arg1 = (switch_codec_settings *)jarg1; arg2 = (int)jarg2; - if (arg1) (arg1)->quality = arg2; + if (arg1) (arg1)->unused = arg2; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_quality_get(void * jarg1) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_unused_get(void * jarg1) { int jresult ; switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int result; arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_complexity_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->complexity = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_complexity_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->complexity); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_enhancement_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->enhancement = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_enhancement_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->enhancement); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vad = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vbr = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vbr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vbr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->vbr_quality = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->vbr_quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_abr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->abr = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_abr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->abr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_dtx_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->dtx = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_dtx_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->dtx); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_preproc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->preproc = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_preproc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->preproc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_vad = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_agc = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_agc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_agc_level = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_agc_level); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_denoise = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_denoise); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_dereverb = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_dereverb); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_decay = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_decay); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_level = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_level); + result = (int) ((arg1)->unused); jresult = result; return jresult; } @@ -20936,6 +20878,117 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_settings(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_set(void * jarg1, unsigned long jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->actual_samples_per_second = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_get(void * jarg1) { + unsigned long jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (uint32_t) ((arg1)->actual_samples_per_second); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->bits_per_second = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->bits_per_second); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->microseconds_per_packet = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->microseconds_per_packet); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_set(void * jarg1, void * jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->private_info = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_get(void * jarg1) { + void * jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *result = 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (void *) ((arg1)->private_info); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec_fmtp() { + void * jresult ; + switch_codec_fmtp *result = 0 ; + + result = (switch_codec_fmtp *)new switch_codec_fmtp(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_fmtp(void * jarg1) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_interface_set(void * jarg1, void * jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; @@ -21042,29 +21095,6 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_codec_fmtp_out_get(void * jarg1) { } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_settings_set(void * jarg1, void * jarg2) { - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *arg2 = (switch_codec_settings_t *) 0 ; - - arg1 = (switch_codec *)jarg1; - arg2 = (switch_codec_settings_t *)jarg2; - if (arg1) (arg1)->codec_settings = *arg2; - -} - - -SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_codec_settings_get(void * jarg1) { - void * jresult ; - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *result = 0 ; - - arg1 = (switch_codec *)jarg1; - result = (switch_codec_settings_t *)& ((arg1)->codec_settings); - jresult = (void *)result; - return jresult; -} - - SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_flags_set(void * jarg1, unsigned long jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; uint32_t arg2 ; @@ -21767,6 +21797,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_implementations_get( } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_set(void * jarg1, void * jarg2) { + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t arg2 = (switch_core_codec_fmtp_parse_func_t) 0 ; + + arg1 = (switch_codec_interface *)jarg1; + arg2 = (switch_core_codec_fmtp_parse_func_t)jarg2; + if (arg1) (arg1)->parse_fmtp = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_get(void * jarg1) { + void * jresult ; + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t result; + + arg1 = (switch_codec_interface *)jarg1; + result = (switch_core_codec_fmtp_parse_func_t) ((arg1)->parse_fmtp); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_codec_id_set(void * jarg1, unsigned long jarg2) { switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; uint32_t arg2 ; @@ -23206,36 +23259,54 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_variable_partner(void * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, int jarg4) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; - switch_bool_t arg4 ; + char *arg4 = (char *) 0 ; + switch_bool_t arg5 ; switch_status_t result; arg1 = (switch_channel_t *)jarg1; arg2 = (char *)jarg2; arg3 = (char *)jarg3; - arg4 = (switch_bool_t)jarg4; - result = (switch_status_t)switch_channel_export_variable_var_check(arg1,(char const *)arg2,(char const *)arg3,arg4); + arg4 = (char *)jarg4; + arg5 = (switch_bool_t)jarg5; + result = (switch_status_t)switch_channel_export_variable_var_check(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5); jresult = result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_printf(void * jarg1, char * jarg2, char * jarg3) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_process_export(void * jarg1, void * jarg2, void * jarg3, char * jarg4) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_channel_t *arg2 = (switch_channel_t *) 0 ; + switch_event_t *arg3 = (switch_event_t *) 0 ; + char *arg4 = (char *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (switch_channel_t *)jarg2; + arg3 = (switch_event_t *)jarg3; + arg4 = (char *)jarg4; + switch_channel_process_export(arg1,arg2,arg3,(char const *)arg4); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_printf(void * jarg1, char * jarg2, char * jarg3, char * jarg4) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; - void *arg4 = 0 ; + char *arg4 = (char *) 0 ; + void *arg5 = 0 ; switch_status_t result; arg1 = (switch_channel_t *)jarg1; arg2 = (char *)jarg2; arg3 = (char *)jarg3; - result = (switch_status_t)switch_channel_export_variable_printf(arg1,(char const *)arg2,(char const *)arg3,arg4); + arg4 = (char *)jarg4; + result = (switch_status_t)switch_channel_export_variable_printf(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5); jresult = result; return jresult; } @@ -26802,7 +26873,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_file(void * jarg1, void * ja } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12, unsigned long jarg13) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -26816,6 +26887,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig char *arg10 = (char *) 0 ; uint32_t arg11 ; char *arg12 = (char *) 0 ; + uint32_t arg13 ; switch_status_t result; arg1 = (switch_core_session_t *)jarg1; @@ -26830,7 +26902,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig arg10 = (char *)jarg10; arg11 = (uint32_t)jarg11; arg12 = (char *)jarg12; - result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12); + arg13 = (uint32_t)jarg13; + result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12,arg13); jresult = result; return jresult; } @@ -27202,6 +27275,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_broadcast(char * jarg1, char * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_broadcast_in_thread(void * jarg1, char * jarg2, int jarg3) { + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (int)jarg3; + switch_ivr_broadcast_in_thread(arg1,(char const *)arg2,arg3); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_transfer_variable(void * jarg1, void * jarg2, char * jarg3) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -27604,7 +27689,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_wait_for_answer(void * jarg1, void } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9, unsigned long jarg10) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -27615,6 +27700,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja switch_size_t arg7 ; uint32_t arg8 ; char *arg9 = (char *) 0 ; + uint32_t arg10 ; switch_status_t result; switch_size_t *argp7 ; @@ -27632,7 +27718,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja arg7 = *argp7; arg8 = (uint32_t)jarg8; arg9 = (char *)jarg9; - result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9); + arg10 = (uint32_t)jarg10; + result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9,arg10); jresult = result; return jresult; } @@ -27860,6 +27947,176 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_uuid_exists(char * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_create(void * jarg1, char * jarg2, void * jarg3, unsigned long jarg4, unsigned long jarg5, void * jarg6, void * jarg7, void * jarg8) { + int jresult ; + switch_ivr_dmachine_t **arg1 = (switch_ivr_dmachine_t **) 0 ; + char *arg2 = (char *) 0 ; + switch_memory_pool_t *arg3 = (switch_memory_pool_t *) 0 ; + uint32_t arg4 ; + uint32_t arg5 ; + switch_ivr_dmachine_callback_t arg6 = (switch_ivr_dmachine_callback_t) 0 ; + switch_ivr_dmachine_callback_t arg7 = (switch_ivr_dmachine_callback_t) 0 ; + void *arg8 = (void *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t **)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_memory_pool_t *)jarg3; + arg4 = (uint32_t)jarg4; + arg5 = (uint32_t)jarg5; + arg6 = (switch_ivr_dmachine_callback_t)jarg6; + arg7 = (switch_ivr_dmachine_callback_t)jarg7; + arg8 = (void *)jarg8; + result = (switch_status_t)switch_ivr_dmachine_create(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7,arg8); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_destroy(void * jarg1) { + switch_ivr_dmachine_t **arg1 = (switch_ivr_dmachine_t **) 0 ; + + arg1 = (switch_ivr_dmachine_t **)jarg1; + switch_ivr_dmachine_destroy(arg1); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_bind(void * jarg1, char * jarg2, char * jarg3, int jarg4, void * jarg5, void * jarg6) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + int32_t arg4 ; + switch_ivr_dmachine_callback_t arg5 = (switch_ivr_dmachine_callback_t) 0 ; + void *arg6 = (void *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (int32_t)jarg4; + arg5 = (switch_ivr_dmachine_callback_t)jarg5; + arg6 = (void *)jarg6; + result = (switch_status_t)switch_ivr_dmachine_bind(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_feed(void * jarg1, char * jarg2, void * jarg3) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_ivr_dmachine_match_t **arg3 = (switch_ivr_dmachine_match_t **) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_ivr_dmachine_match_t **)jarg3; + result = (switch_status_t)switch_ivr_dmachine_feed(arg1,(char const *)arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_clear(void * jarg1) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + result = (switch_status_t)switch_ivr_dmachine_clear(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_ping(void * jarg1, void * jarg2) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + switch_ivr_dmachine_match_t **arg2 = (switch_ivr_dmachine_match_t **) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (switch_ivr_dmachine_match_t **)jarg2; + result = (switch_status_t)switch_ivr_dmachine_ping(arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_ivr_dmachine_get_match(void * jarg1) { + void * jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + switch_ivr_dmachine_match_t *result = 0 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + result = (switch_ivr_dmachine_match_t *)switch_ivr_dmachine_get_match(arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_ivr_dmachine_get_failed_digits(void * jarg1) { + char * jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + result = (char *)switch_ivr_dmachine_get_failed_digits(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_set_digit_timeout_ms(void * jarg1, unsigned long jarg2) { + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (uint32_t)jarg2; + switch_ivr_dmachine_set_digit_timeout_ms(arg1,arg2); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_ivr_dmachine_set_input_timeout_ms(void * jarg1, unsigned long jarg2) { + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (uint32_t)jarg2; + switch_ivr_dmachine_set_input_timeout_ms(arg1,arg2); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_clear_realm(void * jarg1, char * jarg2) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_dmachine_clear_realm(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_dmachine_set_realm(void * jarg1, char * jarg2) { + int jresult ; + switch_ivr_dmachine_t *arg1 = (switch_ivr_dmachine_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_ivr_dmachine_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_ivr_dmachine_set_realm(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RTP_MAX_BUF_LEN_get() { int jresult ; int result; @@ -28850,6 +29107,18 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_stats(void * jarg1, void * j } +SWIGEXPORT unsigned char SWIGSTDCALL CSharp_switch_rtp_check_auto_adj(void * jarg1) { + unsigned char jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_byte_t result; + + arg1 = (switch_rtp_t *)jarg1; + result = (switch_byte_t)switch_rtp_check_auto_adj(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_log_node_t_data_set(void * jarg1, char * jarg2) { switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; char *arg2 = (char *) 0 ; @@ -33600,7 +33869,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Transfer(void * jarg1, char * jarg } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6, int jarg7) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -33608,6 +33877,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -33616,13 +33886,14 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i arg4 = (char *)jarg4; arg5 = (int)jarg5; arg6 = (char *)jarg6; - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + arg7 = (int)jarg7; + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, int jarg11) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -33634,6 +33905,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -33646,7 +33918,8 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, arg8 = (char *)jarg8; arg9 = (char *)jarg9; arg10 = (char *)jarg10; - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + arg11 = (int)jarg11; + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } diff --git a/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj b/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj index 7875d8e6a8..9b8f827202 100644 --- a/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj +++ b/src/mod/languages/mod_managed/managed/FreeSWITCH.Managed.csproj @@ -19,7 +19,7 @@ true full false - ..\..\..\..\..\managed\debug\ + ..\..\..\..\..\Debug\mod\ DEBUG;TRACE prompt 4 @@ -27,11 +27,27 @@ pdbonly true - ..\..\..\..\..\managed\release\ + ..\..\..\..\..\Release\mod\ TRACE prompt 4 + + true + ..\..\..\..\..\x64\Debug\mod\ + DEBUG;TRACE + full + x64 + prompt + + + ..\..\..\..\..\x64\Release\mod\ + TRACE + true + pdbonly + x64 + prompt + diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 8bf2c6c38d..682b3bd0c5 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -327,13 +327,13 @@ public class CoreSession : IDisposable { return ret; } - public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators) { - string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators); + public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout); return ret; } - public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name) { - string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name); + public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout); return ret; } @@ -440,6 +440,22 @@ public class CoreSession : IDisposable { namespace FreeSWITCH.Native { +public enum dm_match_type_t { + DM_MATCH_POSITIVE, + DM_MATCH_NEGATIVE +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + using System; using System.Runtime.InteropServices; @@ -509,6 +525,21 @@ public class DTMF : IDisposable { namespace FreeSWITCH.Native { +public enum dtmf_flag_t { + DTMF_FLAG_SKIP_PROCESS = (1 << 0) +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + using System; using System.Runtime.InteropServices; @@ -1301,6 +1332,16 @@ public class freeswitch { freeswitchPINVOKE.switch_core_session_soft_unlock(SWIGTYPE_p_switch_core_session.getCPtr(session)); } + public static void switch_core_session_set_dmachine(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_switch_ivr_dmachine dmachine) { + freeswitchPINVOKE.switch_core_session_set_dmachine(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + } + + public static SWIGTYPE_p_switch_ivr_dmachine switch_core_session_get_dmachine(SWIGTYPE_p_switch_core_session session) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_dmachine(SWIGTYPE_p_switch_core_session.getCPtr(session)); + SWIGTYPE_p_switch_ivr_dmachine ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_ivr_dmachine(cPtr, false); + return ret; + } + public static string switch_core_get_uuid() { string ret = freeswitchPINVOKE.switch_core_get_uuid(); return ret; @@ -1673,8 +1714,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_core_codec_init(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); + public static switch_status_t switch_core_codec_init_with_bitrate(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint bitrate, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init_with_bitrate(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, bitrate, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); return ret; } @@ -1683,6 +1724,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_codec_parse_fmtp(string codec_name, string fmtp, uint rate, switch_codec_fmtp codec_fmtp) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_parse_fmtp(codec_name, fmtp, rate, switch_codec_fmtp.getCPtr(codec_fmtp)); + return ret; + } + public static switch_status_t switch_core_codec_reset(switch_codec codec) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_reset(switch_codec.getCPtr(codec)); return ret; @@ -2309,6 +2355,11 @@ public class freeswitch { return ret; } + public static uint switch_default_ptime(string name, uint number) { + uint ret = freeswitchPINVOKE.switch_default_ptime(name, number); + return ret; + } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); return ret; @@ -2645,6 +2696,11 @@ public class freeswitch { return ret; } + public static uint switch_known_bitrate(byte payload) { + uint ret = freeswitchPINVOKE.switch_known_bitrate(payload); + return ret; + } + public static SWIGTYPE_p_switch_size_t switch_fd_read_line(int fd, string buf, SWIGTYPE_p_switch_size_t len) { SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_fd_read_line(fd, buf, SWIGTYPE_p_switch_size_t.getCPtr(len)), true); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -2928,11 +2984,44 @@ public class freeswitch { return ret; } + public static string switch_dow_int2str(int val) { + string ret = freeswitchPINVOKE.switch_dow_int2str(val); + return ret; + } + + public static int switch_dow_str2int(string exp) { + int ret = freeswitchPINVOKE.switch_dow_str2int(exp); + return ret; + } + + public static int switch_dow_cmp(string exp, int val) { + int ret = freeswitchPINVOKE.switch_dow_cmp(exp, val); + return ret; + } + public static int switch_number_cmp(string exp, int val) { int ret = freeswitchPINVOKE.switch_number_cmp(exp, val); return ret; } + public static int switch_tod_cmp(string exp, int val) { + int ret = freeswitchPINVOKE.switch_tod_cmp(exp, val); + return ret; + } + + public static int switch_fulldate_cmp(string exp, SWIGTYPE_p_switch_time_t ts) { + int ret = freeswitchPINVOKE.switch_fulldate_cmp(exp, SWIGTYPE_p_switch_time_t.getCPtr(ts)); + return ret; + } + + public static void switch_split_date(string exp, SWIGTYPE_p_int year, SWIGTYPE_p_int month, SWIGTYPE_p_int day) { + freeswitchPINVOKE.switch_split_date(exp, SWIGTYPE_p_int.getCPtr(year), SWIGTYPE_p_int.getCPtr(month), SWIGTYPE_p_int.getCPtr(day)); + } + + public static void switch_split_time(string exp, SWIGTYPE_p_int hour, SWIGTYPE_p_int min, SWIGTYPE_p_int sec) { + freeswitchPINVOKE.switch_split_time(exp, SWIGTYPE_p_int.getCPtr(hour), SWIGTYPE_p_int.getCPtr(min), SWIGTYPE_p_int.getCPtr(sec)); + } + public static int switch_split_user_domain(string arg0, ref string user, ref string domain) { int ret = freeswitchPINVOKE.switch_split_user_domain(arg0, ref user, ref domain); return ret; @@ -3150,13 +3239,17 @@ public class freeswitch { return ret; } - public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string value, switch_bool_t var_check) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, value, (int)var_check); + public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string val, string export_varname, switch_bool_t var_check) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, val, export_varname, (int)var_check); return ret; } - public static switch_status_t switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel channel, string varname, string fmt) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, fmt); + public static void switch_channel_process_export(SWIGTYPE_p_switch_channel channel, SWIGTYPE_p_switch_channel peer_channel, switch_event var_event, string export_varname) { + freeswitchPINVOKE.switch_channel_process_export(SWIGTYPE_p_switch_channel.getCPtr(channel), SWIGTYPE_p_switch_channel.getCPtr(peer_channel), switch_event.getCPtr(var_event), export_varname); + } + + public static switch_status_t switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel channel, string varname, string export_varname, string fmt) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, export_varname, fmt); return ret; } @@ -3986,8 +4079,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex); + public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex, digit_timeout); return ret; } @@ -4092,6 +4185,10 @@ public class freeswitch { return ret; } + public static void switch_ivr_broadcast_in_thread(SWIGTYPE_p_switch_core_session session, string app, int flags) { + freeswitchPINVOKE.switch_ivr_broadcast_in_thread(SWIGTYPE_p_switch_core_session.getCPtr(session), app, flags); + } + public static switch_status_t switch_ivr_transfer_variable(SWIGTYPE_p_switch_core_session sessa, SWIGTYPE_p_switch_core_session sessb, string var) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_transfer_variable(SWIGTYPE_p_switch_core_session.getCPtr(sessa), SWIGTYPE_p_switch_core_session.getCPtr(sessb), var); return ret; @@ -4216,8 +4313,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators); + public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators, digit_timeout); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -4296,6 +4393,64 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_dmachine_create(SWIGTYPE_p_p_switch_ivr_dmachine dmachine_p, string name, SWIGTYPE_p_apr_pool_t pool, uint digit_timeout, uint input_timeout, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t match_callback, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t nonmatch_callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_create(SWIGTYPE_p_p_switch_ivr_dmachine.getCPtr(dmachine_p), name, SWIGTYPE_p_apr_pool_t.getCPtr(pool), digit_timeout, input_timeout, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t.getCPtr(match_callback), SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t.getCPtr(nonmatch_callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static void switch_ivr_dmachine_destroy(SWIGTYPE_p_p_switch_ivr_dmachine dmachine) { + freeswitchPINVOKE.switch_ivr_dmachine_destroy(SWIGTYPE_p_p_switch_ivr_dmachine.getCPtr(dmachine)); + } + + public static switch_status_t switch_ivr_dmachine_bind(SWIGTYPE_p_switch_ivr_dmachine dmachine, string realm, string digits, int key, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_bind(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), realm, digits, key, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t.getCPtr(callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_feed(SWIGTYPE_p_switch_ivr_dmachine dmachine, string digits, SWIGTYPE_p_p_switch_ivr_dmachine_match match) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_feed(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), digits, SWIGTYPE_p_p_switch_ivr_dmachine_match.getCPtr(match)); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_clear(SWIGTYPE_p_switch_ivr_dmachine dmachine) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_clear(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_ping(SWIGTYPE_p_switch_ivr_dmachine dmachine, SWIGTYPE_p_p_switch_ivr_dmachine_match match_p) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_ping(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), SWIGTYPE_p_p_switch_ivr_dmachine_match.getCPtr(match_p)); + return ret; + } + + public static switch_ivr_dmachine_match switch_ivr_dmachine_get_match(SWIGTYPE_p_switch_ivr_dmachine dmachine) { + IntPtr cPtr = freeswitchPINVOKE.switch_ivr_dmachine_get_match(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + switch_ivr_dmachine_match ret = (cPtr == IntPtr.Zero) ? null : new switch_ivr_dmachine_match(cPtr, false); + return ret; + } + + public static string switch_ivr_dmachine_get_failed_digits(SWIGTYPE_p_switch_ivr_dmachine dmachine) { + string ret = freeswitchPINVOKE.switch_ivr_dmachine_get_failed_digits(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + return ret; + } + + public static void switch_ivr_dmachine_set_digit_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine dmachine, uint digit_timeout_ms) { + freeswitchPINVOKE.switch_ivr_dmachine_set_digit_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), digit_timeout_ms); + } + + public static void switch_ivr_dmachine_set_input_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine dmachine, uint input_timeout_ms) { + freeswitchPINVOKE.switch_ivr_dmachine_set_input_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), input_timeout_ms); + } + + public static switch_status_t switch_ivr_dmachine_clear_realm(SWIGTYPE_p_switch_ivr_dmachine dmachine, string realm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_clear_realm(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), realm); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_set_realm(SWIGTYPE_p_switch_ivr_dmachine dmachine, string realm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_set_realm(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), realm); + return ret; + } + public static switch_status_t switch_rtp_add_crypto_key(SWIGTYPE_p_switch_rtp rtp_session, switch_rtp_crypto_direction_t direction, uint index, switch_rtp_crypto_key_type_t type, SWIGTYPE_p_unsigned_char key, SWIGTYPE_p_switch_size_t keylen) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_add_crypto_key(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)direction, index, (int)type, SWIGTYPE_p_unsigned_char.getCPtr(key), SWIGTYPE_p_switch_size_t.getCPtr(keylen)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -4567,6 +4722,11 @@ public class freeswitch { return ret; } + public static byte switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp rtp_session) { + byte ret = freeswitchPINVOKE.switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); + return ret; + } + public static switch_status_t switch_log_init(SWIGTYPE_p_apr_pool_t pool, switch_bool_t colorize) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_log_init(SWIGTYPE_p_apr_pool_t.getCPtr(pool), (int)colorize); return ret; @@ -4762,6 +4922,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_xml_reload(ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_reload(ref err); + return ret; + } + public static switch_status_t switch_xml_destroy() { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_destroy(); return ret; @@ -5126,6 +5291,7 @@ public class freeswitch { public static readonly string SWITCH_CURRENT_APPLICATION_VARIABLE = freeswitchPINVOKE.SWITCH_CURRENT_APPLICATION_VARIABLE_get(); public static readonly string SWITCH_CURRENT_APPLICATION_DATA_VARIABLE = freeswitchPINVOKE.SWITCH_CURRENT_APPLICATION_DATA_VARIABLE_get(); public static readonly string SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE = freeswitchPINVOKE.SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE_get(); + public static readonly string SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE = freeswitchPINVOKE.SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get(); public static readonly string SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE = freeswitchPINVOKE.SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get(); public static readonly string SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE = freeswitchPINVOKE.SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE_get(); public static readonly string SWITCH_READ_RESULT_VARIABLE = freeswitchPINVOKE.SWITCH_READ_RESULT_VARIABLE_get(); @@ -5158,6 +5324,7 @@ public class freeswitch { public static readonly string SWITCH_ENDPOINT_DISPOSITION_VARIABLE = freeswitchPINVOKE.SWITCH_ENDPOINT_DISPOSITION_VARIABLE_get(); public static readonly string SWITCH_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_HOLD_MUSIC_VARIABLE_get(); public static readonly string SWITCH_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_EXPORT_VARS_VARIABLE_get(); + public static readonly string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get(); public static readonly string SWITCH_R_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_R_SDP_VARIABLE_get(); public static readonly string SWITCH_L_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_L_SDP_VARIABLE_get(); public static readonly string SWITCH_B_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_B_SDP_VARIABLE_get(); @@ -5201,6 +5368,7 @@ public class freeswitch { public static readonly int SWITCH_CORE_QUEUE_LEN = freeswitchPINVOKE.SWITCH_CORE_QUEUE_LEN_get(); public static readonly int SWITCH_MAX_MANAGEMENT_BUFFER_LEN = freeswitchPINVOKE.SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get(); public static readonly int SWITCH_RTP_CNG_PAYLOAD = freeswitchPINVOKE.SWITCH_RTP_CNG_PAYLOAD_get(); + public static readonly int DMACHINE_MAX_DIGIT_LEN = freeswitchPINVOKE.DMACHINE_MAX_DIGIT_LEN_get(); public static readonly int SWITCH_API_VERSION = freeswitchPINVOKE.SWITCH_API_VERSION_get(); public static readonly int SWITCH_CORE_DB_OK = freeswitchPINVOKE.SWITCH_CORE_DB_OK_get(); public static readonly int SWITCH_CORE_DB_ERROR = freeswitchPINVOKE.SWITCH_CORE_DB_ERROR_get(); @@ -5651,6 +5819,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE_get")] public static extern string SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get")] + public static extern string SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get")] public static extern string SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get(); @@ -5747,6 +5918,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_EXPORT_VARS_VARIABLE_get")] public static extern string SWITCH_EXPORT_VARS_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get")] + public static extern string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_R_SDP_VARIABLE_get")] public static extern string SWITCH_R_SDP_VARIABLE_get(); @@ -5849,6 +6023,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_duration_get")] public static extern uint switch_dtmf_t_duration_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_flags_set")] + public static extern void switch_dtmf_t_flags_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_flags_get")] + public static extern int switch_dtmf_t_flags_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_dtmf_t")] public static extern IntPtr new_switch_dtmf_t(); @@ -6333,10 +6513,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_remote_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_set")] - public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_get")] - public static extern uint switch_t38_options_t_remote_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_remote_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_ip_set")] public static extern void switch_t38_options_t_local_ip_set(HandleRef jarg1, string jarg2); @@ -6345,10 +6525,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_local_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_set")] - public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_get")] - public static extern uint switch_t38_options_t_local_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_local_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_t38_options_t")] public static extern IntPtr new_switch_t38_options_t(); @@ -6404,6 +6584,45 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_console_callback_match")] public static extern void delete_switch_console_callback_match(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_DMACHINE_MAX_DIGIT_LEN_get")] + public static extern int DMACHINE_MAX_DIGIT_LEN_get(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_dmachine_set")] + public static extern void switch_ivr_dmachine_match_dmachine_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_dmachine_get")] + public static extern IntPtr switch_ivr_dmachine_match_dmachine_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_digits_set")] + public static extern void switch_ivr_dmachine_match_match_digits_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_digits_get")] + public static extern string switch_ivr_dmachine_match_match_digits_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_key_set")] + public static extern void switch_ivr_dmachine_match_match_key_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_key_get")] + public static extern int switch_ivr_dmachine_match_match_key_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_type_set")] + public static extern void switch_ivr_dmachine_match_type_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_type_get")] + public static extern int switch_ivr_dmachine_match_type_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_user_data_set")] + public static extern void switch_ivr_dmachine_match_user_data_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_user_data_get")] + public static extern IntPtr switch_ivr_dmachine_match_user_data_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_ivr_dmachine_match")] + public static extern IntPtr new_switch_ivr_dmachine_match(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_ivr_dmachine_match")] + public static extern void delete_switch_ivr_dmachine_match(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_input_callback_set")] public static extern void switch_input_args_t_input_callback_set(HandleRef jarg1, HandleRef jarg2); @@ -6434,6 +6653,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_user_data_get")] public static extern IntPtr switch_input_args_t_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_dmachine_set")] + public static extern void switch_input_args_t_dmachine_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_dmachine_get")] + public static extern IntPtr switch_input_args_t_dmachine_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_input_args_t")] public static extern IntPtr new_switch_input_args_t(); @@ -7136,6 +7361,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_soft_unlock")] public static extern void switch_core_session_soft_unlock(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_dmachine")] + public static extern void switch_core_session_set_dmachine(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_dmachine")] + public static extern IntPtr switch_core_session_get_dmachine(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_uuid")] public static extern string switch_core_get_uuid(); @@ -7361,12 +7592,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_timer_destroy")] public static extern int switch_core_timer_destroy(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init")] - public static extern int switch_core_codec_init(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, HandleRef jarg8, HandleRef jarg9); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init_with_bitrate")] + public static extern int switch_core_codec_init_with_bitrate(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, uint jarg8, HandleRef jarg9, HandleRef jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_copy")] public static extern int switch_core_codec_copy(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_parse_fmtp")] + public static extern int switch_core_codec_parse_fmtp(string jarg1, string jarg2, uint jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_reset")] public static extern int switch_core_codec_reset(HandleRef jarg1); @@ -7901,6 +8135,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_in_thread")] public static extern int switch_core_session_in_thread(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_default_ptime")] + public static extern uint switch_default_ptime(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); @@ -8219,6 +8456,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_is_digit_string")] public static extern int switch_is_digit_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_known_bitrate")] + public static extern uint switch_known_bitrate(byte jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_fd_read_line")] public static extern IntPtr switch_fd_read_line(int jarg1, string jarg2, HandleRef jarg3); @@ -8384,9 +8624,30 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_network_list_validate_ip_token")] public static extern int switch_network_list_validate_ip_token(HandleRef jarg1, uint jarg2, ref string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_int2str")] + public static extern string switch_dow_int2str(int jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_str2int")] + public static extern int switch_dow_str2int(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_cmp")] + public static extern int switch_dow_cmp(string jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_number_cmp")] public static extern int switch_number_cmp(string jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_tod_cmp")] + public static extern int switch_tod_cmp(string jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_fulldate_cmp")] + public static extern int switch_fulldate_cmp(string jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_date")] + public static extern void switch_split_date(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_time")] + public static extern void switch_split_time(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_user_domain")] public static extern int switch_split_user_domain(string jarg1, ref string jarg2, ref string jarg3); @@ -10319,101 +10580,11 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_directory_handle")] public static extern void delete_switch_directory_handle(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_set")] - public static extern void switch_codec_settings_quality_set(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_set")] + public static extern void switch_codec_settings_unused_set(HandleRef jarg1, int jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_get")] - public static extern int switch_codec_settings_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_set")] - public static extern void switch_codec_settings_complexity_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_get")] - public static extern int switch_codec_settings_complexity_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_set")] - public static extern void switch_codec_settings_enhancement_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_get")] - public static extern int switch_codec_settings_enhancement_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_set")] - public static extern void switch_codec_settings_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_get")] - public static extern int switch_codec_settings_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_set")] - public static extern void switch_codec_settings_vbr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_get")] - public static extern int switch_codec_settings_vbr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_set")] - public static extern void switch_codec_settings_vbr_quality_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_get")] - public static extern float switch_codec_settings_vbr_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_set")] - public static extern void switch_codec_settings_abr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_get")] - public static extern int switch_codec_settings_abr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_set")] - public static extern void switch_codec_settings_dtx_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_get")] - public static extern int switch_codec_settings_dtx_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_set")] - public static extern void switch_codec_settings_preproc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_get")] - public static extern int switch_codec_settings_preproc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_set")] - public static extern void switch_codec_settings_pp_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_get")] - public static extern int switch_codec_settings_pp_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_set")] - public static extern void switch_codec_settings_pp_agc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_get")] - public static extern int switch_codec_settings_pp_agc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_set")] - public static extern void switch_codec_settings_pp_agc_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_get")] - public static extern float switch_codec_settings_pp_agc_level_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_set")] - public static extern void switch_codec_settings_pp_denoise_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_get")] - public static extern int switch_codec_settings_pp_denoise_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_set")] - public static extern void switch_codec_settings_pp_dereverb_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_get")] - public static extern int switch_codec_settings_pp_dereverb_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_set")] - public static extern void switch_codec_settings_pp_dereverb_decay_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_get")] - public static extern float switch_codec_settings_pp_dereverb_decay_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_set")] - public static extern void switch_codec_settings_pp_dereverb_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_get")] - public static extern float switch_codec_settings_pp_dereverb_level_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_get")] + public static extern int switch_codec_settings_unused_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_settings")] public static extern IntPtr new_switch_codec_settings(); @@ -10421,6 +10592,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_settings")] public static extern void delete_switch_codec_settings(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_set")] + public static extern void switch_codec_fmtp_actual_samples_per_second_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_get")] + public static extern uint switch_codec_fmtp_actual_samples_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_set")] + public static extern void switch_codec_fmtp_bits_per_second_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_get")] + public static extern int switch_codec_fmtp_bits_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_set")] + public static extern void switch_codec_fmtp_microseconds_per_packet_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_get")] + public static extern int switch_codec_fmtp_microseconds_per_packet_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_set")] + public static extern void switch_codec_fmtp_private_info_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_get")] + public static extern IntPtr switch_codec_fmtp_private_info_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_fmtp")] + public static extern IntPtr new_switch_codec_fmtp(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_fmtp")] + public static extern void delete_switch_codec_fmtp(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_interface_set")] public static extern void switch_codec_codec_interface_set(HandleRef jarg1, HandleRef jarg2); @@ -10445,12 +10646,6 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_out_get")] public static extern string switch_codec_fmtp_out_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_set")] - public static extern void switch_codec_codec_settings_set(HandleRef jarg1, HandleRef jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_get")] - public static extern IntPtr switch_codec_codec_settings_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_flags_set")] public static extern void switch_codec_flags_set(HandleRef jarg1, uint jarg2); @@ -10631,6 +10826,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_implementations_get")] public static extern IntPtr switch_codec_interface_implementations_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_set")] + public static extern void switch_codec_interface_parse_fmtp_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_get")] + public static extern IntPtr switch_codec_interface_parse_fmtp_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_codec_id_set")] public static extern void switch_codec_interface_codec_id_set(HandleRef jarg1, uint jarg2); @@ -10968,10 +11169,13 @@ class freeswitchPINVOKE { public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")] - public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, int jarg4); + public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_process_export")] + public static extern void switch_channel_process_export(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_printf")] - public static extern int switch_channel_export_variable_printf(HandleRef jarg1, string jarg2, string jarg3); + public static extern int switch_channel_export_variable_printf(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_dup")] public static extern string switch_channel_get_variable_dup(HandleRef jarg1, string jarg2, int jarg3); @@ -11748,7 +11952,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_record_file(HandleRef jarg1, HandleRef jarg2, string jarg3, HandleRef jarg4, uint jarg5); [DllImport("mod_managed", EntryPoint="CSharp_switch_play_and_get_digits")] - public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12); + public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12, uint jarg13); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_speak_text_handle")] public static extern int switch_ivr_speak_text_handle(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, string jarg5, HandleRef jarg6); @@ -11810,6 +12014,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_broadcast")] public static extern int switch_ivr_broadcast(string jarg1, string jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_broadcast_in_thread")] + public static extern void switch_ivr_broadcast_in_thread(HandleRef jarg1, string jarg2, int jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_transfer_variable")] public static extern int switch_ivr_transfer_variable(HandleRef jarg1, HandleRef jarg2, string jarg3); @@ -11886,7 +12093,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_wait_for_answer(HandleRef jarg1, HandleRef jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_read")] - public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9); + public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9, uint jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_block_dtmf_session")] public static extern int switch_ivr_block_dtmf_session(HandleRef jarg1); @@ -11933,6 +12140,42 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_uuid_exists")] public static extern int switch_ivr_uuid_exists(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_create")] + public static extern int switch_ivr_dmachine_create(HandleRef jarg1, string jarg2, HandleRef jarg3, uint jarg4, uint jarg5, HandleRef jarg6, HandleRef jarg7, HandleRef jarg8); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_destroy")] + public static extern void switch_ivr_dmachine_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_bind")] + public static extern int switch_ivr_dmachine_bind(HandleRef jarg1, string jarg2, string jarg3, int jarg4, HandleRef jarg5, HandleRef jarg6); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_feed")] + public static extern int switch_ivr_dmachine_feed(HandleRef jarg1, string jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_clear")] + public static extern int switch_ivr_dmachine_clear(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_ping")] + public static extern int switch_ivr_dmachine_ping(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_get_match")] + public static extern IntPtr switch_ivr_dmachine_get_match(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_get_failed_digits")] + public static extern string switch_ivr_dmachine_get_failed_digits(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_set_digit_timeout_ms")] + public static extern void switch_ivr_dmachine_set_digit_timeout_ms(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_set_input_timeout_ms")] + public static extern void switch_ivr_dmachine_set_input_timeout_ms(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_clear_realm")] + public static extern int switch_ivr_dmachine_clear_realm(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_set_realm")] + public static extern int switch_ivr_dmachine_set_realm(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RTP_MAX_BUF_LEN_get")] public static extern int SWITCH_RTP_MAX_BUF_LEN_get(); @@ -12158,6 +12401,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_stats")] public static extern IntPtr switch_rtp_get_stats(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_check_auto_adj")] + public static extern byte switch_rtp_check_auto_adj(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_data_set")] public static extern void switch_log_node_t_data_set(HandleRef jarg1, string jarg2); @@ -12404,6 +12650,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_init")] public static extern int switch_xml_init(HandleRef jarg1, ref string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_reload")] + public static extern int switch_xml_reload(ref string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_destroy")] public static extern int switch_xml_destroy(); @@ -13290,10 +13539,10 @@ class freeswitchPINVOKE { public static extern int CoreSession_Transfer(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_read")] - public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6); + public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_PlayAndGetDigits")] - public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10); + public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, int jarg11); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_StreamFile")] public static extern int CoreSession_StreamFile(HandleRef jarg1, string jarg2, int jarg3); @@ -14011,6 +14260,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_q_const__char_p_switch_core_session_p_switch_stream_handle__switch_status_t { private HandleRef swigCPtr; @@ -15391,6 +15670,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_ivr_menu_p_char_p_char_size_t_p_void__switch_ivr_action_t { private HandleRef swigCPtr; @@ -16771,6 +17080,66 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_ivr_dmachine { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_ivr_dmachine(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_ivr_dmachine() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_ivr_dmachine obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + +public class SWIGTYPE_p_p_switch_ivr_dmachine_match { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_ivr_dmachine_match(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_ivr_dmachine_match() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_ivr_dmachine_match obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_ivr_menu { private HandleRef swigCPtr; @@ -17611,6 +17980,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_ivr_dmachine { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_ivr_dmachine(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_ivr_dmachine() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_ivr_dmachine obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_ivr_menu { private HandleRef swigCPtr; @@ -20852,6 +21251,8 @@ public enum switch_channel_flag_t { CF_EARLY_HANGUP, CF_MEDIA_SET, CF_CONSUME_ON_ORIGINATE, + CF_PASSTHRU_PTIME_MISMATCH, + CF_BRIDGE_NOWRITE, CF_FLAG_MAX } @@ -21249,17 +21650,6 @@ public class switch_codec : IDisposable { } } - public switch_codec_settings codec_settings { - set { - freeswitchPINVOKE.switch_codec_codec_settings_set(swigCPtr, switch_codec_settings.getCPtr(value)); - } - get { - IntPtr cPtr = freeswitchPINVOKE.switch_codec_codec_settings_get(swigCPtr); - switch_codec_settings ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_settings(cPtr, false); - return ret; - } - } - public uint flags { set { freeswitchPINVOKE.switch_codec_flags_set(swigCPtr, value); @@ -21366,6 +21756,96 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class switch_codec_fmtp : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_codec_fmtp(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_codec_fmtp obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_codec_fmtp() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_codec_fmtp(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public uint actual_samples_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_get(swigCPtr); + return ret; + } + } + + public int bits_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_get(swigCPtr); + return ret; + } + } + + public int microseconds_per_packet { + set { + freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_void private_info { + set { + freeswitchPINVOKE.switch_codec_fmtp_private_info_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_fmtp_private_info_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public switch_codec_fmtp() : this(freeswitchPINVOKE.new_switch_codec_fmtp(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class switch_codec_implementation : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; @@ -21671,6 +22151,17 @@ public class switch_codec_interface : IDisposable { } } + public SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t parse_fmtp { + set { + freeswitchPINVOKE.switch_codec_interface_parse_fmtp_set(swigCPtr, SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_interface_parse_fmtp_get(swigCPtr); + SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(cPtr, false); + return ret; + } + } + public uint codec_id { set { freeswitchPINVOKE.switch_codec_interface_codec_id_set(swigCPtr, value); @@ -21784,162 +22275,12 @@ public class switch_codec_settings : IDisposable { } } - public int quality { + public int unused { set { - freeswitchPINVOKE.switch_codec_settings_quality_set(swigCPtr, value); + freeswitchPINVOKE.switch_codec_settings_unused_set(swigCPtr, value); } get { - int ret = freeswitchPINVOKE.switch_codec_settings_quality_get(swigCPtr); - return ret; - } - } - - public int complexity { - set { - freeswitchPINVOKE.switch_codec_settings_complexity_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_complexity_get(swigCPtr); - return ret; - } - } - - public int enhancement { - set { - freeswitchPINVOKE.switch_codec_settings_enhancement_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_enhancement_get(swigCPtr); - return ret; - } - } - - public int vad { - set { - freeswitchPINVOKE.switch_codec_settings_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vad_get(swigCPtr); - return ret; - } - } - - public int vbr { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vbr_get(swigCPtr); - return ret; - } - } - - public float vbr_quality { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_quality_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_vbr_quality_get(swigCPtr); - return ret; - } - } - - public int abr { - set { - freeswitchPINVOKE.switch_codec_settings_abr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_abr_get(swigCPtr); - return ret; - } - } - - public int dtx { - set { - freeswitchPINVOKE.switch_codec_settings_dtx_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_dtx_get(swigCPtr); - return ret; - } - } - - public int preproc { - set { - freeswitchPINVOKE.switch_codec_settings_preproc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_preproc_get(swigCPtr); - return ret; - } - } - - public int pp_vad { - set { - freeswitchPINVOKE.switch_codec_settings_pp_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_vad_get(swigCPtr); - return ret; - } - } - - public int pp_agc { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_get(swigCPtr); - return ret; - } - } - - public float pp_agc_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_level_get(swigCPtr); - return ret; - } - } - - public int pp_denoise { - set { - freeswitchPINVOKE.switch_codec_settings_pp_denoise_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_denoise_get(swigCPtr); - return ret; - } - } - - public int pp_dereverb { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_decay { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_get(swigCPtr); + int ret = freeswitchPINVOKE.switch_codec_settings_unused_get(swigCPtr); return ret; } } @@ -23484,6 +23825,16 @@ public class switch_dtmf_t : IDisposable { } } + public int flags { + set { + freeswitchPINVOKE.switch_dtmf_t_flags_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_dtmf_t_flags_get(swigCPtr); + return ret; + } + } + public switch_dtmf_t() : this(freeswitchPINVOKE.new_switch_dtmf_t(), true) { } @@ -25063,6 +25414,17 @@ public class switch_input_args_t : IDisposable { } } + public SWIGTYPE_p_switch_ivr_dmachine dmachine { + set { + freeswitchPINVOKE.switch_input_args_t_dmachine_set(swigCPtr, SWIGTYPE_p_switch_ivr_dmachine.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_input_args_t_dmachine_get(swigCPtr); + SWIGTYPE_p_switch_ivr_dmachine ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_ivr_dmachine(cPtr, false); + return ret; + } + } + public switch_input_args_t() : this(freeswitchPINVOKE.new_switch_input_args_t(), true) { } @@ -26372,6 +26734,107 @@ public enum switch_ivr_action_t { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_ivr_dmachine_match : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_ivr_dmachine_match(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_ivr_dmachine_match obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_ivr_dmachine_match() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_ivr_dmachine_match(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_ivr_dmachine dmachine { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_dmachine_set(swigCPtr, SWIGTYPE_p_switch_ivr_dmachine.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_ivr_dmachine_match_dmachine_get(swigCPtr); + SWIGTYPE_p_switch_ivr_dmachine ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_ivr_dmachine(cPtr, false); + return ret; + } + } + + public string match_digits { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_match_digits_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_ivr_dmachine_match_match_digits_get(swigCPtr); + return ret; + } + } + + public int match_key { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_match_key_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_ivr_dmachine_match_match_key_get(swigCPtr); + return ret; + } + } + + public dm_match_type_t type { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_type_set(swigCPtr, (int)value); + } + get { + dm_match_type_t ret = (dm_match_type_t)freeswitchPINVOKE.switch_ivr_dmachine_match_type_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_void user_data { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_user_data_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_ivr_dmachine_match_user_data_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public switch_ivr_dmachine_match() : this(freeswitchPINVOKE.new_switch_ivr_dmachine_match(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_ivr_menu_flags { SWITCH_IVR_MENU_FLAG_FALLTOMAIN = (1 << 0), SWITCH_IVR_MENU_FLAG_FREEPOOL = (1 << 1), @@ -29362,6 +29825,7 @@ public enum switch_status_t { SWITCH_STATUS_NOUNLOAD, SWITCH_STATUS_IGNORE, SWITCH_STATUS_TOO_SMALL, + SWITCH_STATUS_FOUND, SWITCH_STATUS_NOT_INITALIZED } @@ -29671,12 +30135,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint remote_port { + public ushort remote_port { set { freeswitchPINVOKE.switch_t38_options_t_remote_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); return ret; } } @@ -29691,12 +30155,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint local_port { + public ushort local_port { set { freeswitchPINVOKE.switch_t38_options_t_local_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); return ret; } } diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 5f412f4144..2beb015ffc 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -323,13 +323,13 @@ public class CoreSession : IDisposable { return ret; } - public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators) { - string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators); + public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout); return ret; } - public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name) { - string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name); + public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout); return ret; } @@ -436,6 +436,22 @@ public class CoreSession : IDisposable { namespace FreeSWITCH.Native { +public enum dm_match_type_t { + DM_MATCH_POSITIVE, + DM_MATCH_NEGATIVE +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + using System; using System.Runtime.InteropServices; @@ -503,6 +519,21 @@ public class DTMF : IDisposable { namespace FreeSWITCH.Native { +public enum dtmf_flag_t { + DTMF_FLAG_SKIP_PROCESS = (1 << 0) +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + using System; using System.Runtime.InteropServices; @@ -1291,6 +1322,16 @@ public class freeswitch { freeswitchPINVOKE.switch_core_session_soft_unlock(SWIGTYPE_p_switch_core_session.getCPtr(session)); } + public static void switch_core_session_set_dmachine(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_switch_ivr_dmachine dmachine) { + freeswitchPINVOKE.switch_core_session_set_dmachine(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + } + + public static SWIGTYPE_p_switch_ivr_dmachine switch_core_session_get_dmachine(SWIGTYPE_p_switch_core_session session) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_dmachine(SWIGTYPE_p_switch_core_session.getCPtr(session)); + SWIGTYPE_p_switch_ivr_dmachine ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_ivr_dmachine(cPtr, false); + return ret; + } + public static string switch_core_get_uuid() { string ret = freeswitchPINVOKE.switch_core_get_uuid(); return ret; @@ -1663,8 +1704,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_core_codec_init(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); + public static switch_status_t switch_core_codec_init_with_bitrate(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint bitrate, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init_with_bitrate(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, bitrate, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); return ret; } @@ -1673,6 +1714,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_codec_parse_fmtp(string codec_name, string fmtp, uint rate, switch_codec_fmtp codec_fmtp) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_parse_fmtp(codec_name, fmtp, rate, switch_codec_fmtp.getCPtr(codec_fmtp)); + return ret; + } + public static switch_status_t switch_core_codec_reset(switch_codec codec) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_reset(switch_codec.getCPtr(codec)); return ret; @@ -2299,6 +2345,11 @@ public class freeswitch { return ret; } + public static uint switch_default_ptime(string name, uint number) { + uint ret = freeswitchPINVOKE.switch_default_ptime(name, number); + return ret; + } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); return ret; @@ -2635,6 +2686,11 @@ public class freeswitch { return ret; } + public static uint switch_known_bitrate(byte payload) { + uint ret = freeswitchPINVOKE.switch_known_bitrate(payload); + return ret; + } + public static SWIGTYPE_p_switch_size_t switch_fd_read_line(int fd, string buf, SWIGTYPE_p_switch_size_t len) { SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_fd_read_line(fd, buf, SWIGTYPE_p_switch_size_t.getCPtr(len)), true); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -3173,13 +3229,17 @@ public class freeswitch { return ret; } - public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string value, switch_bool_t var_check) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, value, (int)var_check); + public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string val, string export_varname, switch_bool_t var_check) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, val, export_varname, (int)var_check); return ret; } - public static switch_status_t switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel channel, string varname, string fmt) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, fmt); + public static void switch_channel_process_export(SWIGTYPE_p_switch_channel channel, SWIGTYPE_p_switch_channel peer_channel, switch_event var_event, string export_varname) { + freeswitchPINVOKE.switch_channel_process_export(SWIGTYPE_p_switch_channel.getCPtr(channel), SWIGTYPE_p_switch_channel.getCPtr(peer_channel), switch_event.getCPtr(var_event), export_varname); + } + + public static switch_status_t switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel channel, string varname, string export_varname, string fmt) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_printf(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, export_varname, fmt); return ret; } @@ -4009,8 +4069,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex); + public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex, digit_timeout); return ret; } @@ -4115,6 +4175,10 @@ public class freeswitch { return ret; } + public static void switch_ivr_broadcast_in_thread(SWIGTYPE_p_switch_core_session session, string app, int flags) { + freeswitchPINVOKE.switch_ivr_broadcast_in_thread(SWIGTYPE_p_switch_core_session.getCPtr(session), app, flags); + } + public static switch_status_t switch_ivr_transfer_variable(SWIGTYPE_p_switch_core_session sessa, SWIGTYPE_p_switch_core_session sessb, string var) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_transfer_variable(SWIGTYPE_p_switch_core_session.getCPtr(sessa), SWIGTYPE_p_switch_core_session.getCPtr(sessb), var); return ret; @@ -4239,8 +4303,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators); + public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators, digit_timeout); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -4319,6 +4383,64 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_dmachine_create(SWIGTYPE_p_p_switch_ivr_dmachine dmachine_p, string name, SWIGTYPE_p_apr_pool_t pool, uint digit_timeout, uint input_timeout, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t match_callback, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t nonmatch_callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_create(SWIGTYPE_p_p_switch_ivr_dmachine.getCPtr(dmachine_p), name, SWIGTYPE_p_apr_pool_t.getCPtr(pool), digit_timeout, input_timeout, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t.getCPtr(match_callback), SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t.getCPtr(nonmatch_callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static void switch_ivr_dmachine_destroy(SWIGTYPE_p_p_switch_ivr_dmachine dmachine) { + freeswitchPINVOKE.switch_ivr_dmachine_destroy(SWIGTYPE_p_p_switch_ivr_dmachine.getCPtr(dmachine)); + } + + public static switch_status_t switch_ivr_dmachine_bind(SWIGTYPE_p_switch_ivr_dmachine dmachine, string realm, string digits, int key, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_bind(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), realm, digits, key, SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t.getCPtr(callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_feed(SWIGTYPE_p_switch_ivr_dmachine dmachine, string digits, SWIGTYPE_p_p_switch_ivr_dmachine_match match) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_feed(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), digits, SWIGTYPE_p_p_switch_ivr_dmachine_match.getCPtr(match)); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_clear(SWIGTYPE_p_switch_ivr_dmachine dmachine) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_clear(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_ping(SWIGTYPE_p_switch_ivr_dmachine dmachine, SWIGTYPE_p_p_switch_ivr_dmachine_match match_p) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_ping(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), SWIGTYPE_p_p_switch_ivr_dmachine_match.getCPtr(match_p)); + return ret; + } + + public static switch_ivr_dmachine_match switch_ivr_dmachine_get_match(SWIGTYPE_p_switch_ivr_dmachine dmachine) { + IntPtr cPtr = freeswitchPINVOKE.switch_ivr_dmachine_get_match(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + switch_ivr_dmachine_match ret = (cPtr == IntPtr.Zero) ? null : new switch_ivr_dmachine_match(cPtr, false); + return ret; + } + + public static string switch_ivr_dmachine_get_failed_digits(SWIGTYPE_p_switch_ivr_dmachine dmachine) { + string ret = freeswitchPINVOKE.switch_ivr_dmachine_get_failed_digits(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine)); + return ret; + } + + public static void switch_ivr_dmachine_set_digit_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine dmachine, uint digit_timeout_ms) { + freeswitchPINVOKE.switch_ivr_dmachine_set_digit_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), digit_timeout_ms); + } + + public static void switch_ivr_dmachine_set_input_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine dmachine, uint input_timeout_ms) { + freeswitchPINVOKE.switch_ivr_dmachine_set_input_timeout_ms(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), input_timeout_ms); + } + + public static switch_status_t switch_ivr_dmachine_clear_realm(SWIGTYPE_p_switch_ivr_dmachine dmachine, string realm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_clear_realm(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), realm); + return ret; + } + + public static switch_status_t switch_ivr_dmachine_set_realm(SWIGTYPE_p_switch_ivr_dmachine dmachine, string realm) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_dmachine_set_realm(SWIGTYPE_p_switch_ivr_dmachine.getCPtr(dmachine), realm); + return ret; + } + public static switch_status_t switch_rtp_add_crypto_key(SWIGTYPE_p_switch_rtp rtp_session, switch_rtp_crypto_direction_t direction, uint index, switch_rtp_crypto_key_type_t type, SWIGTYPE_p_unsigned_char key, SWIGTYPE_p_switch_size_t keylen) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_add_crypto_key(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)direction, index, (int)type, SWIGTYPE_p_unsigned_char.getCPtr(key), SWIGTYPE_p_switch_size_t.getCPtr(keylen)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -4590,6 +4712,11 @@ public class freeswitch { return ret; } + public static byte switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp rtp_session) { + byte ret = freeswitchPINVOKE.switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); + return ret; + } + public static switch_status_t switch_log_init(SWIGTYPE_p_apr_pool_t pool, switch_bool_t colorize) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_log_init(SWIGTYPE_p_apr_pool_t.getCPtr(pool), (int)colorize); return ret; @@ -5154,6 +5281,7 @@ public class freeswitch { public static readonly string SWITCH_CURRENT_APPLICATION_VARIABLE = freeswitchPINVOKE.SWITCH_CURRENT_APPLICATION_VARIABLE_get(); public static readonly string SWITCH_CURRENT_APPLICATION_DATA_VARIABLE = freeswitchPINVOKE.SWITCH_CURRENT_APPLICATION_DATA_VARIABLE_get(); public static readonly string SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE = freeswitchPINVOKE.SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE_get(); + public static readonly string SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE = freeswitchPINVOKE.SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get(); public static readonly string SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE = freeswitchPINVOKE.SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get(); public static readonly string SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE = freeswitchPINVOKE.SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE_get(); public static readonly string SWITCH_READ_RESULT_VARIABLE = freeswitchPINVOKE.SWITCH_READ_RESULT_VARIABLE_get(); @@ -5186,6 +5314,7 @@ public class freeswitch { public static readonly string SWITCH_ENDPOINT_DISPOSITION_VARIABLE = freeswitchPINVOKE.SWITCH_ENDPOINT_DISPOSITION_VARIABLE_get(); public static readonly string SWITCH_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_HOLD_MUSIC_VARIABLE_get(); public static readonly string SWITCH_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_EXPORT_VARS_VARIABLE_get(); + public static readonly string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get(); public static readonly string SWITCH_R_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_R_SDP_VARIABLE_get(); public static readonly string SWITCH_L_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_L_SDP_VARIABLE_get(); public static readonly string SWITCH_B_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_B_SDP_VARIABLE_get(); @@ -5229,6 +5358,7 @@ public class freeswitch { public static readonly int SWITCH_CORE_QUEUE_LEN = freeswitchPINVOKE.SWITCH_CORE_QUEUE_LEN_get(); public static readonly int SWITCH_MAX_MANAGEMENT_BUFFER_LEN = freeswitchPINVOKE.SWITCH_MAX_MANAGEMENT_BUFFER_LEN_get(); public static readonly int SWITCH_RTP_CNG_PAYLOAD = freeswitchPINVOKE.SWITCH_RTP_CNG_PAYLOAD_get(); + public static readonly int DMACHINE_MAX_DIGIT_LEN = freeswitchPINVOKE.DMACHINE_MAX_DIGIT_LEN_get(); public static readonly int SWITCH_API_VERSION = freeswitchPINVOKE.SWITCH_API_VERSION_get(); public static readonly int SWITCH_CORE_DB_OK = freeswitchPINVOKE.SWITCH_CORE_DB_OK_get(); public static readonly int SWITCH_CORE_DB_ERROR = freeswitchPINVOKE.SWITCH_CORE_DB_ERROR_get(); @@ -5675,6 +5805,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE_get")] public static extern string SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get")] + public static extern string SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get")] public static extern string SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE_get(); @@ -5771,6 +5904,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_EXPORT_VARS_VARIABLE_get")] public static extern string SWITCH_EXPORT_VARS_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get")] + public static extern string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_R_SDP_VARIABLE_get")] public static extern string SWITCH_R_SDP_VARIABLE_get(); @@ -5873,6 +6009,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_duration_get")] public static extern uint switch_dtmf_t_duration_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_flags_set")] + public static extern void switch_dtmf_t_flags_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_flags_get")] + public static extern int switch_dtmf_t_flags_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_dtmf_t")] public static extern IntPtr new_switch_dtmf_t(); @@ -6357,10 +6499,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_remote_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_set")] - public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_get")] - public static extern uint switch_t38_options_t_remote_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_remote_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_ip_set")] public static extern void switch_t38_options_t_local_ip_set(HandleRef jarg1, string jarg2); @@ -6369,10 +6511,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_local_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_set")] - public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_get")] - public static extern uint switch_t38_options_t_local_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_local_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_t38_options_t")] public static extern IntPtr new_switch_t38_options_t(); @@ -6428,6 +6570,45 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_console_callback_match")] public static extern void delete_switch_console_callback_match(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_DMACHINE_MAX_DIGIT_LEN_get")] + public static extern int DMACHINE_MAX_DIGIT_LEN_get(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_dmachine_set")] + public static extern void switch_ivr_dmachine_match_dmachine_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_dmachine_get")] + public static extern IntPtr switch_ivr_dmachine_match_dmachine_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_digits_set")] + public static extern void switch_ivr_dmachine_match_match_digits_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_digits_get")] + public static extern string switch_ivr_dmachine_match_match_digits_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_key_set")] + public static extern void switch_ivr_dmachine_match_match_key_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_match_key_get")] + public static extern int switch_ivr_dmachine_match_match_key_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_type_set")] + public static extern void switch_ivr_dmachine_match_type_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_type_get")] + public static extern int switch_ivr_dmachine_match_type_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_user_data_set")] + public static extern void switch_ivr_dmachine_match_user_data_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_match_user_data_get")] + public static extern IntPtr switch_ivr_dmachine_match_user_data_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_ivr_dmachine_match")] + public static extern IntPtr new_switch_ivr_dmachine_match(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_ivr_dmachine_match")] + public static extern void delete_switch_ivr_dmachine_match(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_input_callback_set")] public static extern void switch_input_args_t_input_callback_set(HandleRef jarg1, HandleRef jarg2); @@ -6458,6 +6639,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_user_data_get")] public static extern IntPtr switch_input_args_t_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_dmachine_set")] + public static extern void switch_input_args_t_dmachine_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_input_args_t_dmachine_get")] + public static extern IntPtr switch_input_args_t_dmachine_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_input_args_t")] public static extern IntPtr new_switch_input_args_t(); @@ -7160,6 +7347,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_soft_unlock")] public static extern void switch_core_session_soft_unlock(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_dmachine")] + public static extern void switch_core_session_set_dmachine(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_dmachine")] + public static extern IntPtr switch_core_session_get_dmachine(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_uuid")] public static extern string switch_core_get_uuid(); @@ -7385,12 +7578,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_timer_destroy")] public static extern int switch_core_timer_destroy(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init")] - public static extern int switch_core_codec_init(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, HandleRef jarg8, HandleRef jarg9); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init_with_bitrate")] + public static extern int switch_core_codec_init_with_bitrate(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, uint jarg8, HandleRef jarg9, HandleRef jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_copy")] public static extern int switch_core_codec_copy(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_parse_fmtp")] + public static extern int switch_core_codec_parse_fmtp(string jarg1, string jarg2, uint jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_reset")] public static extern int switch_core_codec_reset(HandleRef jarg1); @@ -7925,6 +8121,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_in_thread")] public static extern int switch_core_session_in_thread(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_default_ptime")] + public static extern uint switch_default_ptime(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); @@ -8243,6 +8442,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_is_digit_string")] public static extern int switch_is_digit_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_known_bitrate")] + public static extern uint switch_known_bitrate(byte jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_fd_read_line")] public static extern IntPtr switch_fd_read_line(int jarg1, string jarg2, HandleRef jarg3); @@ -10364,101 +10566,11 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_directory_handle")] public static extern void delete_switch_directory_handle(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_set")] - public static extern void switch_codec_settings_quality_set(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_set")] + public static extern void switch_codec_settings_unused_set(HandleRef jarg1, int jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_get")] - public static extern int switch_codec_settings_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_set")] - public static extern void switch_codec_settings_complexity_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_get")] - public static extern int switch_codec_settings_complexity_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_set")] - public static extern void switch_codec_settings_enhancement_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_get")] - public static extern int switch_codec_settings_enhancement_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_set")] - public static extern void switch_codec_settings_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_get")] - public static extern int switch_codec_settings_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_set")] - public static extern void switch_codec_settings_vbr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_get")] - public static extern int switch_codec_settings_vbr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_set")] - public static extern void switch_codec_settings_vbr_quality_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_get")] - public static extern float switch_codec_settings_vbr_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_set")] - public static extern void switch_codec_settings_abr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_get")] - public static extern int switch_codec_settings_abr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_set")] - public static extern void switch_codec_settings_dtx_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_get")] - public static extern int switch_codec_settings_dtx_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_set")] - public static extern void switch_codec_settings_preproc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_get")] - public static extern int switch_codec_settings_preproc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_set")] - public static extern void switch_codec_settings_pp_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_get")] - public static extern int switch_codec_settings_pp_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_set")] - public static extern void switch_codec_settings_pp_agc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_get")] - public static extern int switch_codec_settings_pp_agc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_set")] - public static extern void switch_codec_settings_pp_agc_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_get")] - public static extern float switch_codec_settings_pp_agc_level_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_set")] - public static extern void switch_codec_settings_pp_denoise_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_get")] - public static extern int switch_codec_settings_pp_denoise_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_set")] - public static extern void switch_codec_settings_pp_dereverb_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_get")] - public static extern int switch_codec_settings_pp_dereverb_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_set")] - public static extern void switch_codec_settings_pp_dereverb_decay_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_get")] - public static extern float switch_codec_settings_pp_dereverb_decay_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_set")] - public static extern void switch_codec_settings_pp_dereverb_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_get")] - public static extern float switch_codec_settings_pp_dereverb_level_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_get")] + public static extern int switch_codec_settings_unused_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_settings")] public static extern IntPtr new_switch_codec_settings(); @@ -10466,6 +10578,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_settings")] public static extern void delete_switch_codec_settings(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_set")] + public static extern void switch_codec_fmtp_actual_samples_per_second_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_get")] + public static extern uint switch_codec_fmtp_actual_samples_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_set")] + public static extern void switch_codec_fmtp_bits_per_second_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_get")] + public static extern int switch_codec_fmtp_bits_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_set")] + public static extern void switch_codec_fmtp_microseconds_per_packet_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_get")] + public static extern int switch_codec_fmtp_microseconds_per_packet_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_set")] + public static extern void switch_codec_fmtp_private_info_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_get")] + public static extern IntPtr switch_codec_fmtp_private_info_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_fmtp")] + public static extern IntPtr new_switch_codec_fmtp(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_fmtp")] + public static extern void delete_switch_codec_fmtp(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_interface_set")] public static extern void switch_codec_codec_interface_set(HandleRef jarg1, HandleRef jarg2); @@ -10490,12 +10632,6 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_out_get")] public static extern string switch_codec_fmtp_out_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_set")] - public static extern void switch_codec_codec_settings_set(HandleRef jarg1, HandleRef jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_get")] - public static extern IntPtr switch_codec_codec_settings_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_flags_set")] public static extern void switch_codec_flags_set(HandleRef jarg1, uint jarg2); @@ -10676,6 +10812,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_implementations_get")] public static extern IntPtr switch_codec_interface_implementations_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_set")] + public static extern void switch_codec_interface_parse_fmtp_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_get")] + public static extern IntPtr switch_codec_interface_parse_fmtp_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_codec_id_set")] public static extern void switch_codec_interface_codec_id_set(HandleRef jarg1, uint jarg2); @@ -11013,10 +11155,13 @@ class freeswitchPINVOKE { public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")] - public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, int jarg4); + public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_process_export")] + public static extern void switch_channel_process_export(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_printf")] - public static extern int switch_channel_export_variable_printf(HandleRef jarg1, string jarg2, string jarg3); + public static extern int switch_channel_export_variable_printf(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_dup")] public static extern string switch_channel_get_variable_dup(HandleRef jarg1, string jarg2, int jarg3); @@ -11793,7 +11938,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_record_file(HandleRef jarg1, HandleRef jarg2, string jarg3, HandleRef jarg4, uint jarg5); [DllImport("mod_managed", EntryPoint="CSharp_switch_play_and_get_digits")] - public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12); + public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12, uint jarg13); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_speak_text_handle")] public static extern int switch_ivr_speak_text_handle(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, string jarg5, HandleRef jarg6); @@ -11855,6 +12000,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_broadcast")] public static extern int switch_ivr_broadcast(string jarg1, string jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_broadcast_in_thread")] + public static extern void switch_ivr_broadcast_in_thread(HandleRef jarg1, string jarg2, int jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_transfer_variable")] public static extern int switch_ivr_transfer_variable(HandleRef jarg1, HandleRef jarg2, string jarg3); @@ -11931,7 +12079,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_wait_for_answer(HandleRef jarg1, HandleRef jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_read")] - public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9); + public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9, uint jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_block_dtmf_session")] public static extern int switch_ivr_block_dtmf_session(HandleRef jarg1); @@ -11978,6 +12126,42 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_uuid_exists")] public static extern int switch_ivr_uuid_exists(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_create")] + public static extern int switch_ivr_dmachine_create(HandleRef jarg1, string jarg2, HandleRef jarg3, uint jarg4, uint jarg5, HandleRef jarg6, HandleRef jarg7, HandleRef jarg8); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_destroy")] + public static extern void switch_ivr_dmachine_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_bind")] + public static extern int switch_ivr_dmachine_bind(HandleRef jarg1, string jarg2, string jarg3, int jarg4, HandleRef jarg5, HandleRef jarg6); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_feed")] + public static extern int switch_ivr_dmachine_feed(HandleRef jarg1, string jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_clear")] + public static extern int switch_ivr_dmachine_clear(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_ping")] + public static extern int switch_ivr_dmachine_ping(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_get_match")] + public static extern IntPtr switch_ivr_dmachine_get_match(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_get_failed_digits")] + public static extern string switch_ivr_dmachine_get_failed_digits(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_set_digit_timeout_ms")] + public static extern void switch_ivr_dmachine_set_digit_timeout_ms(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_set_input_timeout_ms")] + public static extern void switch_ivr_dmachine_set_input_timeout_ms(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_clear_realm")] + public static extern int switch_ivr_dmachine_clear_realm(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_dmachine_set_realm")] + public static extern int switch_ivr_dmachine_set_realm(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RTP_MAX_BUF_LEN_get")] public static extern int SWITCH_RTP_MAX_BUF_LEN_get(); @@ -12203,6 +12387,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_stats")] public static extern IntPtr switch_rtp_get_stats(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_check_auto_adj")] + public static extern byte switch_rtp_check_auto_adj(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_data_set")] public static extern void switch_log_node_t_data_set(HandleRef jarg1, string jarg2); @@ -13338,10 +13525,10 @@ class freeswitchPINVOKE { public static extern int CoreSession_Transfer(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_read")] - public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6); + public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_PlayAndGetDigits")] - public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10); + public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, int jarg11); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_StreamFile")] public static extern int CoreSession_StreamFile(HandleRef jarg1, string jarg2, int jarg3); @@ -14051,6 +14238,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_q_const__char_p_switch_core_session_p_switch_stream_handle__switch_status_t { private HandleRef swigCPtr; @@ -15431,6 +15648,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_ivr_dmachine_match__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_media_bug_p_void_enum_switch_abc_type_t__switch_bool_t { private HandleRef swigCPtr; @@ -16781,6 +17028,66 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_ivr_dmachine { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_ivr_dmachine(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_ivr_dmachine() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_ivr_dmachine obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + +public class SWIGTYPE_p_p_switch_ivr_dmachine_match { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_ivr_dmachine_match(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_ivr_dmachine_match() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_ivr_dmachine_match obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_ivr_menu { private HandleRef swigCPtr; @@ -17621,6 +17928,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_ivr_dmachine { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_ivr_dmachine(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_ivr_dmachine() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_ivr_dmachine obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_ivr_menu_action_function_t { private HandleRef swigCPtr; @@ -20862,6 +21199,8 @@ public enum switch_channel_flag_t { CF_EARLY_HANGUP, CF_MEDIA_SET, CF_CONSUME_ON_ORIGINATE, + CF_PASSTHRU_PTIME_MISMATCH, + CF_BRIDGE_NOWRITE, CF_FLAG_MAX } @@ -21253,17 +21592,6 @@ public class switch_codec : IDisposable { } } - public switch_codec_settings codec_settings { - set { - freeswitchPINVOKE.switch_codec_codec_settings_set(swigCPtr, switch_codec_settings.getCPtr(value)); - } - get { - IntPtr cPtr = freeswitchPINVOKE.switch_codec_codec_settings_get(swigCPtr); - switch_codec_settings ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_settings(cPtr, false); - return ret; - } - } - public uint flags { set { freeswitchPINVOKE.switch_codec_flags_set(swigCPtr, value); @@ -21370,6 +21698,94 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class switch_codec_fmtp : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_codec_fmtp(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_codec_fmtp obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_codec_fmtp() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_codec_fmtp(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public uint actual_samples_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_get(swigCPtr); + return ret; + } + } + + public int bits_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_get(swigCPtr); + return ret; + } + } + + public int microseconds_per_packet { + set { + freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_void private_info { + set { + freeswitchPINVOKE.switch_codec_fmtp_private_info_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_fmtp_private_info_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public switch_codec_fmtp() : this(freeswitchPINVOKE.new_switch_codec_fmtp(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class switch_codec_implementation : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; @@ -21671,6 +22087,17 @@ public class switch_codec_interface : IDisposable { } } + public SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t parse_fmtp { + set { + freeswitchPINVOKE.switch_codec_interface_parse_fmtp_set(swigCPtr, SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_interface_parse_fmtp_get(swigCPtr); + SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(cPtr, false); + return ret; + } + } + public uint codec_id { set { freeswitchPINVOKE.switch_codec_interface_codec_id_set(swigCPtr, value); @@ -21782,162 +22209,12 @@ public class switch_codec_settings : IDisposable { } } - public int quality { + public int unused { set { - freeswitchPINVOKE.switch_codec_settings_quality_set(swigCPtr, value); + freeswitchPINVOKE.switch_codec_settings_unused_set(swigCPtr, value); } get { - int ret = freeswitchPINVOKE.switch_codec_settings_quality_get(swigCPtr); - return ret; - } - } - - public int complexity { - set { - freeswitchPINVOKE.switch_codec_settings_complexity_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_complexity_get(swigCPtr); - return ret; - } - } - - public int enhancement { - set { - freeswitchPINVOKE.switch_codec_settings_enhancement_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_enhancement_get(swigCPtr); - return ret; - } - } - - public int vad { - set { - freeswitchPINVOKE.switch_codec_settings_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vad_get(swigCPtr); - return ret; - } - } - - public int vbr { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vbr_get(swigCPtr); - return ret; - } - } - - public float vbr_quality { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_quality_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_vbr_quality_get(swigCPtr); - return ret; - } - } - - public int abr { - set { - freeswitchPINVOKE.switch_codec_settings_abr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_abr_get(swigCPtr); - return ret; - } - } - - public int dtx { - set { - freeswitchPINVOKE.switch_codec_settings_dtx_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_dtx_get(swigCPtr); - return ret; - } - } - - public int preproc { - set { - freeswitchPINVOKE.switch_codec_settings_preproc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_preproc_get(swigCPtr); - return ret; - } - } - - public int pp_vad { - set { - freeswitchPINVOKE.switch_codec_settings_pp_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_vad_get(swigCPtr); - return ret; - } - } - - public int pp_agc { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_get(swigCPtr); - return ret; - } - } - - public float pp_agc_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_level_get(swigCPtr); - return ret; - } - } - - public int pp_denoise { - set { - freeswitchPINVOKE.switch_codec_settings_pp_denoise_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_denoise_get(swigCPtr); - return ret; - } - } - - public int pp_dereverb { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_decay { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_get(swigCPtr); + int ret = freeswitchPINVOKE.switch_codec_settings_unused_get(swigCPtr); return ret; } } @@ -23460,6 +23737,16 @@ public class switch_dtmf_t : IDisposable { } } + public int flags { + set { + freeswitchPINVOKE.switch_dtmf_t_flags_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_dtmf_t_flags_get(swigCPtr); + return ret; + } + } + public switch_dtmf_t() : this(freeswitchPINVOKE.new_switch_dtmf_t(), true) { } @@ -25025,6 +25312,17 @@ public class switch_input_args_t : IDisposable { } } + public SWIGTYPE_p_switch_ivr_dmachine dmachine { + set { + freeswitchPINVOKE.switch_input_args_t_dmachine_set(swigCPtr, SWIGTYPE_p_switch_ivr_dmachine.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_input_args_t_dmachine_get(swigCPtr); + SWIGTYPE_p_switch_ivr_dmachine ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_ivr_dmachine(cPtr, false); + return ret; + } + } + public switch_input_args_t() : this(freeswitchPINVOKE.new_switch_input_args_t(), true) { } @@ -26306,6 +26604,105 @@ public enum switch_ivr_action_t { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_ivr_dmachine_match : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_ivr_dmachine_match(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_ivr_dmachine_match obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_ivr_dmachine_match() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_ivr_dmachine_match(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_ivr_dmachine dmachine { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_dmachine_set(swigCPtr, SWIGTYPE_p_switch_ivr_dmachine.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_ivr_dmachine_match_dmachine_get(swigCPtr); + SWIGTYPE_p_switch_ivr_dmachine ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_ivr_dmachine(cPtr, false); + return ret; + } + } + + public string match_digits { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_match_digits_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_ivr_dmachine_match_match_digits_get(swigCPtr); + return ret; + } + } + + public int match_key { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_match_key_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_ivr_dmachine_match_match_key_get(swigCPtr); + return ret; + } + } + + public dm_match_type_t type { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_type_set(swigCPtr, (int)value); + } + get { + dm_match_type_t ret = (dm_match_type_t)freeswitchPINVOKE.switch_ivr_dmachine_match_type_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_void user_data { + set { + freeswitchPINVOKE.switch_ivr_dmachine_match_user_data_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_ivr_dmachine_match_user_data_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public switch_ivr_dmachine_match() : this(freeswitchPINVOKE.new_switch_ivr_dmachine_match(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_ivr_menu_flags { SWITCH_IVR_MENU_FLAG_FALLTOMAIN = (1 << 0), SWITCH_IVR_MENU_FLAG_FREEPOOL = (1 << 1), @@ -29262,6 +29659,7 @@ public enum switch_status_t { SWITCH_STATUS_NOUNLOAD, SWITCH_STATUS_IGNORE, SWITCH_STATUS_TOO_SMALL, + SWITCH_STATUS_FOUND, SWITCH_STATUS_NOT_INITALIZED } @@ -29567,12 +29965,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint remote_port { + public ushort remote_port { set { freeswitchPINVOKE.switch_t38_options_t_remote_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); return ret; } } @@ -29587,12 +29985,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint local_port { + public ushort local_port { set { freeswitchPINVOKE.switch_t38_options_t_local_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); return ret; } } diff --git a/src/mod/languages/mod_managed/runswig.2010.cmd b/src/mod/languages/mod_managed/runswig.2010.cmd new file mode 100644 index 0000000000..288c420efe --- /dev/null +++ b/src/mod/languages/mod_managed/runswig.2010.cmd @@ -0,0 +1,10 @@ +move freeswitch_wrap.cxx freeswitch_wrap.bak +\dev\swig20\swig.exe -I..\..\..\include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_managed -DSWIG_CSHARP_NO_STRING_HELPER freeswitch.i +del swig.csx +move freeswitch_wrap.cxx freeswitch_wrap.2010.cxx +move freeswitch_wrap.bak freeswitch_wrap.cxx +@ECHO OFF +for %%X in (*.cs) do type %%X >> swig.csx +@ECHO ON +move swig.csx managed\swig.2010.cs +del *.cs diff --git a/src/mod/languages/mod_managed/runswig.cmd b/src/mod/languages/mod_managed/runswig.cmd index 9b1a659061..631a507a20 100644 --- a/src/mod/languages/mod_managed/runswig.cmd +++ b/src/mod/languages/mod_managed/runswig.cmd @@ -1,4 +1,4 @@ -\dev\swig\swig.exe -I..\..\..\include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_managed -DSWIG_CSHARP_NO_STRING_HELPER freeswitch.i +\dev\swig135\swig.exe -I..\..\..\include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_managed -DSWIG_CSHARP_NO_STRING_HELPER freeswitch.i del swig.csx @ECHO OFF for %%X in (*.cs) do type %%X >> swig.csx diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp index 5ba899fbf8..2efbdf1abc 100644 --- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp +++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp @@ -6637,6 +6637,7 @@ XS(_wrap_CoreSession_read) { char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -6652,11 +6653,13 @@ XS(_wrap_CoreSession_read) { int res6 ; char *buf6 = 0 ; int alloc6 = 0 ; + int val7 ; + int ecode7 = 0 ; int argvi = 0; dXSARGS; - if ((items < 6) || (items > 6)) { - SWIG_croak("Usage: CoreSession_read(self,min_digits,max_digits,prompt_audio_file,timeout,valid_terminators);"); + if ((items < 6) || (items > 7)) { + SWIG_croak("Usage: CoreSession_read(self,min_digits,max_digits,prompt_audio_file,timeout,valid_terminators,digit_timeout);"); } res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { @@ -6688,7 +6691,14 @@ XS(_wrap_CoreSession_read) { SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "CoreSession_read" "', argument " "6"" of type '" "char const *""'"); } arg6 = reinterpret_cast< char * >(buf6); - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + if (items > 6) { + ecode7 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(6), &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "CoreSession_read" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + } + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; @@ -6696,6 +6706,7 @@ XS(_wrap_CoreSession_read) { if (alloc4 == SWIG_NEWOBJ) delete[] buf4; if (alloc6 == SWIG_NEWOBJ) delete[] buf6; + XSRETURN(argvi); fail: @@ -6704,6 +6715,7 @@ XS(_wrap_CoreSession_read) { if (alloc4 == SWIG_NEWOBJ) delete[] buf4; if (alloc6 == SWIG_NEWOBJ) delete[] buf6; + SWIG_croak_null(); } } @@ -6721,6 +6733,7 @@ XS(_wrap_CoreSession_playAndGetDigits) { char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -6747,11 +6760,13 @@ XS(_wrap_CoreSession_playAndGetDigits) { int res10 ; char *buf10 = 0 ; int alloc10 = 0 ; + int val11 ; + int ecode11 = 0 ; int argvi = 0; dXSARGS; - if ((items < 9) || (items > 10)) { - SWIG_croak("Usage: CoreSession_playAndGetDigits(self,min_digits,max_digits,max_tries,timeout,terminators,audio_files,bad_input_audio_files,digits_regex,var_name);"); + if ((items < 9) || (items > 11)) { + SWIG_croak("Usage: CoreSession_playAndGetDigits(self,min_digits,max_digits,max_tries,timeout,terminators,audio_files,bad_input_audio_files,digits_regex,var_name,digit_timeout);"); } res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { @@ -6805,7 +6820,14 @@ XS(_wrap_CoreSession_playAndGetDigits) { } arg10 = reinterpret_cast< char * >(buf10); } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + if (items > 10) { + ecode11 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(10), &val11); + if (!SWIG_IsOK(ecode11)) { + SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "CoreSession_playAndGetDigits" "', argument " "11"" of type '" "int""'"); + } + arg11 = static_cast< int >(val11); + } + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; @@ -6817,6 +6839,7 @@ XS(_wrap_CoreSession_playAndGetDigits) { if (alloc8 == SWIG_NEWOBJ) delete[] buf8; if (alloc9 == SWIG_NEWOBJ) delete[] buf9; if (alloc10 == SWIG_NEWOBJ) delete[] buf10; + XSRETURN(argvi); fail: @@ -6829,6 +6852,7 @@ XS(_wrap_CoreSession_playAndGetDigits) { if (alloc8 == SWIG_NEWOBJ) delete[] buf8; if (alloc9 == SWIG_NEWOBJ) delete[] buf9; if (alloc10 == SWIG_NEWOBJ) delete[] buf10; + SWIG_croak_null(); } } @@ -9708,17 +9732,17 @@ XS(SWIG_init) { SWIG_TypeClientData(SWIGTYPE_p_IVRMenu, (void*) "freeswitch::IVRMenu"); SWIG_TypeClientData(SWIGTYPE_p_API, (void*) "freeswitch::API"); SWIG_TypeClientData(SWIGTYPE_p_input_callback_state, (void*) "freeswitch::input_callback_state_t"); - /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_HUP", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_HUP))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_FREE", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_FREE))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_RDLOCK", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_RDLOCK))); SvREADONLY_on(sv); diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index 8dc32a2dca..0907bec98f 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -7025,6 +7025,7 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -7040,14 +7041,17 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb int res6 ; char *buf6 = 0 ; int alloc6 = 0 ; + int val7 ; + int ecode7 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; + PyObject * obj6 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOOO:CoreSession_read",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOOOOO|O:CoreSession_read",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_read" "', argument " "1"" of type '" "CoreSession *""'"); @@ -7078,7 +7082,14 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "CoreSession_read" "', argument " "6"" of type '" "char const *""'"); } arg6 = reinterpret_cast< char * >(buf6); - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + if (obj6) { + ecode7 = SWIG_AsVal_int(obj6, &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "CoreSession_read" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + } + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); resultobj = SWIG_FromCharPtr((const char *)result); if (alloc4 == SWIG_NEWOBJ) delete[] buf4; if (alloc6 == SWIG_NEWOBJ) delete[] buf6; @@ -7102,6 +7113,7 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -7128,6 +7140,8 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM int res10 ; char *buf10 = 0 ; int alloc10 = 0 ; + int val11 ; + int ecode11 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; @@ -7138,8 +7152,9 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM PyObject * obj7 = 0 ; PyObject * obj8 = 0 ; PyObject * obj9 = 0 ; + PyObject * obj10 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO|O:CoreSession_playAndGetDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO|OO:CoreSession_playAndGetDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_playAndGetDigits" "', argument " "1"" of type '" "CoreSession *""'"); @@ -7192,7 +7207,14 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM } arg10 = reinterpret_cast< char * >(buf10); } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + if (obj10) { + ecode11 = SWIG_AsVal_int(obj10, &val11); + if (!SWIG_IsOK(ecode11)) { + SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "CoreSession_playAndGetDigits" "', argument " "11"" of type '" "int""'"); + } + arg11 = static_cast< int >(val11); + } + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); resultobj = SWIG_FromCharPtr((const char *)result); if (alloc6 == SWIG_NEWOBJ) delete[] buf6; if (alloc7 == SWIG_NEWOBJ) delete[] buf7; diff --git a/src/mod/say/mod_say_ja/mod_say_ja.c b/src/mod/say/mod_say_ja/mod_say_ja.c new file mode 100644 index 0000000000..407d2d4a91 --- /dev/null +++ b/src/mod/say/mod_say_ja/mod_say_ja.c @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2007, Anthony Minessale II + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * Braga Bruno + * + * + * mod_say_ja.c -- Say for Japanese. + * + */ + +#include +#include +#include +#include + +SWITCH_MODULE_LOAD_FUNCTION(mod_say_ja_load); +SWITCH_MODULE_DEFINITION(mod_say_ja, mod_say_ja_load, NULL, NULL); + +#define say_num(num, meth) { \ + char tmp[80]; \ + switch_status_t tstatus; \ + switch_say_method_t smeth = say_args->method; \ + switch_say_type_t stype = say_args->type; \ + say_args->type = SST_ITEMS; say_args->method = meth; \ + switch_snprintf(tmp, sizeof(tmp), "%u", (unsigned)num); \ + if ((tstatus = \ + ja_say_general_count(session, tmp, say_args, args)) \ + != SWITCH_STATUS_SUCCESS) { \ + return tstatus; \ + } \ + say_args->method = smeth; say_args->type = stype; \ + } \ + +#define say_file(...) { \ + char tmp[80]; \ + switch_status_t tstatus; \ + switch_snprintf(tmp, sizeof(tmp), __VA_ARGS__); \ + if ((tstatus = \ + switch_ivr_play_file(session, NULL, tmp, args)) \ + != SWITCH_STATUS_SUCCESS){ \ + return tstatus; \ + } \ + if (!switch_channel_ready(switch_core_session_get_channel(session))) { \ + return SWITCH_STATUS_FALSE; \ + }} \ + +static switch_status_t ja_say_general_count(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + int in; + char sbuf[13] = ""; + char digits[11]; + int i; + + if (!(tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf))) || strlen(tosay) > 9) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + + in = atoi(tosay); + + if (in != 0) { + snprintf(digits, sizeof(digits), "%10.10d", in); + switch (say_args->method) { + case SSM_COUNTED: + say_file("digits/ordinal.wav"); + /* Fall through */ + case SSM_PRONOUNCED: + for (i = 0; i <= 9; i++) { + switch (i) { + case 0: + /* Billions column */ + if (digits[i] != '0') { + if (digits[i] != '1') + say_file("digits/%c.wav", digits[i]); + say_file("digits/10.wav"); + if (memcmp(digits + 1, "0", 1) == 0) + say_file("digits/100000000.wav", digits[i]); + } + break; + case 1: + /* Hundred millions columns */ + if (digits[i] != '0') { + say_file("digits/%c.wav", digits[i]); + say_file("digits/100000000.wav", digits[i]); + } + break; + case 2: + /* Ten millions column */ + if (digits[i] != '0') { + say_file("digits/%c.wav", digits[i]); + say_file("digits/1000.wav"); + if (memcmp(digits + 3, "000", 3) == 0) + say_file("digits/10000.wav", digits[i]); + } + break; + case 3: + /* Millions column */ + if (digits[i] != '0') { + say_file("digits/%c.wav", digits[i]); + say_file("digits/100.wav"); + if (memcmp(digits + 4, "00", 2) == 0) + say_file("digits/10000.wav", digits[i]); + } + break; + case 4: + /* Hundred thousands column */ + if (digits[i] != '0') { + if (digits[i] != '1') + say_file("digits/%c.wav", digits[i]); + say_file("digits/10.wav"); + if (memcmp(digits + 5, "0", 1) == 0) + say_file("digits/10000.wav", digits[i]); + } + break; + + case 5: + /* Ten thousands column */ + if (digits[i] != '0') { + say_file("digits/%c.wav", digits[i]); + say_file("digits/10000.wav"); + } + break; + case 6: + /* thousands column */ + if (digits[i] != '0') { + + switch (digits[i]) { + case '1': + if (memcmp(digits, "000000", 6) != 0) { + say_file("digits/1000s.wav"); + } else { + say_file("digits/1000.wav"); + } + break; + case '3': + say_file("digits/3000.wav"); + break; + default: + say_file("digits/%c.wav", digits[i]); + say_file("digits/1000.wav"); + break; + } + } + break; + case 7: + /* hundreds column */ + if (digits[i] != '0') { + switch (digits[i]) { + case '1': + say_file("digits/100.wav"); + break; + case '3': + say_file("digits/300.wav"); + break; + case '6': + say_file("digits/600.wav"); + break; + case '8': + say_file("digits/800.wav"); + break; + default: + say_file("digits/%c.wav", digits[i]); + say_file("digits/100.wav"); + break; + } + } + break; + case 8: + /* Tens column */ + if (digits[i] != '0') { + if (digits[i] != '1') + say_file("digits/%c.wav", digits[i]); + say_file("digits/10.wav"); + } + break; + case 9: + /* Units column */ + if (digits[i] != '0') + say_file("digits/%c.wav", digits[i]); + break; + } + } + break; + case SSM_ITERATED: + { + char *p; + for (p = tosay; p && *p; p++) + say_file("digits/%c.wav", *p); + } + break; + default: + break; + } + } else { + say_file("digits/0.wav"); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t ja_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + int32_t t; + switch_time_t target = 0; + switch_time_exp_t tm; + uint8_t say_date = 0; + uint8_t say_time = 0; + + int mod_min; + char buffer[3]; + + + if (say_args->type == SST_TIME_MEASUREMENT) { + int64_t hours = 0; + int64_t minutes = 0; + int64_t seconds = 0; + int64_t r = 0; + if (strchr(tosay, ':')) { + char *tme = switch_core_session_strdup(session, tosay); + char *p; + + if ((p = strrchr(tme, ':'))) { + *p++ = '\0'; + seconds = atoi(p); + if ((p = strchr(tme, ':'))) { + *p++ = '\0'; + minutes = atoi(p); + if (tme) { + hours = atoi(tme); + } + } else { + minutes = atoi(tme); + } + } + } else { + if ((seconds = atoi(tosay)) <= 0) { + seconds = (int64_t) switch_epoch_time_now(NULL); + } + + if (seconds >= 60) { + minutes = seconds / 60; + r = seconds % 60; + seconds = r; + } + + if (minutes >= 60) { + hours = minutes / 60; + r = minutes % 60; + minutes = r; + } + } + + if (hours) { + say_num(hours, SSM_PRONOUNCED); + say_file("time/hours.wav"); + } + if (minutes) { + say_num(minutes, SSM_PRONOUNCED); + say_file("time/minute.wav"); + } else { + if (hours) { + say_file("digits/0.wav"); + say_file("time/minute.wav"); + } + } + + if (seconds) { + say_num(hours, SSM_PRONOUNCED); + say_file("time/seconds.wav"); + } else { + if (hours || minutes) { + say_file("digits/0.wav"); + say_file("time/second.wav"); + } + } + + return SWITCH_STATUS_SUCCESS; + } + + if ((t = atoi(tosay)) > 0) + target = switch_time_make(t, 0); + else + target = switch_micro_time_now(); + switch_time_exp_lt(&tm, target); + + switch (say_args->type) { + case SST_CURRENT_DATE_TIME: + say_date = say_time = 1; + break; + case SST_CURRENT_DATE: + say_date = 1; + break; + case SST_CURRENT_TIME: + say_time = 1; + break; + default: + break; + } + + if (say_date) { + say_num(tm.tm_year + 1900, SSM_PRONOUNCED); + say_file("time/year.wav"); + say_file("time/month-%d.wav", tm.tm_mon); + say_file("time/day-%d.wav", tm.tm_mday); + } + + if (say_time) { + int32_t hour = tm.tm_hour; + + if (hour < 12) { + say_file("time/am.wav"); + } else { + say_file("time/pm.wav"); + } + say_file("time/hour-%d.wav", tm.tm_hour); + if (tm.tm_min > 10) { + int temp; + char tch[1+1]; + mod_min = tm.tm_min % 10; + memset(buffer,0,sizeof(buffer)); + memset(tch,0,sizeof(tch)); + sprintf(buffer, "%d", tm.tm_min); + memcpy(tch,buffer,1); + temp = atoi(tch); + if (temp > 1){ + say_num(temp,SSM_PRONOUNCED); + } + if (mod_min != 0){ + say_file("digits/10.wav"); + } + else{ + mod_min = 10; + } + } else { + mod_min = tm.tm_min; + } + switch(mod_min) { + case 0: + say_file("time/oclock.wav", mod_min); + break; + case 1: + case 3: + case 4: + case 6: + case 8: + case 10: + say_file("time/min-%d.wav", mod_min); + break; + default: + say_num(mod_min, SSM_PRONOUNCED); + say_file("time/minute.wav"); + break; + } + } + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t ja_say_money(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + char sbuf[16] = ""; /* enough for 999,999,999,999.99 (w/o the commas or leading $) */ + char *dollars = NULL; + char *cents = NULL; + + if (strlen(tosay) > 15 || !(tosay = switch_strip_nonnumerics(tosay, sbuf, sizeof(sbuf)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + + dollars = sbuf; + + if ((cents = strchr(sbuf, '.'))) { + *cents++ = '\0'; + if (strlen(cents) > 2) { + cents[2] = '\0'; + } + } + + /* If positive sign - skip over" */ + if (sbuf[0] == '+') { + dollars++; + } + + /* If negative say "negative" */ + if (sbuf[0] == '-') { + say_file("currency/negative.wav"); + dollars++; + } + + /* Say dollar amount */ + ja_say_general_count(session, dollars, say_args, args); + say_file("currency/dollar.wav"); + + /* Say cents */ + if (cents) { + ja_say_general_count(session, cents, say_args, args); + } else { + say_file("digits/0.wav"); + } + say_file("currency/cent.wav"); + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t ja_say(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + switch_say_callback_t say_cb = NULL; + + switch (say_args->type) { + case SST_NUMBER: + case SST_ITEMS: + case SST_PERSONS: + case SST_MESSAGES: + say_cb = ja_say_general_count; + break; + case SST_TIME_MEASUREMENT: + case SST_CURRENT_DATE: + case SST_CURRENT_TIME: + case SST_CURRENT_DATE_TIME: + say_cb = ja_say_time; + break; + case SST_IP_ADDRESS: + return switch_ivr_say_ip(session, tosay, ja_say_general_count, say_args, args); + break; + case SST_NAME_SPELLED: + case SST_NAME_PHONETIC: + return switch_ivr_say_spell(session, tosay, say_args, args); + break; + case SST_CURRENCY: + say_cb = ja_say_money; + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown Say type=[%d]\n", say_args->type); + break; + } + + if (say_cb) { + return say_cb(session, tosay, say_args, args); + } + + return SWITCH_STATUS_FALSE; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_say_ja_load) +{ + switch_say_interface_t *say_interface; + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + say_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SAY_INTERFACE); + say_interface->interface_name = "ja"; + say_interface->say_function = ja_say; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 83f9f72c09..84643dcd0b 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -264,7 +264,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) if (globals.encode == ENCODING_TEXTXML) { headers = curl_slist_append(headers, "Content-Type: text/xml"); } else if (globals.encode) { - switch_size_t need_bytes = strlen(xml_text) * 3; + switch_size_t need_bytes = strlen(xml_text) * 3 + 1; xml_text_escaped = malloc(need_bytes); switch_assert(xml_text_escaped); diff --git a/src/switch.c b/src/switch.c index b59097ac89..a28baba6f0 100644 --- a/src/switch.c +++ b/src/switch.c @@ -271,13 +271,12 @@ int main(int argc, char *argv[]) switch_size_t pid_len, old_pid_len; const char *err = NULL; /* error value for return from freeswitch initialization */ #ifndef WIN32 - int bf = 0; + int nf = 0; /* TRUE if we are running in nofork mode */ char *runas_user = NULL; char *runas_group = NULL; #else int win32_service = 0; #endif - int nf = 0; /* TRUE if we are running in nofork mode */ int nc = 0; /* TRUE if we are running in noconsole mode */ pid_t pid = 0; int i, x; @@ -329,7 +328,6 @@ int main(int argc, char *argv[]) "\t-monotonic-clock -- use monotonic clock as timer source\n" #else "\t-nf -- no forking\n" - "\t-bf -- block until fully started, then fork\n" "\t-u [user] -- specify user to switch to\n" "\t-g [group] -- specify group to switch to\n" #endif "\t-help -- this message\n" "\t-version -- print the version and exit\n" @@ -463,11 +461,6 @@ int main(int argc, char *argv[]) known_opt++; } - if (local_argv[x] && !strcmp(local_argv[x], "-bf")) { - bf++; - known_opt++; - } - if (local_argv[x] && !strcmp(local_argv[x], "-version")) { fprintf(stdout, "FreeSWITCH version: %s\n", SWITCH_VERSION_FULL); return 0; @@ -530,14 +523,8 @@ int main(int argc, char *argv[]) } if (local_argv[x] && !strcmp(local_argv[x], "-nc")) { - if (!nf) { - nc++; - known_opt++; - } else { - /* The flags -nc and -nf are mutually exclusive. Ignoring -nc. */ - nc = 0; - known_opt++; - } + nc++; + known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-c")) { @@ -698,7 +685,7 @@ int main(int argc, char *argv[]) #ifdef WIN32 FreeConsole(); #else - if (!nf && !bf) { + if (!nf) { daemonize(); } #endif @@ -813,12 +800,6 @@ int main(int argc, char *argv[]) return 255; } -#ifndef WIN32 - if(bf) { - daemonize(); - } -#endif - switch_core_runtime_loop(nc); destroy_status = switch_core_destroy(); diff --git a/src/switch_channel.c b/src/switch_channel.c index ba5560129b..9e76b46a5a 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -400,7 +400,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf_string(switch_channel_t *channel, const char *dtmf_string) { char *p; - switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0) }; + switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0), 0}; int sent = 0, dur; char *string; int i, argc; @@ -410,6 +410,11 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf_string(switch_channel_ return SWITCH_STATUS_FALSE; } + if (*dtmf_string == '!') { + dtmf_string++; + dtmf.flags = DTMF_FLAG_SKIP_PROCESS; + } + string = switch_core_session_strdup(channel->session, dtmf_string); argc = switch_separate_string(string, '+', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -847,29 +852,109 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_profile_var(switch_channel_t return status; } -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) -{ - const char *exports; - switch_status_t status = SWITCH_STATUS_FALSE; - exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE); - - if ((status = switch_channel_set_variable_var_check(channel, varname, value, var_check)) != SWITCH_STATUS_SUCCESS) { - return status; +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) +{ + + const char *export_vars = switch_channel_get_variable(channel, export_varname); + char *cptmp = switch_core_session_strdup(channel->session, export_vars); + int argc; + char *argv[256]; + + if (zstr(export_vars)) return; + + + if (var_event) { + switch_event_del_header(var_event, export_varname); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, export_varname, export_vars); + } + + if (peer_channel) { + switch_channel_set_variable(peer_channel, export_varname, export_vars); } - if (varname && value) { - if (exports) { - switch_channel_set_variable_printf(channel, SWITCH_EXPORT_VARS_VARIABLE, "%s,%s", exports, varname); - } else { - switch_channel_set_variable(channel, SWITCH_EXPORT_VARS_VARIABLE, varname); + if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { + int x; + + for (x = 0; x < argc; x++) { + const char *vval; + if ((vval = switch_channel_get_variable(channel, argv[x]))) { + char *vvar = argv[x]; + if (!strncasecmp(vvar, "nolocal:", 8)) { + vvar += 8; + } + if (var_event) { + switch_event_del_header(var_event, vvar); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, + "%s EXPORTING[%s] [%s]=[%s] to event\n", + switch_channel_get_name(channel), + export_varname, + vvar, vval); + } + if (peer_channel) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, + "%s EXPORTING[%s] [%s]=[%s] to %s\n", + switch_channel_get_name(channel), + export_varname, + vvar, vval, switch_channel_get_name(peer_channel)); + switch_channel_set_variable(peer_channel, vvar, vval); + } + } } } - return status; + } -SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt, ...) +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) +{ + char *var_name = NULL; + const char *exports; + char *var, *new_exports, *new_exports_d = NULL; + int local = 1; + + exports = switch_channel_get_variable(channel, export_varname); + + var = switch_core_session_strdup(channel->session, varname); + + if (var) { + if (!strncasecmp(var, "nolocal:", 8)) { + var_name = var + 8; + local = 0; + } else { + var_name = var; + } + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_DEBUG, "EXPORT (%s) %s[%s]=[%s]\n", + export_varname, local ? "" : "(REMOTE ONLY) ", + var_name ? var_name : "", val ? val : "UNDEF"); + + + switch_channel_set_variable_var_check(channel, var, val, var_check); + + if (var && val) { + if (exports) { + new_exports_d = switch_mprintf("%s,%s", exports, var); + new_exports = new_exports_d; + } else { + new_exports = var; + } + + switch_channel_set_variable(channel, export_varname, new_exports); + + switch_safe_free(new_exports_d); + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname, + const char *export_varname, const char *fmt, ...) { switch_status_t status = SWITCH_STATUS_FALSE; char *data = NULL; @@ -886,7 +971,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_cha return SWITCH_STATUS_FALSE; } - status = switch_channel_export_variable(channel, varname, data); + status = switch_channel_export_variable(channel, varname, export_varname, data); free(data); @@ -902,6 +987,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_var_check(switch_cha switch_mutex_lock(channel->profile_mutex); if (channel->variables && !zstr(varname)) { + switch_event_del_header(channel->variables, varname); if (!zstr(value)) { int ok = 1; @@ -1834,6 +1920,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann if (impl.iananame) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Name", impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Rate", "%u", impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Bit-Rate", "%d", impl.bits_per_second); } switch_core_session_get_write_impl(channel->session, &impl); @@ -1841,6 +1928,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann if (impl.iananame) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%u", impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Bit-Rate", "%d", impl.bits_per_second); } /* Index Caller's Profile */ @@ -2476,6 +2564,10 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_ switch_core_session_execute_application(channel->session, app, arg); } + if ((var = switch_channel_get_variable(channel, SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE))) { + switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH); + } + /* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel */ @@ -2603,6 +2695,10 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan switch_core_session_rwunlock(other_session); } + if ((var = switch_channel_get_variable(channel, SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE))) { + switch_channel_set_flag(channel, CF_PASSTHRU_PTIME_MISMATCH); + } + if ((var = switch_channel_get_variable(channel, SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE))) { uint32_t seconds = 60; int tmp; @@ -2811,14 +2907,15 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables(switch_channel_t *channel } p = e > endof_indup ? endof_indup : e; - if ((vval = strchr(vname, '('))) { + if ((vval = strchr(vname, '(')) || (vval = strchr(vname, ' '))) { + if (*vval == '(') br = 1; e = vval - 1; *vval++ = '\0'; while (*e == ' ') { *e-- = '\0'; } e = vval; - br = 1; + while (e && *e) { if (*e == '(') { br++; @@ -3014,7 +3111,7 @@ SWITCH_DECLARE(char *) switch_channel_build_param_string(switch_channel_t *chann new_len = (strlen(prof[x]) * 3) + 1; if (encode_len < new_len) { char *tmp; - + encode_len = new_len; if (!(tmp = realloc(encode_buf, encode_len))) { diff --git a/src/switch_console.c b/src/switch_console.c index 06a7e0de7a..9f13823198 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -493,7 +493,7 @@ static int comp_callback(void *pArg, int argc, char **argv, char **columnNames) argc = switch_separate_string(list, ':', argv, (sizeof(argv) / sizeof(argv[0]))); - for (i = 0; i < argc; i++) { + for (i = 0; (int)i < argc; i++) { if (!cur || !strncmp(argv[i], cur, strlen(cur))) { r_argv[0] = argv[i]; comp_callback(h, 1, r_argv, r_cols); diff --git a/src/switch_core.c b/src/switch_core.c index 2c33b341de..1275b906e7 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1275,6 +1275,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc switch_core_session_init(runtime.memory_pool); switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA); switch_core_hash_init(&runtime.mime_types, runtime.memory_pool); + switch_core_hash_init_case(&runtime.ptimes, runtime.memory_pool, SWITCH_FALSE); load_mime_types(); runtime.flags |= flags; runtime.sps_total = 30; @@ -1405,13 +1406,56 @@ static void handle_SIGHUP(int sig) } +SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number) +{ + uint32_t *p; + + if ((p = switch_core_hash_find(runtime.ptimes, name))) { + return *p; + } + + return 20; +} + +static uint32_t d_30 = 30; + static void switch_load_core_config(const char *file) { switch_xml_t xml = NULL, cfg = NULL; + switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30); + switch_core_hash_insert(runtime.ptimes, "G723", &d_30); + if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) { switch_xml_t settings, param; + if ((settings = switch_xml_child(cfg, "default-ptimes"))) { + for (param = switch_xml_child(settings, "codec"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "ptime"); + + if (!zstr(var) && !zstr(val)) { + uint32_t *p; + uint32_t v = (unsigned long) atol(val); + + if (!strcasecmp(var, "G723") || !strcasecmp(var, "iLBC")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, defaults cannot be changed\n", var); + continue; + } + + if (v < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding %s, invalid ptime\n", var); + continue; + } + + p = switch_core_alloc(runtime.memory_pool, sizeof(*p)); + *p = v; + switch_core_hash_insert(runtime.ptimes, var, p); + } + + } + } + if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { const char *var = switch_xml_attr_soft(param, "name"); @@ -1973,6 +2017,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir); switch_event_destroy(&runtime.global_vars); + switch_core_hash_destroy(&runtime.ptimes); switch_core_hash_destroy(&runtime.mime_types); if (IP_LIST.hash) { diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index ba84b0301c..9b607ea873 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -137,9 +137,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_s memset(&session->read_impl, 0, sizeof(session->read_impl)); } old->next = NULL; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Restore previous codec %s:%d.\n", switch_channel_get_name(session->channel), - session->read_codec->implementation->iananame, session->read_codec->implementation->ianacode); + session->read_impl.iananame ? session->read_impl.iananame : "N/A", session->read_impl.ianacode); + } else if (session->real_read_codec) { session->read_codec = session->real_read_codec; @@ -165,6 +167,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_s switch_channel_event_set_data(session->channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-read-codec-name", session->read_impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-rate", "%d", session->read_impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-bit-rate", "%d", session->read_impl.bits_per_second); if (session->read_impl.actual_samples_per_second != session->read_impl.samples_per_second) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-reported-read-codec-rate", "%d", session->read_impl.samples_per_second); } @@ -317,6 +320,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_write_codec(switch_core_ switch_channel_event_set_data(session->channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", session->write_impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%d", session->write_impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-codec-bit-rate", "%d", session->write_impl.bits_per_second); if (session->write_impl.actual_samples_per_second != session->write_impl.samples_per_second) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Reported-Write-Codec-Rate", "%d", session->write_impl.actual_samples_per_second); @@ -448,6 +452,28 @@ SWITCH_DECLARE(switch_codec_t *) switch_core_session_get_video_write_codec(switc } +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_codec_interface_t *codec_interface; + switch_status_t status = SWITCH_STATUS_FALSE; + + if (zstr(codec_name) || zstr(fmtp) || !codec_fmtp) { + return SWITCH_STATUS_FALSE; + } + + memset(codec_fmtp, 0, sizeof(*codec_fmtp)); + + if ((codec_interface = switch_loadable_module_get_codec_interface(codec_name))) { + if (codec_interface->parse_fmtp) { + codec_fmtp->actual_samples_per_second = rate; + status = codec_interface->parse_fmtp(fmtp, codec_fmtp); + } + + UNPROTECT_INTERFACE(codec_interface); + } + + return status; +} SWITCH_DECLARE(switch_status_t) switch_core_codec_reset(switch_codec_t *codec) { @@ -494,8 +520,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, sw return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, const char *codec_name, const char *fmtp, - uint32_t rate, int ms, int channels, uint32_t flags, +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_codec_interface_t *codec_interface; @@ -519,7 +545,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, co /* If no specific codec interval is requested opt for 20ms above all else because lots of stuff assumes it */ if (!ms) { for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) { - if ((!rate || rate == iptr->samples_per_second) && + if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) && (20 == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) { implementation = iptr; goto found; @@ -529,7 +555,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, co /* Either looking for a specific interval or there was no interval specified and there wasn't one @20ms available */ for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) { - if ((!rate || rate == iptr->samples_per_second) && + if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) && (!ms || ms == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) { implementation = iptr; break; diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 1eb224bda1..4e6d2fc6a2 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -126,7 +126,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_mutex_lock(session->read_codec->mutex); top: - + + if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { + switch_ivr_dmachine_ping(session->dmachine, NULL); + } + if (switch_channel_down(session->channel) || !switch_core_codec_ready(session->read_codec)) { *frame = NULL; status = SWITCH_STATUS_FALSE; @@ -653,7 +657,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess if (session->write_impl.codec_id == frame->codec->implementation->codec_id || session->write_impl.microseconds_per_packet != frame->codec->implementation->microseconds_per_packet) { ptime_mismatch = TRUE; - if (switch_test_flag(frame->codec, SWITCH_CODEC_FLAG_PASSTHROUGH) || switch_test_flag(session->read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) { + if ((switch_test_flag(frame->codec, SWITCH_CODEC_FLAG_PASSTHROUGH) || switch_test_flag(session->read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) || + switch_channel_test_flag(session->channel, CF_PASSTHRU_PTIME_MISMATCH)) { status = perform_write(session, frame, flags, stream_id); goto error; } @@ -1149,6 +1154,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio switch_io_event_hook_recv_dtmf_t *ptr; switch_status_t status; switch_dtmf_t new_dtmf; + int fed = 0; if (switch_channel_down(session->channel)) { return SWITCH_STATUS_FALSE; @@ -1170,12 +1176,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio new_dtmf.duration = switch_core_default_dtmf_duration(0); } - for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) { - if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) { - return status; + if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)) { + if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { + char str[2] = { dtmf->digit, '\0' }; + switch_ivr_dmachine_feed(session->dmachine, str, NULL); + fed = 1; + } + + for (ptr = session->event_hooks.recv_dtmf; ptr; ptr = ptr->next) { + if ((status = ptr->recv_dtmf(session, &new_dtmf, SWITCH_DTMF_RECV)) != SWITCH_STATUS_SUCCESS) { + return status; + } } } - return SWITCH_STATUS_SUCCESS; + + return fed ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS; } SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 9e942fea5e..c8aca7dbc6 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -38,6 +38,16 @@ struct switch_session_manager session_manager; +SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine) +{ + session->dmachine = dmachine; +} + +SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session) +{ + return session->dmachine; +} + SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec) { session->soft_lock = sec; @@ -1094,6 +1104,10 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * switch_ivr_clear_speech_cache(*session); switch_channel_uninit((*session)->channel); + if ((*session)->dmachine) { + switch_ivr_dmachine_destroy(&(*session)->dmachine); + } + pool = (*session)->pool; //#ifndef NDEBUG //memset(*session, 0, sizeof(switch_core_session_t)); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index c6b7f8d970..c467a23a62 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -871,7 +871,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *threa while (sql_manager.db_thread_running == 1) { if (++sec == SQL_CACHE_TIMEOUT) { sql_close(switch_epoch_time_now(NULL)); - wake_thread(1); + wake_thread(0); sec = 0; } switch_yield(1000); @@ -911,10 +911,9 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, sql_manager.thread_running = 1; + switch_mutex_lock(sql_manager.cond_mutex); + while (sql_manager.thread_running == 1) { - - switch_mutex_lock(sql_manager.cond_mutex); - if (sql || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { @@ -993,6 +992,8 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, } } + switch_mutex_unlock(sql_manager.cond_mutex); + while (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) { free(pop); } @@ -1141,11 +1142,13 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CODEC: new_sql() = switch_mprintf - ("update channels set read_codec='%q',read_rate='%q',write_codec='%q',write_rate='%q' where uuid='%q' and hostname='%q'", + ("update channels set read_codec='%q',read_rate='%q',read_bit_rate='%q',write_codec='%q',write_rate='%q',write_bit_rate='%q' where uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "channel-read-codec-name"), switch_event_get_header_nil(event, "channel-read-codec-rate"), + switch_event_get_header_nil(event, "channel-read-codec-bit-rate"), switch_event_get_header_nil(event, "channel-write-codec-name"), switch_event_get_header_nil(event, "channel-write-codec-rate"), + switch_event_get_header_nil(event, "channel-write-codec-bit-rate"), switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); break; case SWITCH_EVENT_CHANNEL_HOLD: @@ -1422,7 +1425,7 @@ static void core_event_handler(switch_event_t *event) switch_queue_push(sql_manager.sql_queue[0], sql[i]); } sql[i] = NULL; - wake_thread(1); + wake_thread(0); } } } @@ -1470,8 +1473,10 @@ static char create_channels_sql[] = " context VARCHAR(128),\n" " read_codec VARCHAR(128),\n" " read_rate VARCHAR(32),\n" + " read_bit_rate VARCHAR(32),\n" " write_codec VARCHAR(128),\n" " write_rate VARCHAR(32),\n" + " write_bit_rate VARCHAR(32),\n" " secure VARCHAR(32),\n" " hostname VARCHAR(256),\n" " presence_id VARCHAR(4096),\n" @@ -1539,6 +1544,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ { switch_threadattr_t *thd_attr; switch_cache_db_handle_t *dbh; + uint32_t sanity = 400; sql_manager.memory_pool = pool; sql_manager.manage = manage; @@ -1611,7 +1617,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ case SCDB_TYPE_ODBC: { char *err; - switch_cache_db_test_reactive(dbh, "select call_uuid from channels", "DROP TABLE channels", create_channels_sql); + switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate from channels", "DROP TABLE channels", create_channels_sql); switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); switch_cache_db_test_reactive(dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); @@ -1678,7 +1684,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ } switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); - while (!sql_manager.thread_running) { + while (sql_manager.manage && !sql_manager.thread_running && --sanity) { switch_yield(10000); } @@ -1699,7 +1705,7 @@ void switch_core_sqldb_stop(void) switch_queue_push(sql_manager.sql_queue[0], NULL); switch_queue_push(sql_manager.sql_queue[1], NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n"); - wake_thread(1); + wake_thread(0); } sql_manager.thread_running = -1; diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 5368cdddeb..469ae18c4b 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -775,7 +775,8 @@ SWITCH_DECLARE(char *) CoreSession::read(int min_digits, int max_digits, const char *prompt_audio_file, int timeout, - const char *valid_terminators) + const char *valid_terminators, + int digit_timeout) { this_check((char *)""); sanity_check((char *)""); @@ -792,7 +793,8 @@ SWITCH_DECLARE(char *) CoreSession::read(int min_digits, } begin_allow_threads(); - switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, NULL, dtmf_buf, sizeof(dtmf_buf), timeout, valid_terminators); + switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, NULL, dtmf_buf, + sizeof(dtmf_buf), timeout, valid_terminators, (uint32_t)digit_timeout); end_allow_threads(); return dtmf_buf; @@ -806,7 +808,8 @@ SWITCH_DECLARE(char *) CoreSession::playAndGetDigits(int min_digits, char *audio_files, char *bad_input_audio_files, char *digits_regex, - const char *var_name) + const char *var_name, + int digit_timeout) { switch_status_t status; sanity_check((char *)""); @@ -824,7 +827,8 @@ SWITCH_DECLARE(char *) CoreSession::playAndGetDigits(int min_digits, var_name, dtmf_buf, sizeof(dtmf_buf), - digits_regex); + digits_regex, + (uint32_t) digit_timeout); end_allow_threads(); return dtmf_buf; diff --git a/src/switch_event.c b/src/switch_event.c index cfd6a7a139..f782c15900 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -274,7 +274,7 @@ static void *SWITCH_THREAD_FUNC switch_event_dispatch_thread(switch_thread_t *th switch_mutex_lock(EVENT_QUEUE_MUTEX); - EVENT_DISPATCH_QUEUE_RUNNING[my_id] = 1; + EVENT_DISPATCH_QUEUE_RUNNING[my_id] = 0; THREAD_COUNT--; switch_mutex_unlock(EVENT_QUEUE_MUTEX); @@ -1644,14 +1644,15 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const } p = e > endof_indup ? endof_indup : e; - if ((vval = strchr(vname, '('))) { + if ((vval = strchr(vname, '(')) || (vval = strchr(vname, ' '))) { + if (*vval == '(') br = 1; e = vval - 1; *vval++ = '\0'; while (*e == ' ') { *e-- = '\0'; } e = vval; - br = 1; + while (e && *e) { if (*e == '(') { br++; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 543e472a13..744072c145 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -224,7 +224,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen)) { + if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { switch_dtmf_t dtmf; /* @@ -232,12 +232,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { - if (!args->input_callback && !args->buf) { + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; break; } switch_channel_dequeue_dtmf(channel, &dtmf); - if (args->input_callback) { + + if (args->dmachine) { + char ds[2] = {dtmf.digit, '\0'}; + if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } else if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); } else { switch_copy_string((char *) args->buf, (void *) &dtmf, args->buflen); @@ -265,6 +271,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, break; } + if (args && args->dmachine) { + if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + if (sval && write_frame.datalen) { switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval); switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); @@ -876,7 +888,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s switch_time_t abs_started = 0, digit_started = 0; uint32_t abs_elapsed = 0, digit_elapsed = 0; - if (!args || !args->input_callback) { + if (!args) { return SWITCH_STATUS_GENERR; } @@ -917,8 +929,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s if (switch_channel_has_dtmf(channel)) { + if (!args->input_callback && !args->buf && !args->dmachine) { + status = SWITCH_STATUS_BREAK; + break; + } switch_channel_dequeue_dtmf(channel, &dtmf); - status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); + + if (args->dmachine) { + char ds[2] = {dtmf.digit, '\0'}; + if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } else if (args->input_callback) { + status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); + } + if (digit_timeout) { digit_started = switch_micro_time_now(); } @@ -943,8 +968,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s break; } + if (args && args->dmachine) { + if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + if (read_frame && args && (args->read_frame_callback)) { - if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) { + if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { break; } } @@ -1417,13 +1448,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ if (profile->callee_id_name) { switch_channel_set_variable(channel, "pre_transfer_caller_id_name", new_profile->caller_id_name); new_profile->caller_id_name = switch_core_strdup(new_profile->pool, profile->callee_id_name); - profile->callee_id_name = NULL; + profile->callee_id_name = SWITCH_BLANK_STRING; } if (profile->callee_id_number) { switch_channel_set_variable(channel, "pre_transfer_caller_id_number", new_profile->caller_id_number); new_profile->caller_id_number = switch_core_strdup(new_profile->pool, profile->callee_id_number); - profile->callee_id_number = NULL; + profile->callee_id_number = SWITCH_BLANK_STRING; } } @@ -1841,7 +1872,7 @@ SWITCH_DECLARE(int) switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channe for (; hi; hi = hi->next) { if (!zstr(hi->name) && !zstr(hi->value) && ((variable = switch_xml_add_child_d(xml, hi->name, off++)))) { char *data; - switch_size_t dlen = strlen(hi->value) * 3; + switch_size_t dlen = strlen(hi->value) * 3 + 1; if ((data = malloc(dlen))) { memset(data, 0, dlen); @@ -2257,6 +2288,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, goto done; } + if (!module_name) { + module_name = chan_lang; + } + if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { sound_path = (char *) switch_xml_attr(language, "sound_path"); } diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 4fe5732f82..9bfa27eae7 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -35,6 +35,392 @@ #include #include +struct switch_ivr_dmachine_binding { + char *digits; + int32_t key; + switch_ivr_dmachine_callback_t callback; + switch_byte_t is_regex; + void *user_data; + struct switch_ivr_dmachine_binding *next; +}; +typedef struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t; + +typedef struct { + switch_ivr_dmachine_binding_t *binding_list; + switch_ivr_dmachine_binding_t *tail; +} dm_binding_head_t; + +struct switch_ivr_dmachine { + switch_memory_pool_t *pool; + switch_byte_t my_pool; + char *name; + uint32_t digit_timeout_ms; + uint32_t input_timeout_ms; + switch_hash_t *binding_hash; + switch_ivr_dmachine_match_t match; + char digits[DMACHINE_MAX_DIGIT_LEN]; + char last_matching_digits[DMACHINE_MAX_DIGIT_LEN]; + char last_failed_digits[DMACHINE_MAX_DIGIT_LEN]; + uint32_t cur_digit_len; + uint32_t max_digit_len; + switch_time_t last_digit_time; + switch_byte_t is_match; + switch_ivr_dmachine_callback_t match_callback; + switch_ivr_dmachine_callback_t nonmatch_callback; + dm_binding_head_t *realm; + switch_ivr_dmachine_binding_t *last_matching_binding; + void *user_data; +}; + +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_ms, + uint32_t input_timeout_ms, + switch_ivr_dmachine_callback_t match_callback, + switch_ivr_dmachine_callback_t nonmatch_callback, + void *user_data) +{ + switch_byte_t my_pool = !!pool; + switch_ivr_dmachine_t *dmachine; + + if (!pool) { + switch_core_new_memory_pool(&pool); + } + + dmachine = switch_core_alloc(pool, sizeof(*dmachine)); + dmachine->pool = pool; + dmachine->my_pool = my_pool; + dmachine->digit_timeout_ms = digit_timeout_ms; + dmachine->input_timeout_ms = input_timeout_ms; + dmachine->match.dmachine = dmachine; + dmachine->name = switch_core_strdup(dmachine->pool, name); + + switch_core_hash_init(&dmachine->binding_hash, dmachine->pool); + + if (match_callback) { + dmachine->match_callback = match_callback; + } + + if (nonmatch_callback) { + dmachine->nonmatch_callback = nonmatch_callback; + } + + dmachine->user_data = user_data; + + *dmachine_p = dmachine; + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_DECLARE(void) switch_ivr_dmachine_set_digit_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t digit_timeout_ms) +{ + dmachine->digit_timeout_ms = digit_timeout_ms; +} + +SWITCH_DECLARE(void) switch_ivr_dmachine_set_input_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t input_timeout_ms) +{ + dmachine->input_timeout_ms = input_timeout_ms; +} + +SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine) +{ + switch_memory_pool_t *pool; + + if (!(dmachine && *dmachine)) return; + + pool = (*dmachine)->pool; + + switch_core_hash_destroy(&(*dmachine)->binding_hash); + + if ((*dmachine)->my_pool) { + switch_core_destroy_memory_pool(&pool); + } +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm) +{ + dm_binding_head_t *headp = switch_core_hash_find(dmachine->binding_hash, realm); + + if (headp) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Setting realm to %s\n", dmachine->name, realm); + dmachine->realm = headp; + return SWITCH_STATUS_SUCCESS; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error Setting realm to %s\n", dmachine->name, realm); + + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmachine_t *dmachine, const char *realm) +{ + if (zstr(realm)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error unknown realm: %s\n", dmachine->name, realm); + return SWITCH_STATUS_FALSE; + } + + /* pool alloc'd just ditch it and it will give back the memory when we destroy ourselves */ + switch_core_hash_delete(dmachine->binding_hash, realm); + return SWITCH_STATUS_SUCCESS; +} + +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_ivr_dmachine_binding_t *binding; + switch_size_t len; + dm_binding_head_t *headp; + + if (strlen(digits) > DMACHINE_MAX_DIGIT_LEN -1) { + return SWITCH_STATUS_FALSE; + } + + if (zstr(realm)) { + realm = "default"; + } + + if (!(headp = switch_core_hash_find(dmachine->binding_hash, realm))) { + headp = switch_core_alloc(dmachine->pool, sizeof(*headp)); + switch_core_hash_insert(dmachine->binding_hash, realm, headp); + } + + binding = switch_core_alloc(dmachine->pool, sizeof(*binding)); + + if (*digits == '~') { + binding->is_regex = 1; + digits++; + } + + binding->key = key; + binding->digits = switch_core_strdup(dmachine->pool, digits); + binding->callback = callback; + binding->user_data = user_data; + + if (headp->tail) { + headp->tail->next = binding; + } else { + headp->binding_list = binding; + } + + headp->tail = binding; + + len = strlen(digits); + + if (dmachine->realm != headp) { + switch_ivr_dmachine_set_realm(dmachine, realm); + } + + if (binding->is_regex && dmachine->max_digit_len != DMACHINE_MAX_DIGIT_LEN -1) { + dmachine->max_digit_len = DMACHINE_MAX_DIGIT_LEN -1; + } else if (len > dmachine->max_digit_len) { + dmachine->max_digit_len = (uint32_t) len; + } + + if (binding->is_regex) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: binding realm: %s regex: %s key: %.4d callback: %p data: %p\n", + dmachine->name, realm, digits, key, (void *)(intptr_t) callback, user_data); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: binding realm %s digits: %4s key: %.4d callback: %p data: %p\n", + dmachine->name, realm, digits, key, (void *)(intptr_t) callback, user_data); + } + + return SWITCH_STATUS_SUCCESS; +} + +typedef enum { + DM_MATCH_NONE, + DM_MATCH_EXACT, + DM_MATCH_PARTIAL, + DM_MATCH_BOTH +} dm_match_t; + + +static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachine, switch_bool_t is_timeout) +{ + dm_match_t best = DM_MATCH_NONE; + switch_ivr_dmachine_binding_t *bp, *exact_bp = NULL; + int exact_count = 0, partial_count = 0, both_count = 0; + + + if (!dmachine->cur_digit_len || !dmachine->realm) goto end; + + for(bp = dmachine->realm->binding_list; bp; bp = bp->next) { + + if (bp->is_regex) { + switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits); + + if (r_status == SWITCH_STATUS_SUCCESS) { + if (is_timeout) { + best = DM_MATCH_EXACT; + exact_count++; + exact_bp = bp; + break; + } + + best = DM_MATCH_PARTIAL; + partial_count++; + continue; + } + } else { + if (!exact_bp && !strcmp(bp->digits, dmachine->digits)) { + exact_bp = bp; + best = DM_MATCH_EXACT; + exact_count++; + continue; + } + + if (!strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits))) { + if (best == DM_MATCH_EXACT) { + if (is_timeout) { + best = DM_MATCH_EXACT; + exact_count++; + exact_bp = bp; + } else { + best = DM_MATCH_BOTH; + both_count++; + } + } else { + best = DM_MATCH_PARTIAL; + partial_count++; + } + break; + } + } + } + + end: + + if (!both_count && exact_bp) { + dmachine->last_matching_binding = exact_bp; + switch_set_string(dmachine->last_matching_digits, dmachine->digits); + best = DM_MATCH_EXACT; + } + + return best; + +} + +static switch_bool_t switch_ivr_dmachine_check_timeout(switch_ivr_dmachine_t *dmachine) +{ + switch_time_t now = switch_time_now(); + uint32_t timeout = dmachine->cur_digit_len ? dmachine->digit_timeout_ms : dmachine->input_timeout_ms; + + if (!dmachine->last_digit_time) dmachine->last_digit_time = now; + + if (timeout) { + if ((uint32_t)((now - dmachine->last_digit_time) / 1000) > timeout) { + return SWITCH_TRUE; + } + } + + return SWITCH_FALSE; +} + +SWITCH_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(switch_ivr_dmachine_t *dmachine) +{ + if (dmachine->is_match) { + dmachine->is_match = 0; + return &dmachine->match; + } + + return NULL; +} + +SWITCH_DECLARE(const char *) switch_ivr_dmachine_get_failed_digits(switch_ivr_dmachine_t *dmachine) +{ + + return dmachine->last_failed_digits; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p) +{ + switch_bool_t is_timeout = switch_ivr_dmachine_check_timeout(dmachine); + dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout); + switch_status_t r; + + if (zstr(dmachine->digits) && !is_timeout) { + r = SWITCH_STATUS_SUCCESS; + } else if (dmachine->cur_digit_len > dmachine->max_digit_len) { + r = SWITCH_STATUS_FALSE; + } else if (is_match == DM_MATCH_EXACT || (is_match == DM_MATCH_BOTH && is_timeout)) { + r = SWITCH_STATUS_FOUND; + + dmachine->match.match_digits = dmachine->last_matching_digits; + dmachine->match.match_key = dmachine->last_matching_binding->key; + dmachine->match.user_data = dmachine->last_matching_binding->user_data; + + if (match_p) { + *match_p = &dmachine->match; + } + + dmachine->is_match = 1; + + dmachine->match.type = DM_MATCH_POSITIVE; + + if (dmachine->last_matching_binding->callback) { + dmachine->last_matching_binding->callback(&dmachine->match); + } + + if (dmachine->match_callback) { + dmachine->match.user_data = dmachine->user_data; + dmachine->match_callback(&dmachine->match); + } + + } else if (is_timeout) { + r = SWITCH_STATUS_TIMEOUT; + } else if (dmachine->cur_digit_len == dmachine->max_digit_len) { + r = SWITCH_STATUS_NOTFOUND; + } else { + r = SWITCH_STATUS_SUCCESS; + } + + if (r != SWITCH_STATUS_FOUND && r != SWITCH_STATUS_SUCCESS) { + switch_set_string(dmachine->last_failed_digits, dmachine->digits); + dmachine->match.match_digits = dmachine->last_failed_digits; + + dmachine->match.type = DM_MATCH_NEGATIVE; + + if (dmachine->nonmatch_callback) { + dmachine->match.user_data = dmachine->user_data; + dmachine->nonmatch_callback(&dmachine->match); + } + } + + if (r != SWITCH_STATUS_SUCCESS) { + switch_ivr_dmachine_clear(dmachine); + } + + return r; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match) +{ + if (strlen(digits) + strlen(dmachine->digits) > dmachine->max_digit_len) { + return SWITCH_STATUS_FALSE; + } + + strncat(dmachine->digits, digits, dmachine->max_digit_len); + dmachine->cur_digit_len = strlen(dmachine->digits); + dmachine->last_digit_time = switch_time_now(); + + return switch_ivr_dmachine_ping(dmachine, match); +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear(switch_ivr_dmachine_t *dmachine) +{ + memset(dmachine->digits, 0, sizeof(dmachine->digits)); + dmachine->cur_digit_len = 0; + dmachine->last_digit_time = 0; + return SWITCH_STATUS_SUCCESS; +} + + #ifdef SWITCH_VIDEO_IN_THREADS struct echo_helper { switch_core_session_t *session; @@ -2214,7 +2600,7 @@ static void *SWITCH_THREAD_FUNC bcast_thread(switch_thread_t *thread, void *obj) return NULL; } -static void broadcast_in_thread(switch_core_session_t *session, const char *app, int flags) +SWITCH_DECLARE(void) switch_ivr_broadcast_in_thread(switch_core_session_t *session, const char *app, int flags) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; @@ -2319,7 +2705,7 @@ static switch_status_t meta_on_dtmf(switch_core_session_t *session, const switch switch_channel_get_name(channel), dtmf->digit, md->sr[direction].map[dval].app); if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { - broadcast_in_thread(session, md->sr[direction].map[dval].app, flags | SMF_REBRIDGE); + switch_ivr_broadcast_in_thread(session, md->sr[direction].map[dval].app, flags | SMF_REBRIDGE); } else { switch_ivr_broadcast(switch_core_session_get_uuid(session), md->sr[direction].map[dval].app, flags); } @@ -2528,7 +2914,7 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj if (status == SWITCH_STATUS_SUCCESS && switch_true(switch_channel_get_variable(channel, "asr_intercept_dtmf"))) { const char *p; - + if ((p = switch_stristr("", xmlstr))) { p += 7; } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index b317cef628..165df886fd 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -468,6 +468,10 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) continue; } + if (switch_channel_test_flag(chan_a, CF_BRIDGE_NOWRITE)) { + continue; + } + if (status != SWITCH_STATUS_BREAK && !switch_channel_test_flag(chan_a, CF_HOLD)) { if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, @@ -839,13 +843,26 @@ static switch_status_t hanguphook(switch_core_session_t *session) { switch_core_session_message_t msg = { 0 }; switch_channel_t *channel = NULL; + switch_event_t *event; + switch_channel_state_t state; channel = switch_core_session_get_channel(session); + state = switch_channel_get_state(channel); msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; msg.from = __FILE__; msg.string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE); + if (state == CS_ROUTING) { + if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { + switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR); + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_fire(&event); + } + } + } + switch_core_session_receive_message(session, &msg); switch_core_event_hook_remove_state_change(session, hanguphook); @@ -859,6 +876,7 @@ static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session const char *key; switch_core_session_message_t msg = { 0 }; switch_event_t *event = NULL; + switch_ivr_dmachine_t *dmachine; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); @@ -886,6 +904,19 @@ static switch_status_t signal_bridge_on_hibernate(switch_core_session_t *session } } + if ((dmachine = switch_core_session_get_dmachine(session))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s not hibernating due to active digit parser, semi-hibernation engaged.\n", switch_channel_get_name(channel)); + + while(switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_HIBERNATE) { + if (!switch_channel_test_flag(channel, CF_BROADCAST)) { + switch_ivr_dmachine_ping(dmachine, NULL); + } + switch_yield(20000); + } + } + + return SWITCH_STATUS_SUCCESS; } @@ -963,6 +994,12 @@ static const switch_state_handler_table_t signal_bridge_state_handlers = { /*.on_hibernate */ signal_bridge_on_hibernate }; +static void check_bridge_export(switch_channel_t *channel, switch_channel_t *peer_channel) +{ + switch_channel_process_export(peer_channel, channel, NULL, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE); + switch_channel_process_export(channel, peer_channel, NULL, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE); +} + SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t *session, switch_core_session_t *peer_session) { switch_channel_t *caller_channel = switch_core_session_get_channel(session); @@ -979,6 +1016,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * return SWITCH_STATUS_FALSE; } + check_bridge_export(caller_channel, peer_channel); + switch_channel_set_flag_recursive(caller_channel, CF_SIGNAL_BRIDGE_TTL); switch_channel_set_flag_recursive(peer_channel, CF_SIGNAL_BRIDGE_TTL); @@ -1054,7 +1093,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses return switch_ivr_signal_bridge(session, peer_session); } - + check_bridge_export(caller_channel, peer_channel); + switch_channel_set_flag_recursive(caller_channel, CF_MEDIA_BRIDGE_TTL); switch_channel_set_flag_recursive(peer_channel, CF_MEDIA_BRIDGE_TTL); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 22b26eb4e0..0b5ab77ffd 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -212,7 +212,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void status = switch_ivr_read(collect->session, len, len, - collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL); + collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL, 0); if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_TOO_SMALL) { @@ -1328,7 +1328,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess int var_block_count = 0; char *e = NULL; switch_event_t *var_event = NULL; - const char *export_vars = NULL; switch_core_new_memory_pool(&pool); @@ -1395,33 +1394,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess } switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ent_originate_aleg_uuid", switch_core_session_get_uuid(session)); - - /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */ - if (channel && (export_vars = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE))) { - char *cptmp = switch_core_session_strdup(session, export_vars); - int argc; - char *argv[256]; - switch_event_del_header(var_event, SWITCH_EXPORT_VARS_VARIABLE); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, SWITCH_EXPORT_VARS_VARIABLE, export_vars); - - if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { - int x; - - for (x = 0; x < argc; x++) { - const char *vval; - if ((vval = switch_channel_get_variable(channel, argv[x]))) { - char *vvar = argv[x]; - if (!strncasecmp(vvar, "nolocal:", 8)) { - vvar += 8; - } - switch_event_del_header(var_event, vvar); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval); - } - } - } + if (channel) { + switch_channel_process_export(channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); } - + if (vars) { /* Parse parameters specified from the dialstring */ char *var_array[1024] = { 0 }; int var_count = 0; @@ -1756,7 +1733,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess const char *cancel_key = NULL; const char *holding = NULL; const char *soft_holding = NULL; - const char *export_vars = NULL; early_state_t early_state = { 0 }; int read_packet = 0; @@ -1945,27 +1921,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } - /* A comma (,) separated list of variable names that should ne propagated from originator to originatee */ - if (caller_channel && (export_vars = switch_channel_get_variable(caller_channel, SWITCH_EXPORT_VARS_VARIABLE))) { - char *cptmp = switch_core_session_strdup(session, export_vars); - int argc; - char *argv[256]; - - if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { - int x; - - for (x = 0; x < argc; x++) { - const char *vval; - if ((vval = switch_channel_get_variable(caller_channel, argv[x]))) { - char *vvar = argv[x]; - if (!strncasecmp(vvar, "nolocal:", 8)) { - vvar += 8; - } - switch_event_del_header(var_event, vvar); - switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, vvar, vval); - } - } - } + if (caller_channel) { + switch_channel_process_export(caller_channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); } if (vars) { /* Parse parameters specified from the dialstring */ @@ -2595,6 +2552,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if ((inner_var_count = switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) { + + /* this is stupid but necessary: if the value begins with ^^ take the very next char as a delim, + increment the string to start the next char after that and replace every instance of the delim with a , */ + + if (*inner_var_array[1] == '^' && *(inner_var_array[1] + 1) == '^') { + char *iv; + char d = 0; + inner_var_array[1] += 2; + d = *inner_var_array[1]++; + + if (d) { + for(iv = inner_var_array[1]; iv && *iv; iv++) { + if (*iv == d) *iv = ','; + } + } + } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "local variable string %d = [%s=%s]\n", x, inner_var_array[0], inner_var_array[1]); diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 75ed2d6283..c99745d57c 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -493,7 +493,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; } - if ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p)) { + if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p))) { file_flags |= SWITCH_FILE_WRITE_APPEND; } @@ -613,18 +613,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se break; } - if (args && (args->input_callback || args->buf || args->buflen)) { + if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { - if (!args->input_callback && !args->buf) { + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; break; } switch_channel_dequeue_dtmf(channel, &dtmf); - if (args->input_callback) { + + if (args->dmachine) { + char ds[2] = {dtmf.digit, '\0'}; + if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } else if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); } else { *((char *) args->buf) = dtmf.digit; @@ -651,8 +657,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se break; } + if (args && args->dmachine) { + if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + if (args && (args->read_frame_callback)) { - if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) { + if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { break; } } @@ -810,28 +822,39 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi break; } + if (args && args->dmachine) { + if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } if (args && (args->read_frame_callback)) { - if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) { + if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { break; } } switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen)) { + if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { /* dtmf handler function you can hook up to be executed when a digit is dialed during gentones if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { - if (!args->input_callback && !args->buf) { + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; done = 1; break; } switch_channel_dequeue_dtmf(channel, &dtmf); - if (args->input_callback) { + + if (args->dmachine) { + char ds[2] = {dtmf.digit, '\0'}; + if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } else if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); } else { *((char *) args->buf) = dtmf.digit; @@ -841,7 +864,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi if (args->input_callback) { switch_event_t *event; - + if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); switch_event_destroy(&event); @@ -1224,19 +1247,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen)) { + if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { - if (!args->input_callback && !args->buf) { + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; done = 1; break; } switch_channel_dequeue_dtmf(channel, &dtmf); - if (args->input_callback) { + + if (args->dmachine) { + char ds[2] = {dtmf.digit, '\0'}; + if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } else if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); } else { *((char *) args->buf) = dtmf.digit; @@ -1263,7 +1292,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if (framelen > FILE_STARTSAMPLES) { framelen = FILE_STARTSAMPLES; } - memset(abuf, 0, framelen); + memset(abuf, 255, framelen); olen = ilen; do_speed = 0; } else if (fh->sp_audio_buffer && (eof || (switch_buffer_inuse(fh->sp_audio_buffer) > (switch_size_t) (framelen)))) { @@ -1276,7 +1305,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } if (bread < framelen) { - memset(abuf + bread, 0, framelen - bread); + memset(abuf + bread, 255, framelen - bread); } olen = asis ? framelen : ilen; @@ -1291,7 +1320,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } if (bread < framelen) { - memset(abuf + bread, 0, framelen - bread); + memset(abuf + bread, 255, framelen - bread); } olen = asis ? framelen : ilen; @@ -1379,10 +1408,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess last_speed = fh->speed; continue; } - + if (olen < llen) { uint8_t *dp = (uint8_t *) write_frame.data; - memset(dp + (int) olen, 0, (int) (llen - olen)); + memset(dp + (int) olen, 255, (int) (llen - olen)); olen = llen; } @@ -1405,10 +1434,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess break; } + if (args && args->dmachine) { + if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + if (args && (args->read_frame_callback)) { int ok = 1; switch_set_flag(fh, SWITCH_FILE_CALLBACK); - if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) { + if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { ok = 0; } switch_clear_flag(fh, SWITCH_FILE_CALLBACK); @@ -1441,7 +1476,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } #endif #endif - if (fh->vol) { + if (!asis && fh->vol) { switch_change_sln_volume(write_frame.data, write_frame.datalen / 2, fh->vol); } @@ -1645,7 +1680,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_channel_t *channel; switch_input_args_t args = { 0 }; @@ -1696,7 +1736,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, if ((min_digits && len < min_digits) || len < max_digits) { args.buf = digit_buffer + len; args.buflen = (uint32_t) (digit_buffer_length - len); - status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], timeout, 0, 0); + status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], + len ? digit_timeout : timeout, digit_timeout, 0); } @@ -1745,7 +1786,10 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t const char *prompt_audio_file, const char *bad_input_audio_file, const char *var_name, - char *digit_buffer, uint32_t digit_buffer_length, const char *digits_regex) + char *digit_buffer, + uint32_t digit_buffer_length, + const char *digits_regex, + uint32_t digit_timeout) { switch_channel_t *channel = switch_core_session_get_channel(session); @@ -1755,7 +1799,7 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t memset(digit_buffer, 0, digit_buffer_length); switch_channel_flush_dtmf(channel); status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, - digit_buffer, digit_buffer_length, timeout, valid_terminators); + digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout); if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) { status = SWITCH_STATUS_SUCCESS; } @@ -1910,12 +1954,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session switch_event_destroy(&event); } - if (args && (args->input_callback || args->buf || args->buflen)) { + if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback * if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { - if (!args->input_callback && !args->buf) { + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; done = 1; break; @@ -1924,7 +1968,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session status = SWITCH_STATUS_BREAK; } else { switch_channel_dequeue_dtmf(channel, &dtmf); - if (args->input_callback) { + + if (args->dmachine) { + char ds[2] = {dtmf.digit, '\0'}; + if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { + break; + } + } else if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); } else { *((char *) args->buf) = dtmf.digit; @@ -1963,9 +2013,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session break; } + if (args && args->dmachine) { + if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { + goto done; + } + } + if (args && (args->read_frame_callback)) { - if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) { - break; + if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { + goto done; } } } @@ -2029,15 +2085,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session break; } + if (args && args->dmachine) { + if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { + goto done; + } + } + if (args && (args->read_frame_callback)) { - if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) { - break; + if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { + goto done; } } } } + done: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done speaking text\n"); flags = 0; switch_core_speech_flush_tts(sh); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index d23b4226e3..7e08f71472 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -183,8 +183,9 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable if (load_interface) { for (impl = ptr->implementations; impl; impl = impl->next) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Adding Codec '%s' (%s) %dhz %dms\n", - impl->iananame, ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000); + "Adding Codec %s %d %s %dhz %dms %dbps\n", + impl->iananame, impl->ianacode, + ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000, impl->bits_per_second); if (!switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) { switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) ptr); } @@ -515,8 +516,9 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t if (load_interface) { for (impl = ptr->implementations; impl; impl = impl->next) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Deleting Codec '%s' (%s) %dhz %dms\n", - impl->iananame, ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000); + "Deleting Codec %s %d %s %dhz %dms\n", + impl->iananame, impl->ianacode, + ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000); switch_core_session_hupall_matching_var("read_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST); switch_core_session_hupall_matching_var("write_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST); if (switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) { @@ -1557,13 +1559,16 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_impleme for (hi = switch_hash_first(NULL, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, NULL, NULL, &val); codec_interface = (switch_codec_interface_t *) val; - /* Look for a 20ms implementation because it's the safest choice */ + + /* Look for the default ptime of the codec because it's the safest choice */ for (imp = codec_interface->implementations; imp; imp = imp->next) { + uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode); + if (lock && imp->microseconds_per_packet != lock) { continue; } - if (imp->microseconds_per_packet / 1000 == 20) { + if (imp->microseconds_per_packet / 1000 == (int)default_ptime) { array[i++] = imp; goto found; } @@ -1597,7 +1602,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ for (x = 0; x < preflen; x++) { char *cur, *last = NULL, *next = NULL, *name, *p, buf[256]; - uint32_t interval = 0, rate = 0; + uint32_t interval = 0, rate = 0, bit = 0; switch_copy_string(buf, prefs[x], sizeof(buf)); last = name = next = cur = buf; @@ -1617,21 +1622,24 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ interval = atoi(cur); } else if ((strchr(cur, 'k') || strchr(cur, 'h'))) { rate = atoi(cur); + } else if (strchr(cur, 'b')) { + bit = atoi(cur); } } cur = next; } if ((codec_interface = switch_loadable_module_get_codec_interface(name)) != 0) { - /* If no specific codec interval is requested opt for 20ms above all else because lots of stuff assumes it */ + /* If no specific codec interval is requested opt for the default above all else because lots of stuff assumes it */ for (imp = codec_interface->implementations; imp; imp = imp->next) { - + uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode); + if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { if (lock && imp->microseconds_per_packet != lock) { continue; } - - if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != 20) || + + if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != default_ptime) || (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval)) { continue; } @@ -1639,6 +1647,11 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ if (((!rate && (uint32_t) imp->samples_per_second != 8000) || (rate && (uint32_t) imp->samples_per_second != rate))) { continue; } + + if (bit && (uint32_t) imp->bits_per_second != bit) { + continue; + } + } @@ -1647,7 +1660,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ } - /* Either looking for a specific interval or there was no interval specified and there wasn't one @20ms available */ + /* Either looking for a specific interval or there was no interval specified and there wasn't one at the default ptime available */ for (imp = codec_interface->implementations; imp; imp = imp->next) { if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { @@ -1662,6 +1675,11 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ if (rate && (uint32_t) imp->samples_per_second != rate) { continue; } + + if (bit && (uint32_t) imp->bits_per_second != bit) { + continue; + } + } array[i++] = imp; diff --git a/src/switch_regex.c b/src/switch_regex.c index 88152f978f..38c527cc0a 100644 --- a/src/switch_regex.c +++ b/src/switch_regex.c @@ -215,7 +215,7 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c if (match_count > 0) { *partial = 0; return SWITCH_STATUS_SUCCESS; - } else if (match_count == PCRE_ERROR_PARTIAL) { + } else if (match_count == PCRE_ERROR_PARTIAL || match_count == PCRE_ERROR_BADPARTIAL) { /* yes it is already set, but the code is clearer this way */ *partial = 1; return SWITCH_STATUS_SUCCESS; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 969309ec89..66fc4cc7f3 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -239,6 +239,7 @@ struct switch_rtp { #endif switch_time_t send_time; + switch_byte_t auto_adj_used; }; struct switch_rtcp_senderinfo { @@ -1623,6 +1624,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port) { const char *err = NULL; + + if (!rtp_session->ms_per_packet) { + return SWITCH_STATUS_FALSE; + } switch_set_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP); @@ -2308,6 +2313,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ pt = 20000; } + if ((io_flags & SWITCH_IO_FLAG_NOBLOCK)) { + pt = 0; + } + poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt); if (rtp_session->dtmf_data.out_digit_dur > 0) { do_2833(rtp_session); @@ -2333,7 +2342,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - if (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { + if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) && (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO))) { return_cng_frame(); } } @@ -2356,6 +2365,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if ((other_session = switch_core_session_locate(uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); if ((other_rtp_session = switch_channel_get_private(other_channel, "__rtcp_audio_rtp_session")) && + other_rtp_session->rtcp_sock_output && switch_test_flag(other_rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { *other_rtp_session->rtcp_send_msg.body = *rtp_session->rtcp_recv_msg.body; @@ -2526,13 +2536,14 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ switch_channel_set_variable(channel, "remote_media_port", adj_port); switch_channel_set_variable(channel, "rtp_auto_adjust", "true"); } - + rtp_session->auto_adj_used = 1; switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->from_addr), 0, SWITCH_FALSE, &err); switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Correct ip/port confirmed.\n"); switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + rtp_session->auto_adj_used = 0; } } @@ -2872,6 +2883,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ return ret; } + +SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session) +{ + return rtp_session->auto_adj_used; +} + SWITCH_DECLARE(switch_size_t) switch_rtp_has_dtmf(switch_rtp_t *rtp_session) { switch_size_t has = 0; @@ -3436,7 +3453,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session, rtp_session->last_write_ts = this_ts; - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) && + if (rtp_session->rtcp_sock_output && + switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) && rtp_session->rtcp_interval && (rtp_session->stats.outbound.packet_count % rtp_session->rtcp_interval) == 0) { struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_send_msg.body; diff --git a/src/tone2wav.c b/src/tone2wav.c index 4415860802..8d4978a57c 100644 --- a/src/tone2wav.c +++ b/src/tone2wav.c @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) teletone_destroy_session(&ts); switch_core_file_close(&fh); - printf("File: %s generated.....\n\nPlease support:\nFreeSWITCH http://www.freeswitch.org\nClueCon http://www.cluecon.com\n", file); + printf("File: %s generated...\n\nPlease support:\nFreeSWITCH http://www.freeswitch.org\nClueCon http://www.cluecon.com\n", file); end: