diff --git a/Freeswitch.2008.express.sln b/Freeswitch.2008.express.sln index b4f1f60201..43cbc02d0e 100644 --- a/Freeswitch.2008.express.sln +++ b/Freeswitch.2008.express.sln @@ -9,12 +9,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Co EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Library\FreeSwitchCore.2008.vcproj", "{202D7A4E-760D-4D0E-AFA1-D7459CED30FF}" ProjectSection(ProjectDependencies) = postProject + {D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {D331904D-A00A-4694-A5A3-FCFF64AB5DBE} {8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9} {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C} {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3} {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} + {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588} {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} {6EDFEFD5-3596-4FA9-8EBA-B331547B35A3} = {6EDFEFD5-3596-4FA9-8EBA-B331547B35A3} EndProjectSection diff --git a/Freeswitch.2008.sln b/Freeswitch.2008.sln index f915005e7c..4061116d07 100644 --- a/Freeswitch.2008.sln +++ b/Freeswitch.2008.sln @@ -379,12 +379,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Co EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Library\FreeSwitchCore.2008.vcproj", "{202D7A4E-760D-4D0E-AFA1-D7459CED30FF}" ProjectSection(ProjectDependencies) = postProject + {D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {D331904D-A00A-4694-A5A3-FCFF64AB5DBE} {8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9} {89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C} {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} {F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3} {03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD} {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF} + {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588} {EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750} {6EDFEFD5-3596-4FA9-8EBA-B331547B35A3} = {6EDFEFD5-3596-4FA9-8EBA-B331547B35A3} EndProjectSection diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln index 63b3ad12f2..cfb4770b6f 100644 --- a/Freeswitch.2010.sln +++ b/Freeswitch.2010.sln @@ -709,6 +709,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_pt", "src\mod\say\m EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ldns", "libs\win32\ldns\ldns-lib\ldns-lib.2010.vcxproj", "{23B4D303-79FC-49E0-89E2-2280E7E28940}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_callcenter", "src\mod\applications\mod_callcenter\mod_callcenter.2010.vcxproj", "{47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All|Win32 = All|Win32 @@ -3633,6 +3635,19 @@ Global {23B4D303-79FC-49E0-89E2-2280E7E28940}.Release|x64.Build.0 = Release|x64 {23B4D303-79FC-49E0-89E2-2280E7E28940}.Release|x64 Setup.ActiveCfg = Release|x64 {23B4D303-79FC-49E0-89E2-2280E7E28940}.Release|x86 Setup.ActiveCfg = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|Win32.ActiveCfg = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x64.ActiveCfg = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x64.Build.0 = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x64 Setup.ActiveCfg = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.All|x86 Setup.ActiveCfg = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|Win32.ActiveCfg = Debug|Win32 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|x64.ActiveCfg = Debug|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|x64 Setup.ActiveCfg = Debug|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Debug|x86 Setup.ActiveCfg = Debug|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|Win32.ActiveCfg = Release|Win32 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|x64.ActiveCfg = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|x64 Setup.ActiveCfg = Release|x64 + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A}.Release|x86 Setup.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3680,6 +3695,7 @@ Global {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} + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A} = {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 5b6b9896ac..95c53dd128 100644 --- a/Makefile.am +++ b/Makefile.am @@ -106,7 +106,10 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src -I$(switch_srcdir)/libs/tiff- CORE_LIBS = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la +if ENABLE_SRTP +CORE_CFLAGS += -DENABLE_SRTP CORE_LIBS += libs/srtp/libsrtp.la +endif MOD_LINK = $(switch_srcdir)/libfreeswitch.la CLEANFILES = src/include/switch_version.h src/include/switch_swigable_cpp.h diff --git a/build/freeswitch.init.redhat b/build/freeswitch.init.redhat index 6fe9c43c47..b9dc3d8db5 100644 --- a/build/freeswitch.init.redhat +++ b/build/freeswitch.init.redhat @@ -15,7 +15,7 @@ . /etc/init.d/functions PROG_NAME=freeswitch -PID_FILE=${PID_FILE-/opt/freeswitch/run/freeswitch.pid} +PID_FILE=${PID_FILE-/var/run/freeswitch/freeswitch.pid} FS_USER=${FS_USER-freeswitch} FS_FILE=${FS_FILE-/opt/freeswitch/bin/freeswitch} FS_HOME=${FS_HOME-/opt/freeswitch} diff --git a/build/modules.conf.in b/build/modules.conf.in index d31bb31b76..1084461f0e 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -37,6 +37,7 @@ applications/mod_valet_parking #applications/mod_callcenter #applications/mod_fsk #applications/mod_ladspa +#applications/mod_mongo codecs/mod_g723_1 codecs/mod_amr #codecs/mod_amrwb diff --git a/build/sounds_version.txt b/build/sounds_version.txt index 20cb29cbd7..55729b1f9f 100644 --- a/build/sounds_version.txt +++ b/build/sounds_version.txt @@ -1,3 +1,3 @@ -en-us-callie 1.0.14 +en-us-callie 1.0.16 ru-RU-elena 1.0.12 diff --git a/conf/autoload_configs/cepstral.conf.xml b/conf/autoload_configs/cepstral.conf.xml new file mode 100644 index 0000000000..cf4aa92f41 --- /dev/null +++ b/conf/autoload_configs/cepstral.conf.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/conf/autoload_configs/modules.conf.xml b/conf/autoload_configs/modules.conf.xml index 14a5bc8084..96079cd227 100644 --- a/conf/autoload_configs/modules.conf.xml +++ b/conf/autoload_configs/modules.conf.xml @@ -113,7 +113,7 @@ - + diff --git a/conf/autoload_configs/mongo.conf.xml b/conf/autoload_configs/mongo.conf.xml new file mode 100644 index 0000000000..a7fdecae8d --- /dev/null +++ b/conf/autoload_configs/mongo.conf.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index d2500a6463..b0f0c53fef 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -24,6 +24,17 @@ + + + + + + diff --git a/conf/dialplan/default/01_Talking_Clock.xml b/conf/dialplan/default/01_Talking_Clock.xml new file mode 100644 index 0000000000..205132a249 --- /dev/null +++ b/conf/dialplan/default/01_Talking_Clock.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/freeswitch.xml b/conf/freeswitch.xml index 65f6e1812d..42eede31ee 100644 --- a/conf/freeswitch.xml +++ b/conf/freeswitch.xml @@ -52,14 +52,12 @@ - -
- - - - - - - + +
+ + + + +
diff --git a/conf/lang/de/de.xml b/conf/lang/de/de.xml index 5239489f75..1b44c9a1dd 100644 --- a/conf/lang/de/de.xml +++ b/conf/lang/de/de.xml @@ -1,7 +1,11 @@ - - - - + + + + + + + + diff --git a/conf/lang/de/vm/sounds.xml b/conf/lang/de/vm/sounds.xml new file mode 100644 index 0000000000..ad9dc2e136 --- /dev/null +++ b/conf/lang/de/vm/sounds.xml @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/lang/en/en.xml b/conf/lang/en/en.xml index 6bd5a7d5fb..1e23dc5d7b 100644 --- a/conf/lang/en/en.xml +++ b/conf/lang/en/en.xml @@ -1,8 +1,12 @@ - - - - - + + + + + + + + + diff --git a/conf/lang/en/ivr/sounds.xml b/conf/lang/en/ivr/sounds.xml new file mode 100644 index 0000000000..58db0a6c15 --- /dev/null +++ b/conf/lang/en/ivr/sounds.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/conf/lang/fr/fr.xml b/conf/lang/fr/fr.xml index 12bec06f20..eaf00f247e 100644 --- a/conf/lang/fr/fr.xml +++ b/conf/lang/fr/fr.xml @@ -1,8 +1,12 @@ - - - - - + + + + + + + + + diff --git a/conf/lang/he/he.xml b/conf/lang/he/he.xml index 006195bf9a..fe7c5d8a01 100644 --- a/conf/lang/he/he.xml +++ b/conf/lang/he/he.xml @@ -1,7 +1,11 @@ - - - - + + + + + + + + diff --git a/conf/lang/ru/ru.xml b/conf/lang/ru/ru.xml index 25d63b6110..686e840860 100644 --- a/conf/lang/ru/ru.xml +++ b/conf/lang/ru/ru.xml @@ -1,9 +1,13 @@ - - - - + + + + + + + + diff --git a/configure.in b/configure.in index 4ae6dc7b59..c396ffa3d6 100644 --- a/configure.in +++ b/configure.in @@ -347,6 +347,11 @@ AC_ARG_ENABLE(cpp, AM_CONDITIONAL([ENABLE_CPP],[test "${enable_cpp}" = "yes"]) +AC_ARG_ENABLE(srtp, +[AC_HELP_STRING([--disable-srtp],[build without srtp support])],[enable_srtp="$enableval"],[enable_srtp="yes"]) + +AM_CONDITIONAL([ENABLE_SRTP],[test "${enable_srtp}" = "yes"]) + AC_ARG_ENABLE(zrtp, [AS_HELP_STRING([--enable-zrtp], [Compile with zrtp Support])],,[enable_zrtp="no"]) if test "x$enable_zrtp" = "xyes" ; then @@ -583,6 +588,21 @@ if test x"$ac_cv_gcc_declaration_after_statement" = xyes; then fi CFLAGS="$saved_CFLAGS" +# Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready +# Untested modules : mod_osp mod_soundtouch mod_sangoma_codec mod_dingaling mod_opal mod_skypopen mod_h323 mod_khomp +# mod_unimrcp mod_cepstral mod_erlang_event mod_snmp mod_perl mod_java mod_managed +# +#saved_CFLAGS="$CFLAGS" +#AC_CACHE_CHECK([whether compiler supports -Wunused-but-set-variable], [ac_cv_gcc_unused_but_set_variable], [ +#CFLAGS="$CFLAGS -Wunused-but-set-variable" +#AC_TRY_COMPILE([],[return 0;],[ac_cv_gcc_unused_but_set_variable=yes],[ac_cv_gcc_unused_but_set_variable=no]) +#]) +#AC_MSG_RESULT($ac_cv_gcc_unused_but_set_variable) +#if test x"$ac_cv_gcc_unused_but_set_variable" = xyes; then +# APR_ADDTO(SWITCH_ANSI_CFLAGS, -Wunused-but-set-variable) +#fi +#CFLAGS="$saved_CFLAGS" + AC_C_BIGENDIAN(AC_DEFINE([SWITCH_BYTE_ORDER],__BIG_ENDIAN,[Big Endian]),AC_DEFINE([SWITCH_BYTE_ORDER],__LITTLE_ENDIAN,[Little Endian])) # Checks for integer size @@ -788,6 +808,7 @@ SAC_OPENSSL if test x$HAVE_OPENSSL = x1; then openssl_CFLAGS="$openssl_CFLAGS -DHAVE_OPENSSL"; + APR_ADDTO(SWITCH_AM_CFLAGS, -DHAVE_OPENSSL) fi AX_CHECK_JAVA diff --git a/debian/freeswitch-lang-de.conffiles b/debian/freeswitch-lang-de.conffiles index 34d88b70ea..5c1dded24e 100644 --- a/debian/freeswitch-lang-de.conffiles +++ b/debian/freeswitch-lang-de.conffiles @@ -1,3 +1,4 @@ /opt/freeswitch/conf/lang/de/demo/demo.xml /opt/freeswitch/conf/lang/de/de.xml /opt/freeswitch/conf/lang/de/vm/tts.xml +/opt/freeswitch/conf/lang/de/vm/sounds.xml diff --git a/debian/freeswitch-lang-de.install b/debian/freeswitch-lang-de.install index a7e326a6ad..1b33ebec72 100644 --- a/debian/freeswitch-lang-de.install +++ b/debian/freeswitch-lang-de.install @@ -1,4 +1,5 @@ opt/freeswitch/conf/lang/de/demo/demo.xml opt/freeswitch/conf/lang/de/de.xml opt/freeswitch/conf/lang/de/vm/tts.xml +/opt/freeswitch/conf/lang/de/vm/sounds.xml opt/freeswitch/mod/mod_say_de.so* diff --git a/debian/freeswitch.conffiles b/debian/freeswitch.conffiles index 20da33de15..c765625b6f 100644 --- a/debian/freeswitch.conffiles +++ b/debian/freeswitch.conffiles @@ -22,6 +22,7 @@ /opt/freeswitch/conf/autoload_configs/logfile.conf.xml /opt/freeswitch/conf/autoload_configs/memcache.conf.xml /opt/freeswitch/conf/autoload_configs/modules.conf.xml +/opt/freeswitch/conf/autoload_configs/mongo.conf.xml /opt/freeswitch/conf/autoload_configs/nibblebill.conf.xml /opt/freeswitch/conf/autoload_configs/opal.conf.xml /opt/freeswitch/conf/autoload_configs/pocketsphinx.conf.xml diff --git a/debian/freeswitch.install b/debian/freeswitch.install index 37c1407d9c..72ded2c48c 100644 --- a/debian/freeswitch.install +++ b/debian/freeswitch.install @@ -29,6 +29,7 @@ opt/freeswitch/conf/autoload_configs/local_stream.conf.xml opt/freeswitch/conf/autoload_configs/logfile.conf.xml opt/freeswitch/conf/autoload_configs/memcache.conf.xml opt/freeswitch/conf/autoload_configs/modules.conf.xml +opt/freeswitch/conf/autoload_configs/mongo.conf.xml opt/freeswitch/conf/autoload_configs/nibblebill.conf.xml opt/freeswitch/conf/autoload_configs/opal.conf.xml opt/freeswitch/conf/autoload_configs/pocketsphinx.conf.xml diff --git a/docs/ChangeLog b/docs/ChangeLog index 55bec755fc..b4e93ab05c 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -24,6 +24,7 @@ freeswitch (1.0.7) build: VS2010 libportaudio project improvements for DirectX builds and switch to build DirectX by default (r:e9e33f51/FS-3033) build: add make targets for mod_com_g729 mod_com_g729-activate mod_com_g729-install mod_com_g729-clean mod_com_g729-uninstall (r:17d52112) build: add support for bz2 to getlibs (r:b61fc396) + build: Bump callie sounds to 1.0.15 (r:c8eaef60) 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 @@ -41,6 +42,7 @@ freeswitch (1.0.7) config: docs for acl (r:57b410eb) config: add default to conf to demonstrate min-idle-cpu (r:b8b7266a) config: change min/max enforcements to >= instead of > (r:0d5fcf65) + config: Add README_IMPORTANT.txt to default configuration (r:6cd5ce72) 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 @@ -214,6 +216,35 @@ freeswitch (1.0.7) core: add limits to simo open sql handles (r:61cdf0da) core: Fix db locks affecting mod_callcenter (r:8da371c7/FS-3127) core: improve flow of dtmf through a bridge when timer is disabled (r:59da356d) + core: Fix Freeswitch crash on Debian ARM (r:a80fae92/FS-3126) + core: switch_xml: reloadxml will(should) never lock again. It will load the XML structure into a new XML structure, and just replace the currently available ROOT XML. It then the job of the last user of the switch_xml structure to free it. (r:471bd6df) + core: switch_xml: Remove commented out mmap. With the changes in the past 2 year, mmap can't really be put back in it current state. (r:34bd0e5e) + core: Fix jitterbuffer with SRTP enabled (r:069f5f7d/FS-3075) + core: this will remove the reported symptom but does not change the fact that 1khz resolution is ideal for proper performance (r:5f18ec94/FS-3168) + core: this was specific to the user channel which is not a real channel in every sense of the word as it has no running thread or any usable state changes so this new line of code in 233d3164be4412aaaf8f9f42d8042e48279a018a to wait for the state machine to stabilize before returning from originate caused an issue with user/ channels (r:88a6ac2f/FS-3170) + core: this also fixes the incorrect usage of L16 on payload 10 which may or may not break interop with other sip devices if we do it right. also added rtp_disable_byteswap variable that can be set to false to disable byteswap when a device is encountered that is incompat (including all previous version of FS up till now) (r:e657e32f/FS-3172) + core: dont calibrate clock when timerfd enabled (r:26f5ebd4) + core: fix DTMF in SRTP/ZRTP (r:fd608901/FS-3165) + core: add switch_atomic_* type and functions switch_apr.c and switch_apr.h (r:3b56c119/FS-3173) + core: improve some defaults to tune performance if you use -heavy_timer, try not using it (r:5d783134) + core: Fix api_hangup_hook with no args (r:484a397d/FS-3194) + core: allow 100 microsecond tolerance on timer loop (r:6388e03d) + core: Fix X-PREPROCESS exec to wait pid (r:dae2cb4a) + core: Ability to use mod_say with native files; native is a special case so use the extension native e.g. en.native (r:3a2e1d03/FS-3176) + core: Fix: Bridging a call to multiple legs and using leg_delay_start, legs that lost the race before the leg_delay_start time is up still get originated for a brief moment (r:c5daf80e/FS-3218) + core: Have UPNP/PMP active without opening port mappings in the router/firewall (r:008f9889/FS-3208) + core: add execute_on function so you can have execute_on_answer_1 execute_on_answer_2 execute_on_answer_3 etc (r:27c6d111) + core: do this slightly safer so we don't have the mutex locked when we exec the app (r:ef175741) + core: Fix argument parsing for tone_detect app (r:38c3a67a/FS-3229) + core: add L16 def for 32ms and allow timer matrix to drop to 1ms to support nelly (r:82e3d49f) + core: fix segfault in zrtp srtcp (r:2330b340) + core: add switch_clean_name_string util function to strip out caller id name chars that can cause issues (r:244048f8) + core: switch_core_sqldb - clear pointer on release (r:aaef33cc) + core: all [] {} and <> can be stacked and override the delim per set <><^^:>{}{^^:}{^^;}[][^^:] (r:4c4bf59e/FS-3246) + core: fix default tipping point it was too low (r:e4eade33) + core: enable optimal defaults on linux kernels that can support newer features. (r:0b51aca3) + core: Lower NAT port mapping disabled log msg from WARNING to INFO (r:973a850d) + core: Change the structure of the phrases/language system. Previously it was fxml->phrases->macros->language->macro. Changed it so fxml->languages->language->phrases->macros->macro You can have sub macros and allow you to call it login@voicemail. Change the sound-path to sound-prefix to make it constistant with the rest of freeswitch. Also allow to set a sound-prefix to a macros, so you can override it for a specific file set. You can set say-modules="en" or whatever in the 1024 get this patch to ldns ppl (r:710fc7a7/FS-3110) 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) @@ -265,6 +302,7 @@ freeswitch (1.0.7) libsofiasip: VS2010 sofia posix problem (r:46dd24c2/SFSIP-220) libsofiasip: set minimum initital sip t1 timer to 1000ms to work around race condition on retry timer firing before all the things that are supposed to be handled by the timer are set. The base resolution on this timer is 500ms, so doubling up makes sure we always hit the initial retry timer on the next run, where everything should be set. The side effect was, 1/2 the time on a request that did not get immediate response, the timer would be fired and cleared, but the action (sending retry) was never done, and a new timer was not set, causing the request to just sit zombied and never retry. A better solution would be to find and correct the race condition so the timer is never set to early and we never hit this condition. (r:20c2740c) libsofiasip: fix bad assert (r:56404641/FS-3133) + libsofiasip: lower stack and boost priority of sofia schedule thread (r:257bc9ff) libspandsp: Fixed a typo in spandsp's msvc/inttypes.h Updated sig_tone processing in spandsp to the latest, to allow moy to proceed with his signaling work. 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) @@ -272,6 +310,7 @@ freeswitch (1.0.7) 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) libspandsp: spandsp t38 fax receiving error in win XP - regression from f029f7ef (r:761cec8f/FS-2766) libspandsp: Added missing error codes when an ECM FAX is abandoned with the T30_ERR message (r:ec57dc7a) + libspandsp: Fixed a vulnerability in T.4 and T.6 processing which is similar to http://bugzilla.maptools.org/show_bug.cgi?id=2297 in libtiff. A really screwed up 2D T.4 image, or a maliciously constructed T.4 2D or T.6 image should potential run off the end of an image decoder buffer. (r:c6f67322) libstfu: add param to jb to try to recapture latency (disabled by default) (r:d59d41d7) mod_avmd: Initial check in - Advanced Voicemail Detect (r:10c6a30a) (by Eric Des Courtis) mod_avmd: Add to windows build (r:df4bd935) @@ -299,11 +338,24 @@ freeswitch (1.0.7) mod_callcenter: IMPORTANT UPDATE, DTMF during moh created an loop to reactivate MOH but got canceled right away because of pending DTMF in the queue never been cleaned. Could cause masive disk write of debug, and can cause problem to the rest of FS stability. This patch also include basic fundation for DTMF capture support for member waiting. (r:cd1982ce) mod_callcenter: force loopback_bowout=false on originate. This will need to be reworked, but should fix basic issues call to an agent using loopback (r:2e399b0b) mod_callcenter: segfault using busy-delay-time parameter (r:c6f044d5/FS-3067) + mod_callcenter: Fix a bug when an caller leave the queue from a BREAK Call (Transfer...), it doesn't think an agent answered. (r:51a531aa) + mod_callcenter: Add new CLI cmd and change some to be more standard. Patch from Francois Delawarde, thanks. (r:30dd1774) + mod_callcenter: >WARNING, some event value got removed< Adding new event time value that can then be used to calculate the Wait;Talk;Total duration of a member were on call. CC-Wait-Time CC-Talk-Time and CC-Total-Time are no longer returned. Visit the code or check the wiki for the updated variable. (r:5f233785) + mod_callcenter: Add better support when agent doesn't answer, including creating a new variable for the delay that is different than reject or busy. Thanks to Francois Delawarde (r:26303c5c) + mod_callcenter: Add better handle of failed agent, member channel getting a break, and debuging info upon leaving. Thanks to Fran?ois Delawarde (with some changes) (r:25cee255) + mod_callcenter: New Agent order Possibility: Agent order by Level and Position by agents.last_offered_call. Change the default and sequentially-by-agent-order strategy to include the longest-idle-agent. This should offer a default consistant way to go through all the agent within the same tier/position. (Before, it was left to the DB to return the order of the result) (r:dcafff20/FS-3158) + mod_callcenter: Generate per member uuid different from the member session uuid. Might fix transfer between queue. More changes are coming (r:b63a72f8) + mod_callcenter: Remove the concept of Caller for Members. Event Socket event have been changed (CC-Caller.* to CC-Member.*) Also CC-Caller-UUID is renamed to CC-Member-Session-UUID. The reason for this is you could actually put people to be call in the queue. So they are not caller per say. But they are a member of a queue. (r:40a134bd) + mod_callcenter: Reload a queue wont delete all the currently waiting members. Only a reload of the module will. (r:c5ae5de0/FS-3250) + mod_callcenter: Add a very prototype (and maybe not functional) strategy called : sequentially-by-next-agent-order. It will try to find the last agent we tried to reach, and start calling more agent after that one based on position. It will use the level for the next agent, but once that level is done, it start back at the lowest level (r:bef6f0f4) + mod_callcenter: New strategies: round-robin, random, and 'top-down' (r:2b4b23aa,r:bee247ca) mod_cdr_sqlite: initial commit (r:f625fe3b) mod_cdr_sqlite: config file for mod_cdr_sqlite (r:25bc8fe3) mod_cdr_sqlite: Drop transaction BEGIN/END around INSERT. We're only executing one command, and autocommit will automatically rollback if the INSERT fails. Sync state_handlers with mod_cdr_csv. Minor libpq fixups. (r:0f95b870) mod_celt: Bump celt to 0.10.0 (r:231fbe5e) mod_celt: update code in mod_celt to match API of 0.10.0 (r:6e4c30ea) + mod_celt: Add dependency to fix parallel builds (r:6e37a8b2) + mod_cepstral: add ability to set encoding of text (r:28738b06/FS-3001) 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 @@ -326,6 +378,7 @@ freeswitch (1.0.7) mod_commands: add uuid_buglist to fetch the current media-bugs attached to a given session uuid (r:f6eab64c) mod_commands: add recovery_refresh app and api and use it in mod_conference to send a message to the channel telling it to sync its recovery snapshot (r:650393fb) mod_commands: add moh by default to uuid_broadcast when only broadcasting to A leg use aleg arg to disable this (r:d164a797) + mod_commands: add API uuid_limit - thanks to Francois Delawarde (r:98a95016/FS-1792) 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 @@ -351,6 +404,13 @@ freeswitch (1.0.7) mod_conference: clear talk flag when you mute (r:b7419add) mod_conference: fix pthread mutex lock error and add some tab completion and help messages from cli (r:547d5393/FS-3095) mod_conference: Use the channel's sound_prefix if it's not set in the conference's config (r:0911ed74/FS-3124) + mod_conference: Add conf_uuid chan var for djbinter (Thanks Math) (r:3c9ee25a) + mod_conference: removes the existing conference transfer function and replaces it using the core transfer it also introduces a new tracking method where the same conference id is reserved for a particular member for the lifetime of the call allowing a user to transfer in and out of conferences and ivr and bridges etc and retain the same member id for the duration of that call (r:246b2195/FS-3095) + mod_conference: prevent race condition on conference join/exit (r:1552ecf5) + mod_conference: I finally tracked this down to the actual recordings generated by mod_conference. This patch delays the recording slightly to allow time for the buffer to fill up, we were riding it so closely that sometimes we would come up short and inject silence into the file to preserve time passing (r:3253bcb3/FS-3147) + mod_conference: wait for channels to come up in paging mode (r:b8063c3d) + mod_conference: Conference APIs for enabling/disabling enter/exit sounds for active conferences (r:31cebd4f/FS-3219) + mod_conference: Fix pool swelling, replaced a pool strdup that could recur with a strdup/free to avoid it (r:bcd6c3a1/FS-3137) mod_curl: use method=post when post requested (r:c6a4ddd0/FSMOD-69) mod_db: fix stack corruption (MODAPP-407) mod_dialplan_xml: Add in the INFO log the caller id number when processing a request (Currenly only show the caller name) (r:e1df5e13) @@ -360,6 +420,7 @@ freeswitch (1.0.7) mod_dingaling: Fix NULL pointer (r:e3eff816/FS-1103) mod_dingaling: fix leak in chat_send (r:eb109a85) mod_dingaling: use the login as message source when not in component mode. (chat_send) (r:58c28aab) + mod_dingaling: fix mod_dingaling/iksemel/gnutls link error when using newer autotools (r:294b0779/FS-3182) mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f) mod_distributor: Add mod_distributor to VS2010 - not built by default (r:bac79ba1) mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012) @@ -371,7 +432,14 @@ freeswitch (1.0.7) mod_dptools: Log error when there's no IVR menus configured when you call 'ivr' DP app (r:30034891) mod_dptools: reset signal_bond variable back to its original value on failed dial in att_xfer (r:330d7418) mod_dptools: Fix storage class for 'cause' in user_outgoing_channel() so that each call has its very own hangup cause (r:cb6f1ed6) + mod_dptools: transfer_on_fail note I changed the variable name to auto_cause (r:45edec4c/FS-3193) + mod_dptools: merge file_string into dptools (r:eefdb764) + mod_dptools: change mod_dptools to use the better method of fetching user xml that does not hang onto the xml root (r:e52e44e3) + mod_dptools: the intent for having the module and lang separate is for things where the same module can use different sets of sounds like en module and en-male or en-female lang (sound dirs) there was indeed a disconnect in the dialplan version of this app. Originally say was only available in phrase macros so I change the syntax of the say app so you can specify both the module and the lang absolte from the dp with something like he:he as the module name. (r:44304f49) + mod_dptools: Set the default lang if not supplied (mod_say_en) (r:5382972a/FS-3215) mod_easyroute: Fix possible segfaults and memory leak during unload, and add new setting odbc-retries (r:7fbc47f8/FS-2973) + mod_enum: switch mod_enum to use new portable in-tree version (r:2bbc37e3) + mod_enum: fix race condition between ldns configure creating ldns/util.h and mod_enum (r:87884c5c) 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) @@ -384,6 +452,8 @@ freeswitch (1.0.7) mod_event_socket: Fix small mem leaks (r:e4f90584/MODEVENT-68) mod_event_socket: Add "-ERR" to api cmd response when failure occurs (r:58759052/FS-2827) mod_event_socket: clear unique headers on event_socket filters (r:436413e0) + mod_event_socket: Unlock mutex to prevent mortuus obfirmo (r:64bc1938/FS-3156/FS-3157) + mod_event_zmq: Intitial mod_event_zmq code (r:4d554067) mod_fifo: allow multiple dtmf to exit fifo, set fifo_caller_exit_key to specify which (MODAPP-420) 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) @@ -396,6 +466,7 @@ freeswitch (1.0.7) mod_fifo: Fix crash when using fifo_destroy_after_use (r:ee562c82/FS-2879) mod_fifo: don't seg in edge case error conditions (r:9ee13b72) mod_fifo: set tracking data before enabling hooks (r:34267869) + mod_file_string: Fix segfault when using file string in conference (r:9c40e8e9/FS-3122) 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) @@ -447,10 +518,11 @@ freeswitch (1.0.7) mod_hash: use 5 seconds connection timeouts for remote connections (r:7431fbe9) mod_hash: use esl_recv_timed with a 5000ms timeout when doing api commands (r:27d8378f) mod_hash: limit_remote_thread sending invalid handle to esl_connect_timeout causing core (r:6cdd3e2a/MODAPP-446) - mod_hash: avoid scheduler caling a function on null hash during shutdown (r:8458adeb) + mod_hash: avoid scheduler calling a function on null hash during shutdown (r:8458adeb) + mod_hash: add realm filter to hash_dump db command so that you can quickly dump all entries that belong only to a specific realm without getting the whole db (r:81347126) mod_h323: initial t.38 support. remake logical channel opening. add missing param name in example config. (r:8c58074c) - mod_h323: some t.38 and lockinng improvements. replace ptrace with switch_log_printf. (r:5efe5c88) - mod_h323: add missing conf prameter (r:0b353d7a) + mod_h323: some t.38 and locking improvements. replace ptrace with switch_log_printf. (r:5efe5c88) + mod_h323: add missing conf praameter (r:0b353d7a) mod_h323: Add mod_h323 to windows (r:015bcaf6/MODENDP-301) mod_h323: move PTrace level set to FSH323EndPoint::Initialise. partially apply patch from from Peter Olsson, Remove UnLock() when TryLock() failed and DEBUG_RTP_PACKETS directiv e. (r:7b5803f7) mod_h323: set network_addr of caller profile to signaling ip address. (requested by Steven Ayre) (r:072bf5ad) @@ -459,6 +531,8 @@ freeswitch (1.0.7) mod_json_cdr: Fix segfault in mod_json_cdr.c (r:f347698a/MODEVENT-66) mod_khomp: Added mod_khomp Endpoint. (r:5fea197b) mod_khomp: Removed alternative contexts / extensions - New struct for matchs - On calls originated from an FXS branch, the Endpoint searches for a valid extension (digits sent) after the DTMF '#' or after the timeout (option fxs-digit-timeout). That search is done in the context defined in section , or if no context configured, the search is done in context defined in context-fxs. - Added "dialplan" configuration: Name of the dialplan module in use (default XML) - Group context enabled. If set, the search for a valid extension is done only in that context. - Updated documentation (r:1ef3fc9a) + mod_ladspa: Add mod_ladspa (Audio plugin framework for linux) (r:2d3d8f8d) + mod_ladspa: add string params to ladspa so you can connect files to audio ports (string params don't count towards number params) (r:b7891511) mod_lcr: Expand variables (MODAPP-418) mod_lcr: add enable_sip_redir parameter (r:70bf7a0a/MODAPP-427) mod_lcr: don't validate profiles with ${} vars since they are dynamic and we can't guess what the proper value should be (r:af33afaa) @@ -466,6 +540,8 @@ freeswitch (1.0.7) 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_lcr: properly destroy lcr object when done (r:084819a3/FS-3199) + mod_lcr: don't add routes that have no rate of the desired type (r:82e3ccf8) 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) @@ -479,6 +555,7 @@ freeswitch (1.0.7) mod_lua: Make dbh:connected accessible from Lua - thanks Grmt (r:09e6fd3f) mod_lua: Added optional core: prefix to first arg passed to freeswitch.Dbh for giving direct access to sqlite db (r:a0181479) mod_lua: expose switch_simple_email as "email" method (r:89c5f3bf/FS-3023) + mod_lua: Fix setInputCallback crash (r:c49c1fde/FS-3161) mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165) mod_managed: add additional support (r:5be58aac) mod_managed: add mono 2.8 patch file see FS-2774 (r:6a948bd9/FS-2774) @@ -495,10 +572,13 @@ freeswitch (1.0.7) mod_openzap: disable dtmf app and cmd line option (r:fb4b7f7a) mod_openzap: add enable dtmf app (r:3c95106e) mod_opus: add mod_opus (r:8f565277) + mod_opus: Use libtool archives for linking, add dependencies to fix parallel builds (r:74bbd4be) mod_osp: initial check (Open Settlement Protocol) mod_osp:Changed OSP TCP port from 1080 to 5045. (r:03abefdf) mod_portaudio: Fix inbound state (CS_ROUTING not CS_INIT) (MODENDP-302) mod_portaudio: mod_portaudio improvements and bug fixes (r:33b74ca8/FS-3006) + mod_portaudio: Add pa devlist to portaudio webapi (r:e8f10ea3) + mod_protovm: This is a very early new prototype voicemail ivr system. You need to copy the sounds.xml and make it loadale in the language folder and protovm.conf.xml inside the autoload_configs folder. Configs file will most definitly change. Once stabilized, we make it install those file by default. (r:fb549777) mod_sangoma_codec: Add sample config file mod_sangoma_codec: added load/noload options for the supported codecs mod_sangoma_codec: rename load/noload to register/noregister @@ -513,9 +593,14 @@ freeswitch (1.0.7) mod_sangoma_codec: add G722 (r:ca8c2336) mod_sangoma_codec: add siren7 32kbps (r:fcaf2677) mod_sangoma_codec: add SIREN7 24kbps (r:3acc5fdb) + mod_say: Fix crash for Say Number Pronounced with numbers of more than 9 digits (r:06bccf28/FS-3202) + mod_say_en: introduce new say_string method of doing say and use it in mod_say_en as an example. try: eval ${say_string en.gsm en current_date_time pronounced ${strepoch()}} from the cli with this patch. We can do more to centralize the say things and go back and apply it to other langs, using this method you can set the desired file ext as well which I think is a bounty.... (r:d5ef86d7) + mod_say_en: If you only tell SAY CURRENCY to say 100 it should only say 100 dollars without the "0 cents" (r:426a4e76/FS-2922) mod_say_es: fix grammar when saying dates and time (r:6bed19b2/MODAPP-429) + mod_say_he: Add Hebrew say module (r:ebd9c83e/FS-3211) 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_ru: now support say_string like mod_say_en. Now support channel variables gender,cases can be set in english and russian for example: (r:8b5ecd2f) mod_say_zh: Number reading should now be OK for the whole range of integers for Cantonese and Mandarin mod_shout: bump mod_shout to use mpg123-1.13.2 to hopefully address unwanted calls to exit() and inherit other upstream fixes (r:079f3f73) mod_silk: Fix mod_silk compliance and performance issues (r:2ddbc457/MODCODEC-20) @@ -543,6 +628,8 @@ freeswitch (1.0.7) mod_skypopen: making XEvents to works when EARLYMEDIA, and correctly manage threads death mod_skypopen: now answer a call only when directed to do it (before was trying to answer any incoming call). Lot of changes to a messy part, so maybe some problem will come out... (r:45c6c4d3) mod_skypopen: ignore early media sent by channels to be bridged before our channel is answered (r:ef14b78a) + mod_skypopen: OSS driver, refinement (r:b0a23f8e) + mod_skypopen: deleted osscuse subdir (r:4842a620) mod_snapshot: fix bad codepaths in mod_snapshot (r:844ac220) mod_sndfile: Add support for .alaw and .ulaw to mod_sndfile (r:facf09b8/MODFORM-41) mod_sndfile: return break in mod_sndfile when seek returns failure (r:564dc7e4) @@ -689,6 +776,20 @@ freeswitch (1.0.7) mod_sofia: Send BYE to endpoints that lose race even if they answered (r:8c3651fa/FS-640) mod_sofia: do not renegotiate codecs on hold re-invites (r:bfd0ba97) mod_sofia: add rtp-notimer-during-bridge (alternative to rtp-autoflush-during-bridge (r:2a35dfb5) + mod_sofia: send another presence event on calls that were cancelled from LOSE_RACE to fix winnable race in Broadsoft SCA (r:59f6654e) + mod_sofia: pass header in X-FS headers on attended transfer CID update to indicate specific situation to flip callee/caller id when targeting a 1 legged call (r:24a97292) + mod_sofia: change text of error message to be more descriptive (r:4c435ec5) + mod_sofia: Correct a problem where restarting profile would cause some profile hash entry to remain. (r:81bfe435) + mod_sofia: New Sofia API to look up the username of a given user (r:7556ec57/FS-3187) + mod_sofia: sip_authentication was not cleared after nonce expired -caused sofia_reg_internal.db grow bigger and bigger with time (r:c735e28a/FS-3190) + mod_sofia: pass failure across in T.38 passthru mode (r:31273b42) + mod_sofia: auto-aleg-full and auto-aleg-domain for from_domain field in gateway (r:fda2283b) + mod_sofia: After further review I can concede the point that we should always say partial considering how we do things. With this commit we should at least be sending separate partial updates for each existing dialog to everyone with a subscription. If we need to introduce more data, consolidate them etc. We need to do it in small chunks and keep things sane. (r:7eae7f37/FS-2877) + mod_sofia: Fix:Attended transfer with bypass media fails in various ways (r:4b706dac/FS-3227) + mod_sofia: SO, If the RFC told you to jump off a cliff......? (r:07b9186d/FS-3226) + mod_sofia: Don't assume incoming "gw" contact param is valid (prevent possible DoS) (r:2b6f7070/FS-3244) + mod_sofia: offer both avp and savp when using srtp (r:5857495e) + mod_sofia: fix race in sla (r:a4ed829d) 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) @@ -701,15 +802,22 @@ freeswitch (1.0.7) 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_spandsp: Fire event when fax is finished; indicates result of fax attempt (r:314a2a1e/FS-3004) + mod_spandsp: new option to set sip_execute_on_image to 't38_gateway self nocng' this should skip the tone detection adn go right into the gateway mode so you should be able to do only this and have it work based on remote re-invite (r:9227b538/FS-3252) + mod_spandsp: additional fix to this bug and add better fax detect code to mod_spandsp (r:7fe313cf/FS-3252) 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) mod_spidermonkey: Add session.ringReady() to check for CF_RING_READY (r:7386b9f8) mod_spy: add support for loopback endpoint (MODAPP-416) mod_spy: fix crash when session can't be located (r:c4154633/FS-2929) + mod_timer_fd: external timerfd module by Timo Ter?s (r:48b11935) + mod_timer_fd: add timerfd support to the core for now you must enable it in switch.conf.xml with the param enable-softtimer-timerfd=true later if it proves to work well we can make it on by default, please test if you have a new kernel that supports this option kernel >= 2.6.25 and libc >= 2.8 (r:10174ea6) mod_tts_commandline: fix core dump, temp file problem. flush can be called several times (FSMOD-35) mod_unimrcp: fix fortify findings for mod_unimrcp (r:336f0b4e/FSMOD-67) mod_unimrcp: fix truncated TTS (r:e37dd41e/FS-3201) + mod_unimrcp: Destroy schannel only *after* cleanup of its contents is done (r:0f17bcc5) + mod_unimrcp: add locking to mrcp dtmf generator (r:f5704114/FS-3163) + mod_unimrcp: check for NULL recog_hdr (r:478d5186/FS-3247) 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) @@ -729,19 +837,24 @@ freeswitch (1.0.7) mod_voicemail: let vmain-key and operator-key be set empty (r:de49305a) mod_voicemail: add ability to jump to a specific message (r:0f8fb4b1) mod_voicemail: vm-skip-instructions param in xml directory to disable instructions how to record a file (r:ed7e1f39) + mod_voicemail: Implement 10 new standard api function call that allow you to control fs voicemail storage system. The goal is to have a standard API set for any additional storage system we wish the voicemail to run off. Current list of added api name are : vm_fsdb_msg_count, vm_fsdb_msg_list, vm_fsdb_msg_get, vm_fsdb_msg_delete, vm_fsdb_msg_undelete, vm_fsdb_msg_purge, vm_fsdb_msg_save, vm_fsdb_pref_greeting_set, vm_fsdb_pref_recname_set, vm_fsdb_pref_password_set. (r:1f4cb488) + mod_voicemail: Adding a new voicemail fsdb api vm_fsdb_auth_login that does basic login authentication for a user (r:bfdfac5e) 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_cdr: Fix prefix-a-leg not respected for url submission (r:ea9021a2/FS-2998) + mod_xml_cdr: Fix delay to 5 sec from 5000 sec (r:34a38009/FS-2815) 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) scripts: do simple verification to make sure we are getting IP addresses from VoIP abuse blacklist (r:b0049160) scripts: add_user - cmd line utility that lets admin create new users very easily. (r:ec8f2c2b) 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) + support: update fscore_pb to work with git (r:8f67e93a) tools: Add fs_encode tool (r:89b17601) tools: Add randomize-passwords.pl script to main tree (r:5e6123ef) + tools: Change logger.pl host flag to -H from -h (conflicted w/ -h for help); add -H/--host to usage (r:73ca862c) freeswitch (1.0.6) @@ -1513,7 +1626,7 @@ freeswitch (1.0.4) build: use different version file for moh version (r:13093) build: de-couple version numbers and builds of sound files and moh files (FSBUILD-153/r:13096) build: use sound_version.txt and moh_version.txt to determine sound file version on windows (FSBUILD-152/r:13097) - build: use in tree libtiff for msvc build and fix some header generation checks (r:13150) + build: use in tree libtiff for msvc build and fix some header generation checks (r:13097) build: clean esl on make current (r:13204,13205) build: fix warning-as-error that stops MSVC from building solution (FSCORE-367/r:13301) build: fix MSVC build issue from r13294 (FSBUILD-159/r:13302) diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml index 56a8094d22..507fc7bd34 100644 --- a/docs/phrase/phrase_en.xml +++ b/docs/phrase/phrase_en.xml @@ -5,6 +5,23 @@ + + + + + + + + + + + + + + + + + @@ -222,6 +239,8 @@ + + @@ -268,6 +287,14 @@ + + + + + + + + @@ -425,17 +452,47 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/phrase/phrase_fr.xml b/docs/phrase/phrase_fr.xml index ef3ee7bb6d..2d5f488152 100644 --- a/docs/phrase/phrase_fr.xml +++ b/docs/phrase/phrase_fr.xml @@ -219,14 +219,14 @@ - + - - + + diff --git a/freeswitch-sounds-en-us-callie.spec b/freeswitch-sounds-en-us-callie.spec index c4764570f5..dabf1e45de 100644 --- a/freeswitch-sounds-en-us-callie.spec +++ b/freeswitch-sounds-en-us-callie.spec @@ -2,7 +2,7 @@ # Copyright and license ############################################################################## # -# Spec file for package freeswitch-sounds-en-us-callie (version 1.0.12-8) +# Spec file for package freeswitch-sounds-en-us-callie (version 1.0.16-8) # # Copyright (c) 2009 Patrick Laimbock # Some fixes and additions (c) 2011 Michal Bielicki @@ -20,7 +20,7 @@ # Set variables ############################################################################## -%define version 1.0.14 +%define version 1.0.16 %define release 1 %define fsname freeswitch @@ -299,6 +299,8 @@ cd %{_prefix}/sounds/en/us/callie ############################################################################## %changelog +* Sun May 22 2011 Michal Bielicki - 1.0.16-1 +- bump up version * Tue Jan 18 2011 Michal Bielicki - 1.0.14-1 - bump up version - include script into freeswitch core diff --git a/freeswitch.spec b/freeswitch.spec index 5e2ad85271..d13ae2686d 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -63,12 +63,12 @@ Vendor: http://www.freeswitch.org/ # Source files and where to get them # ###################################################################################################################### -Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2 +Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2 Source1: http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz Source2: http://files.freeswitch.org/downloads/libs/flite-1.3.99-latest.tar.gz Source3: http://files.freeswitch.org/downloads/libs/lame-3.97.tar.gz Source4: http://files.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz -Source5: http://files.freeswitch.org/downloads/libs/mpg123.tar.gz +Source5: http://files.freeswitch.org/downloads/libs/mpg123-1.13.2.tar.gz Source6: http://files.freeswitch.org/downloads/libs/openldap-2.4.11.tar.gz Source7: http://files.freeswitch.org/downloads/libs/pocketsphinx-0.5.99-20091212.tar.gz Source8: http://files.freeswitch.org/downloads/libs/soundtouch-1.3.1.tar.gz @@ -752,6 +752,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_csv.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_pg_csv.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_sqlite.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cepstral.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cidlookup.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/conference.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/console.conf.xml @@ -775,6 +776,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/logfile.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/memcache.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/modules.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/mongo.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/nibblebill.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/opal.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/osp.conf.xml @@ -1064,10 +1066,13 @@ fi %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/demo %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/vm +%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/dir +%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en/ivr %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/vm/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/dir/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/en/ivr/*.xml %{prefix}/mod/mod_say_en.so* %files lang-de @@ -1085,6 +1090,7 @@ fi %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr/demo %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr/vm +%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/fr/dir %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/fr/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/fr/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/fr/vm/*.xml @@ -1096,6 +1102,7 @@ fi %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru/demo %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru/vm +%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/ru/dir %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/vm/*.xml @@ -1107,6 +1114,7 @@ fi %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/ %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/demo %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/vm +%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/he/dir %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/he/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/he/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/he/vm/*.xml diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 2985bca2af..96cd81d349 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -839,9 +839,9 @@ static const char *basic_gets(int *cnt) } Sleep(20); } +#endif return command_buf; -#endif } #endif diff --git a/libs/esl/lua/esl_lua.2010.sln b/libs/esl/lua/esl_lua.2010.sln new file mode 100644 index 0000000000..5cdab36b1c --- /dev/null +++ b/libs/esl/lua/esl_lua.2010.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ESL", "esl_lua.2010.vcxproj", "{86B6AB99-A261-455A-9CD6-9142A5A1652E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|Win32.ActiveCfg = Debug|Win32 + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|Win32.Build.0 = Debug|Win32 + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|x64.ActiveCfg = Debug|x64 + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Debug|x64.Build.0 = Debug|x64 + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|Win32.ActiveCfg = Release|Win32 + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|Win32.Build.0 = Release|Win32 + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|x64.ActiveCfg = Release|x64 + {86B6AB99-A261-455A-9CD6-9142A5A1652E}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/esl/lua/esl_lua.2010.vcxproj b/libs/esl/lua/esl_lua.2010.vcxproj new file mode 100644 index 0000000000..99a355f95a --- /dev/null +++ b/libs/esl/lua/esl_lua.2010.vcxproj @@ -0,0 +1,178 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ESL + {86B6AB99-A261-455A-9CD6-9142A5A1652E} + esl_lua.2010 + Win32Proj + + + + DynamicLibrary + + + DynamicLibrary + + + DynamicLibrary + + + DynamicLibrary + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration)\;$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + + + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration)\;$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + + + X64 + + + Disabled + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration);$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + MachineX64 + + + + + X64 + + + $(ProjectDir)..\..\..\src\mod\languages\mod_lua\lua\;$(ProjectDir)..\src\include;%(AdditionalIncludeDirectories) + ESL_DECLARE_STATIC;WIN32;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + esl.lib;lua51.lib;ws2_32.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\$(Platform)\$(Configuration);$(ProjectDir)..\..\..\libs\esl\src\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX64 + + + + + + + + + + \ No newline at end of file diff --git a/libs/esl/lua/esl_lua.2010.vcxproj.filters b/libs/esl/lua/esl_lua.2010.vcxproj.filters new file mode 100644 index 0000000000..51644e4cdf --- /dev/null +++ b/libs/esl/lua/esl_lua.2010.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/libs/esl/perl/ESL/IVR.pm b/libs/esl/perl/ESL/IVR.pm index f7919c1b94..5dc6088236 100644 --- a/libs/esl/perl/ESL/IVR.pm +++ b/libs/esl/perl/ESL/IVR.pm @@ -73,13 +73,13 @@ sub setVar($;) { sub playAndGetDigits($;) { my $self = shift; - my ($min, $max, $tries, $to, $term, $file, $invalid_file, $var, $regex) = @_; + my ($min, $max, $tries, $to, $term, $file, $invalid_file, $var, $regex, $digit_timeout) = @_; if (!$self->{_esl}->connected()) { return undef; } - $self->execute("play_and_get_digits", "$min $max $tries $to $term $file $invalid_file $var $regex"); + $self->execute("play_and_get_digits", "$min $max $tries $to $term $file $invalid_file $var $regex $digit_timeout"); return $self->getVar($var); diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 95e9615107..bfdf58a625 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -323,7 +323,7 @@ static void default_logger(const char *file, const char *func, int line, int lev ret = esl_vasprintf(&data, fmt, ap); if (ret != -1) { - fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], file, line, func, data); + fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data); free(data); } diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index 55185cb10d..493f0da3b0 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -294,6 +294,19 @@ if test "${HAVE_SNG_SS7}" = "yes"; then fi fi + +## +# zlib (required for Sangoma SS7 Transparent IAM) +# +HAVE_ZLIB="no" +AC_MSG_RESULT([${as_nl}<<>> zlib]) +AC_CHECK_LIB([z], [compress], [HAVE_ZLIB="yes"]) +AC_MSG_RESULT([checking whether zlib is installed... ${HAVE_ZLIB}]) +AM_CONDITIONAL([HAVE_ZLIB], [test "{HAVE_ZLIB]" = "yes"]) +if test "${HAVE_ZLIB}" = "yes"; then + CFLAGS="$CFLAGS -DHAVE_ZLIB" +fi + ## # libisdn # diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 8739c4c0bf..618f2501ff 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -87,7 +87,7 @@ static struct { analog_option_t analog_options; switch_hash_t *ss7_configs; int sip_headers; - uint8_t crash_on_assert; + int crash_on_assert; } globals; /* private data attached to each fs session */ @@ -130,6 +130,10 @@ struct span_config { int limit_calls; int limit_seconds; limit_reset_event_t limit_reset_event; + /* digital codec and digital sampling rate are used to configure the codec + * when bearer capability is set to unrestricted digital */ + const char *digital_codec; + int digital_sampling_rate; chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN]; }; @@ -294,13 +298,11 @@ static void cycle_foreground(ftdm_channel_t *ftdmchan, int flash, const char *bc } } - - - -static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan) +static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data) { const char *dname = NULL; uint32_t interval = 0, srate = 8000; + uint32_t span_id; ftdm_codec_t codec; tech_pvt->ftdmchan = ftdmchan; @@ -321,6 +323,16 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses return SWITCH_STATUS_GENERR; } + span_id = ftdm_channel_get_span_id(ftdmchan); + if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED + && SPAN_CONFIG[span_id].digital_codec) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initializing digital call with codec %s at %dhz.\n", + SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate); + dname = SPAN_CONFIG[span_id].digital_codec; + srate = SPAN_CONFIG[span_id].digital_sampling_rate; + goto init_codecs; + } + if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CODEC, &codec)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n"); return SWITCH_STATUS_GENERR; @@ -349,6 +361,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses } } +init_codecs: if (switch_core_codec_init(&tech_pvt->read_codec, dname, @@ -720,7 +733,6 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc ftdm_size_t len; unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; ftdm_wait_flag_t wflags = FTDM_WRITE; - ftdm_status_t status; channel = switch_core_session_get_channel(session); assert(channel != NULL); @@ -755,7 +767,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc wflags = FTDM_WRITE; - status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10); + ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10); if (!(wflags & FTDM_WRITE)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready)\n"); @@ -1094,7 +1106,7 @@ static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t span_id = ftdm_channel_get_span_id(fchan); chan_id = ftdm_channel_get_id(fchan); - tech_init(hdata->tech_pvt, hdata->new_session, fchan); + tech_init(hdata->tech_pvt, hdata->new_session, fchan, caller_data); snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name); @@ -1299,35 +1311,83 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS"); if (sipvar) { ftdm_set_string(caller_data.rdnis.digits, sipvar); - } - - sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-TON"); - if (sipvar) { - caller_data.rdnis.type = (uint8_t)atoi(sipvar); + ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_digits", sipvar); } sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Plan"); if (sipvar) { - caller_data.rdnis.plan = (uint8_t)atoi(sipvar); + ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_plan", sipvar); } - /* Used by ftmod_sangoma_ss7 only */ sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-NADI"); if (sipvar) { ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_nadi", sipvar); } + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Screen"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_screen_ind", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Presentation"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_rdnis_pres_ind", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_digits", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NumQual"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_numqual", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NADI"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_nadi", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Screen"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_screen_ind", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Presentation"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_pres_ind", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-Plan"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_npi", sipvar); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-GN-NumInComp"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_gn_num_inc_ind", sipvar); + } + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Screen"); if (sipvar) { - caller_data.screen = (uint8_t)atoi(sipvar); + ftdm_usrmsg_add_var(&usrmsg, "ss7_screen_ind", sipvar); } sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Presentation"); if (sipvar) { - caller_data.pres = (uint8_t)atoi(sipvar); + ftdm_usrmsg_add_var(&usrmsg, "ss7_pres_ind", sipvar); } - + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CPC"); + if (sipvar) { + ftdm_set_calling_party_category(sipvar, (uint8_t *)&caller_data.cpc); + } + + sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM"); + if (sipvar) { + ftdm_usrmsg_add_var(&usrmsg, "ss7_iam", sipvar); + } } if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) { @@ -1343,19 +1403,19 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } if ((var = channel_get_variable(session, var_event, "freetdm_bearer_layer1"))) { - caller_data.bearer_layer1 = (uint8_t)atoi(var); + caller_data.bearer_layer1 = (uint8_t)atoi(var); } if ((var = channel_get_variable(session, var_event, "freetdm_screening_ind"))) { - ftdm_set_screening_ind(var, &caller_data.screen); + ftdm_set_screening_ind(var, &caller_data.screen); } if ((var = channel_get_variable(session, var_event, "freetdm_presentation_ind"))) { - ftdm_set_presentation_ind(var, &caller_data.pres); + ftdm_set_presentation_ind(var, &caller_data.pres); } if ((var = channel_get_variable(session, var_event, "freetdm_outbound_ton"))) { - ftdm_set_ton(var, &caller_data.dnis.type); + ftdm_set_ton(var, &caller_data.dnis.type); } else { caller_data.dnis.type = outbound_profile->destination_number_ton; } @@ -1400,7 +1460,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) { char *v = h->name + FREETDM_VAR_PREFIX_LEN; if (!zstr(v)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id); + if (!strcasecmp(v, "ss7_iam")) { + /* Do not print the value of ss7_iam as it is very long */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s to channel %d:%d\n", v, span_id, chan_id); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id); + } + ftdm_usrmsg_add_var(&usrmsg, v, h->value); } } @@ -1503,7 +1569,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t)); assert(tech_pvt != NULL); channel = switch_core_session_get_channel(session); - if (tech_init(tech_pvt, session, sigmsg->channel) != SWITCH_STATUS_SUCCESS) { + if (tech_init(tech_pvt, session, sigmsg->channel, channel_caller_data) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n"); switch_core_session_destroy(&session); return FTDM_FAIL; @@ -1565,9 +1631,11 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid); switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability); switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1); + switch_channel_set_variable_printf(channel, "freetdm_calling_party_category", ftdm_calling_party_category2str(channel_caller_data->cpc)); switch_channel_set_variable_printf(channel, "screening_ind", ftdm_screening2str(channel_caller_data->screen)); switch_channel_set_variable_printf(channel, "presentation_ind", ftdm_presentation2str(channel_caller_data->pres)); + if (globals.sip_headers) { switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel)); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid); @@ -1586,9 +1654,61 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-Plan", "%d", channel_caller_data->dnis.plan); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits); - switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-TON", "%d", channel_caller_data->rdnis.type); + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-NADI", "%d", channel_caller_data->rdnis.type); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan); + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", ftdm_calling_party_category2str(channel_caller_data->cpc)); + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_screen_ind"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Screen", "%d", var_value); + } + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_pres_ind"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Presentation", "%d", channel_caller_data->rdnis.plan); + } + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN", "%d", var_value); + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_numqual"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumQual", "%d", var_value); + } + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_nadi"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NADI", "%d", var_value); + } + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_screen_ind"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Screen", "%d", var_value); + } + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_pres_ind"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Presentation", "%d", var_value); + } + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_npi"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-Plan", "%d", var_value); + } + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_num_inc_ind"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumInComp", "%d", var_value); + } + } /* End - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); */ + + var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam"); + if (!ftdm_strlen_zero(var_value)) { + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM", "%s", var_value); + } + switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen); switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres); } @@ -1599,7 +1719,12 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session ftdm_get_current_var(curr, &var_name, &var_value); snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name); switch_channel_set_variable_printf(channel, name, "%s", var_value); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value); + if (!strcasecmp(var_name, "ss7_iam")) { + /* Do not print freetdm_ss7_iam as it is a very long variable */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s is present\n", name); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value); + } } ftdm_iterator_free(iter); @@ -2584,6 +2709,7 @@ static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans) /* some defaults first */ SPAN_CONFIG[span_id].limit_backend = "hash"; SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT; + SPAN_CONFIG[span_id].digital_sampling_rate = 8000; for (param = switch_xml_child(myspan, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); @@ -2598,6 +2724,21 @@ static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans) context = val; } else if (!strcasecmp(var, "dialplan")) { dialplan = val; + } else if (!strcasecmp(var, "unrestricted-digital-codec")) { + //switch_core_strdup(pool, val); + const switch_codec_implementation_t *codec = NULL; + int num_codecs; + num_codecs = switch_loadable_module_get_codecs_sorted(&codec, 1, &val, 1); + if (num_codecs != 1 || !codec) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Failed finding codec %s for unrestricted digital calls\n", val); + } else { + SPAN_CONFIG[span_id].digital_codec = switch_core_strdup(module_pool, codec->iananame); + SPAN_CONFIG[span_id].digital_sampling_rate = codec->samples_per_second; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Unrestricted digital codec is %s at %dhz for span %d\n", + SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate, span_id); + } } else if (!strcasecmp(var, "call_limit_backend")) { SPAN_CONFIG[span_id].limit_backend = val; ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id); @@ -3519,6 +3660,12 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre "physical_span_id: %u\n" "physical_chan_id: %u\n" "physical_status: %s\n" + "physical_status_red: %d\n" + "physical_status_yellow: %d\n" + "physical_status_rai: %d\n" + "physical_status_blue: %d\n" + "physical_status_ais: %d\n" + "physical_status_general: %d\n" "signaling_status: %s\n" "type: %s\n" "state: %s\n" @@ -3539,7 +3686,13 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre phspan_id, phchan_id, alarmflag ? "alarmed" : "ok", - ftdm_signaling_status2str(sigstatus), + (alarmflag & FTDM_ALARM_RED) ? 1 : 0, + (alarmflag & FTDM_ALARM_YELLOW) ? 1 : 0, + (alarmflag & FTDM_ALARM_RAI) ? 1 : 0, + (alarmflag & FTDM_ALARM_BLUE) ? 1 : 0, + (alarmflag & FTDM_ALARM_AIS) ? 1 : 0, + (alarmflag & FTDM_ALARM_GENERAL) ? 1 : 0, + ftdm_signaling_status2str(sigstatus), chan_type, state, last_state, @@ -3595,6 +3748,12 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t * " %u\n" " %u\n" " %s\n" + " %d\n" + " %d\n" + " %d\n" + " %d\n" + " %d\n" + " %d\n" " %s\n" " %s\n" " %s\n" @@ -3615,7 +3774,13 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t * phspan_id, phchan_id, alarmflag ? "alarmed" : "ok", - ftdm_signaling_status2str(sigstatus), + (alarmflag & FTDM_ALARM_RED) ? 1 : 0, + (alarmflag & FTDM_ALARM_YELLOW) ? 1 : 0, + (alarmflag & FTDM_ALARM_RAI) ? 1 : 0, + (alarmflag & FTDM_ALARM_BLUE) ? 1 : 0, + (alarmflag & FTDM_ALARM_AIS) ? 1 : 0, + (alarmflag & FTDM_ALARM_GENERAL) ? 1 : 0, + ftdm_signaling_status2str(sigstatus), chan_type, state, last_state, diff --git a/libs/freetdm/src/ftdm_call_utils.c b/libs/freetdm/src/ftdm_call_utils.c index 2b72f05b77..d23c95af4e 100644 --- a/libs/freetdm/src/ftdm_call_utils.c +++ b/libs/freetdm/src/ftdm_call_utils.c @@ -42,6 +42,74 @@ #include + + +FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len) +{ + /* This implementation of url_encode is slightly different compared to the + * Freeswitch one. This is because this implementation accepts the full + * range of values (0x00 - 0xFF) compared to the Freeswitch implementation + * that does not accept 0x00 */ + + const char *p; + size_t x = 0,y = 0; + const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}"; + const char hex[] = "0123456789ABCDEF"; + + if (!buf) { + return 0; + } + + if (!url) { + return 0; + } + + len--; + + for (p = url; y <= len; p++) { + if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) { + buf[x++] = '%'; + buf[x++] = hex[(*p >> 4) & 0x0f]; + buf[x++] = hex[*p & 0x0f]; + } else { + buf[x++] = *p; + } + y++; + } + buf[x] = '\0'; + return buf; +} + + +FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len) +{ + /* This implementation of url_decode is slightly different compared to the + * Freeswitch one. This is because this implementation accepts the full + * range of values (0x00 - 0xFF) compared to the Freeswitch implementation + * that does not accept 0x00 */ + + char *o; + unsigned int tmp; + ftdm_size_t mylen = 0; + + if (ftdm_strlen_zero(s)) { + return s; + } + + for (o = s; *s; s++, o++) { + if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) { + *o = (char) tmp; + s += 2; + } else { + *o = *s; + } + mylen++; + } + *o = '\0'; + *len = mylen; + return s; +} + FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *string, uint8_t *target) { uint8_t val; diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 1d7a0d1eb1..b57292c5b0 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -310,21 +310,6 @@ FTDM_STR2ENUM(ftdm_str2channel_indication, ftdm_channel_indication2str, ftdm_cha static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name); -static const char *cut_path(const char *in) -{ - const char *p, *ret = in; - char delims[] = "/\\"; - char *i; - - for (i = delims; *i; i++) { - p = in; - while ((p = strchr(p, *i)) != 0) { - ret = ++p; - } - } - return ret; -} - static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) { if (file && func && line && level && fmt) { @@ -350,7 +335,6 @@ static int ftdm_log_level = FTDM_LOG_LEVEL_DEBUG; static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) { - const char *fp; char data[1024]; va_list ap; @@ -360,14 +344,11 @@ static void default_logger(const char *file, const char *func, int line, int lev if (level > ftdm_log_level) { return; } - - fp = cut_path(file); va_start(ap, fmt); vsnprintf(data, sizeof(data), fmt, ap); - fprintf(stderr, "[%s] %s:%d %s() %s", FTDM_LEVEL_NAMES[level], file, line, func, data); va_end(ap); @@ -411,13 +392,13 @@ FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *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 the ec is disabled on idle, we need to enable it unless is a digital call */ - if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) { + if (caller_data->bearer_capability != FTDM_BEARER_CAP_UNRESTRICTED) { ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec for call in channel state %s\n", ftdm_channel_state2str(chan->state)); ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL); } } else { /* If the ec is enabled on idle, we do nothing unless is a digital call that needs it disabled */ - if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) { + if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) { ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec for digital call in channel state %s\n", ftdm_channel_state2str(chan->state)); ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL); } @@ -508,13 +489,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan, { ftdm_status_t err = FTDM_SUCCESS; if (!ftdmchan) { - ftdm_log(FTDM_LOG_CRIT, "Error: trying to set caller data, but no ftdmchan!\n"); + ftdm_log(FTDM_LOG_CRIT, "trying to set caller data, but no ftdmchan!\n"); return FTDM_FAIL; } if ((err = ftdm_set_caller_data(ftdmchan->span, caller_data)) != FTDM_SUCCESS) { return err; } ftdmchan->caller_data = *caller_data; + if (ftdmchan->caller_data.bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) { + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA); + } return FTDM_SUCCESS; } @@ -2628,6 +2612,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan) ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_MEDIA); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED); ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA); ftdm_mutex_lock(ftdmchan->pre_buffer_mutex); ftdm_buffer_destroy(&ftdmchan->pre_buffer); ftdmchan->pre_buffer_size = 0; @@ -3566,7 +3551,7 @@ static FIO_READ_FUNCTION(ftdm_raw_read) if (status == FTDM_SUCCESS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN) && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) { - int i = 0; + ftdm_size_t i = 0; unsigned char *rdata = data; for (i = 0; i < *datalen; i++) { rdata[i] = ftdmchan->rxgain_table[rdata[i]]; @@ -3780,6 +3765,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data handle_tone_generation(ftdmchan); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) { + goto done; + } + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) { if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) { codec_func = fio_ulaw2slin; @@ -3934,7 +3923,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); - memset(data, 255, *datalen); + memset(data, FTDM_SILENCE_VALUE(ftdmchan), *datalen); if (ftdmchan->skip_read_frames > 0) { ftdmchan->skip_read_frames--; @@ -3946,7 +3935,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data if (ftdm_buffer_inuse(ftdmchan->pre_buffer) >= ftdmchan->pre_buffer_size) { ftdm_buffer_read(ftdmchan->pre_buffer, data, *datalen); } else { - memset(data, 255, *datalen); + memset(data, FTDM_SILENCE_VALUE(ftdmchan), *datalen); } } ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex); @@ -3994,6 +3983,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat status = FTDM_FAIL; goto done; } + + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) { + goto do_write; + } if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) { if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) { @@ -4025,6 +4018,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat } } +do_write: + if (ftdmchan->span->sig_write) { status = ftdmchan->span->sig_write(ftdmchan, data, *datalen); if (status == FTDM_BREAK) { @@ -5374,10 +5369,12 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED); ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data); /* 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? - * */ + * 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); + if (sigmsg->channel->caller_data.bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) { + ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_DIGITAL_MEDIA); + } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 21008e6c96..7e230ecc34 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -426,7 +426,6 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout; uint32_t answer_on_polarity_counter = 0; ftdm_sigmsg_t sig; - ftdm_status_t status; ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n"); @@ -916,7 +915,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) } if (codec_func) { - status = codec_func(frame, sizeof(frame), &rlen); + codec_func(frame, sizeof(frame), &rlen); } else { snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!"); goto done; diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 31c2421b9b..907a8cb034 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -221,7 +221,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) ftdm_channel_t *closed_chan; uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000; ftdm_sigmsg_t sig; - ftdm_status_t status; ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread starting.\n"); @@ -545,7 +544,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) } if (codec_func) { - status = codec_func(frame, sizeof(frame), &rlen); + codec_func(frame, sizeof(frame), &rlen); } else { snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!"); goto done; diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c index a7b84ea5d8..4abddf16e1 100644 --- a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.c @@ -979,7 +979,6 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic { Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf); Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf); - uint32_t cplen = mlen; int overlap_dial = 0; int fail_cause = 0; int fail = 1; @@ -2128,7 +2127,7 @@ static int ftdm_isdn_q921_log(void *pvt, Q921LogLevel_t level, char *msg, L2INT return 0; } -static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, char *msg, L3INT size) +static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, const char *msg, L3INT size) { ftdm_span_t *span = (ftdm_span_t *) pvt; diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 6653a923aa..8093443986 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -562,14 +562,18 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) sig.chan_id = ftdm_channel_get_id(chan); sig.span_id = ftdm_channel_get_span_id(chan); sig.channel = chan; - + ftdm_channel_complete_state(chan); switch (ftdm_channel_get_state(chan)) { case FTDM_CHANNEL_STATE_DOWN: { ftdm_channel_t *chtmp = chan; - chan->call_data = NULL; + + if (call) { + pri_destroycall(isdn_data->spri.pri, call); + chan->call_data = NULL; + } if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n", @@ -776,8 +780,7 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause); // pri_destroycall(isdn_data->spri.pri, call); - - chan->call_data = NULL; +// chan->call_data = NULL; } ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); } @@ -785,10 +788,10 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: { - if (call) { - pri_destroycall(isdn_data->spri.pri, call); - chan->call_data = NULL; - } +// if (call) { +// pri_destroycall(isdn_data->spri.pri, call); +// chan->call_data = NULL; +// } ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); } break; @@ -854,7 +857,6 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even { ftdm_span_t *span = spri->span; ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel); - q931_call *call = NULL; if (!chan) { ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d %s but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel); @@ -863,27 +865,61 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even ftdm_channel_lock(chan); - if (ftdm_channel_get_state(chan) >= FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n", ftdm_channel_get_state_str(chan)); - goto done; + switch (event_type) { + case LPWRAP_PRI_EVENT_HANGUP_REQ: /* DISCONNECT */ + if (ftdm_channel_get_state(chan) >= FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n", + ftdm_channel_get_state_str(chan)); + goto done; + } + ftdm_log(FTDM_LOG_DEBUG, "-- Hangup REQ on channel %d:%d\n", + ftdm_span_get_id(spri->span), pevent->hangup.channel); + + pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause); + + chan->caller_data.hangup_cause = pevent->hangup.cause; + ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING); + break; + + case LPWRAP_PRI_EVENT_HANGUP_ACK: /* */ + ftdm_log(FTDM_LOG_DEBUG, "-- Hangup ACK on channel %d:%d\n", + ftdm_span_get_id(spri->span), pevent->hangup.channel); + + pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause); + + ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + break; + + case LPWRAP_PRI_EVENT_HANGUP: /* "RELEASE/RELEASE_COMPLETE/other" */ + ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", + ftdm_span_get_id(spri->span), pevent->hangup.channel); + + switch (ftdm_channel_get_state(chan)) { + case FTDM_CHANNEL_STATE_DIALING: + case FTDM_CHANNEL_STATE_RINGING: + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + case FTDM_CHANNEL_STATE_PROCEED: + case FTDM_CHANNEL_STATE_UP: + chan->caller_data.hangup_cause = pevent->hangup.cause; + ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING); + break; + case FTDM_CHANNEL_STATE_HANGUP: + chan->caller_data.hangup_cause = pevent->hangup.cause; + ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + break; +// case FTDM_CHANNEL_STATE_TERMINATING: +// ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP); +// break; +// case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: +// ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN); +// break; + } + break; + default: + break; } - if (!chan->call_data) { - ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s with no call data\n", ftdm_channel_get_state_str(chan)); - goto done; - } - - call = (q931_call *)chan->call_data; - - ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", ftdm_span_get_id(spri->span), pevent->hangup.channel); - - pri_release(spri->pri, call, 0); - pri_destroycall(spri->pri, call); - - chan->caller_data.hangup_cause = pevent->hangup.cause; - chan->call_data = NULL; - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING); - done: ftdm_channel_unlock(chan); return 0; @@ -1654,6 +1690,7 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj) LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_UP, on_dchan_up); LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_DOWN, on_dchan_down); LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_REQ, on_hangup); + LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_ACK, on_hangup); LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP, on_hangup); LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_INFO_RECEIVED, on_info); LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RESTART, on_restart); @@ -1928,6 +1965,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span) assert(isdn_data != NULL); memset(isdn_data, 0, sizeof(*isdn_data)); + /* set some default values */ + isdn_data->mode = PRI_CPE; + isdn_data->ton = PRI_UNKNOWN; + switch (ftdm_span_get_trunk_type(span)) { case FTDM_TRUNK_BRI: case FTDM_TRUNK_BRI_PTMP: @@ -1938,12 +1979,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span) #endif case FTDM_TRUNK_E1: ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ALAW since this is an E1/BRI/BRI PTMP trunk\n"); - isdn_data->layer1 = PRI_LAYER_1_ALAW; + isdn_data->layer1 = PRI_LAYER_1_ALAW; + isdn_data->dialect = PRI_SWITCH_EUROISDN_E1; break; case FTDM_TRUNK_T1: case FTDM_TRUNK_J1: ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ULAW since this is a T1/J1 trunk\n"); - isdn_data->layer1 = PRI_LAYER_1_ULAW; + isdn_data->layer1 = PRI_LAYER_1_ULAW; + isdn_data->dialect = PRI_SWITCH_LUCENT5E; break; default: ftdm_log(FTDM_LOG_ERROR, "Invalid trunk type: '%s'\n", ftdm_span_get_trunk_type_str(span)); diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 64d8b4fc3c..1c15f992a2 100755 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -360,11 +360,15 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call) static void ft_r2_accept_call(ftdm_channel_t *ftdmchan) { openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; - // FIXME: not always accept as no charge, let the user decide that - // also we should check the return code from openr2_chan_accept_call and handle error condition + ftdm_r2_data_t *r2data = ftdmchan->span->signal_data; + + // FIXME: we should check the return code from openr2_chan_accept_call and handle error condition // hanging up the call with protocol error as the reason, this openr2 API will fail only when there something // wrong at the I/O layer or the library itself - openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE); + if (r2data->charge_calls) + openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE); + else + openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE); } static void ft_r2_answer_call(ftdm_channel_t *ftdmchan) @@ -1697,6 +1701,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling) r2data->category = r2conf.category; r2data->allow_collect_calls = r2conf.allow_collect_calls; r2data->flags = 0; + r2data->charge_calls = r2conf.charge_calls; + r2data->forced_release = r2conf.forced_release; spanpvt->r2context = r2data->r2context; /* just the value must be freed by the hash */ @@ -1854,6 +1860,10 @@ static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) { if (!r2call->disconnect_rcvd) { openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); + /* overwrite the hangup cause if this is an incoming call and forced_release is set */ + if (openr2_chan_get_direction(r2chan) == OR2_DIR_BACKWARD && r2data->forced_release) { + disconnect_cause = OR2_CAUSE_FORCED_RELEASE; + } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause)); /* this will disconnect the call, but need to wait for the call end before moving to DOWN */ openr2_chan_disconnect_call(r2chan, disconnect_cause); 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 cd09f8606d..0cc8654f56 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 @@ -1198,9 +1198,17 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_isdn_unload) return FTDM_SUCCESS; } +#define SANGOMA_ISDN_API_USAGE_TRACE "ftdm sangoma_isdn trace \n" +#define SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS "ftdm sangoma_isdn l1_stats \n" +#define SANGOMA_ISDN_API_USAGE_SHOW_SPANS "ftdm sangoma_isdn show_spans []\n" + +#define SANGOMA_ISDN_API_USAGE "\t"SANGOMA_ISDN_API_USAGE_TRACE \ + "\t"SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS \ + "\t"SANGOMA_ISDN_API_USAGE_SHOW_SPANS + static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) { - ftdm_status_t status = FTDM_SUCCESS; + ftdm_status_t status = FTDM_EINVAL; char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; @@ -1222,7 +1230,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) ftdm_span_t *span; if (argc < 3) { - ftdm_log(FTDM_LOG_ERROR, "Usage: ftdm sangoma_isdn trace \n"); + ftdm_log(FTDM_LOG_ERROR, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_TRACE); status = FTDM_FAIL; goto done; } @@ -1231,34 +1239,40 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) status = ftdm_span_find_by_name(argv[2], &span); if (FTDM_SUCCESS != status) { stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]); + + status = FTDM_FAIL; goto done; } if (!strcasecmp(trace_opt, "q921")) { - sngisdn_activate_trace(span, SNGISDN_TRACE_Q921); + status = sngisdn_activate_trace(span, SNGISDN_TRACE_Q921); } else if (!strcasecmp(trace_opt, "q931")) { - sngisdn_activate_trace(span, SNGISDN_TRACE_Q931); + status = sngisdn_activate_trace(span, SNGISDN_TRACE_Q931); } else if (!strcasecmp(trace_opt, "disable")) { - sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE); + status = sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE); } else { stream->write_function(stream, "-ERR invalid trace option \n"); + status = FTDM_FAIL; } + goto done; } + if (!strcasecmp(argv[0], "l1_stats")) { ftdm_span_t *span; if (argc < 2) { - stream->write_function(stream, "Usage: ftdm sangoma_isdn l1_stats \n"); + stream->write_function(stream, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS); status = FTDM_FAIL; goto done; } status = ftdm_span_find_by_name(argv[1], &span); if (FTDM_SUCCESS != status) { stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]); - /* Return SUCCESS because we do not want to print the general FTDM usage list */ - status = FTDM_SUCCESS; + + status = FTDM_FAIL; goto done; } - sngisdn_print_phy_stats(stream, span); + status = sngisdn_show_l1_stats(stream, span); + goto done; } if (!strcasecmp(argv[0], "show_spans")) { @@ -1267,20 +1281,42 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) status = ftdm_span_find_by_name(argv[1], &span); if (FTDM_SUCCESS != status) { stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]); - /* Return SUCCESS because we do not want to print the general FTDM usage list */ - status = FTDM_SUCCESS; + + stream->write_function(stream, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_SHOW_SPANS); + status = FTDM_FAIL; goto done; } - sngisdn_print_span(stream, span); - status = FTDM_SUCCESS; + status = sngisdn_show_span(stream, span); goto done; } - sngisdn_print_spans(stream); + status = sngisdn_show_spans(stream); + goto done; } + if (!strcasecmp(argv[0], "check_ids")) { - sngisdn_check_free_ids(); + status = sngisdn_check_free_ids(); + goto done; + } + if (!strcasecmp(argv[0], "check_mem")) { + sngisdn_get_memory_info(); } done: + switch (status) { + case FTDM_SUCCESS: + stream->write_function(stream, "Command executed OK\n"); + break; + case FTDM_EINVAL: + stream->write_function(stream, "Invalid arguments [%s]\n", mycmd); + stream->write_function(stream, "Usage:\n%s\n", SANGOMA_ISDN_API_USAGE); + break; + default: + /* FTDM_FAIL - Do nothing since we already printed the cause of the error */ + break; + } + + /* Return SUCCESS because we do not want to print the general FTDM usage list */ + status = FTDM_SUCCESS; + ftdm_safe_free(mycmd); return status; } 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 112e7cf27d..7930a827f3 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 @@ -292,6 +292,12 @@ typedef struct ftdm_sngisdn_data { sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */ }ftdm_sngisdn_data_t; +typedef struct ftdm2trillium +{ + uint8_t ftdm_val; + uint8_t trillium_val; +}ftdm2trillium_t; + /* TODO implement these 2 functions */ #define ISDN_FUNC_TRACE_ENTER(a) @@ -388,7 +394,7 @@ void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len); -void get_memory_info(void); +void sngisdn_get_memory_info(void); ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); ftdm_status_t sngisdn_check_free_ids(void); @@ -471,9 +477,9 @@ ftdm_status_t sngisdn_stack_start(ftdm_span_t *span); ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span); ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span); -void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span); -void sngisdn_print_spans(ftdm_stream_handle_t *stream); -void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span); +ftdm_status_t sngisdn_show_l1_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span); +ftdm_status_t sngisdn_show_spans(ftdm_stream_handle_t *stream); +ftdm_status_t sngisdn_show_span(ftdm_stream_handle_t *stream, ftdm_span_t *span); #endif /* __FTMOD_SNG_ISDN_H__ */ 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 1bd2753e81..88aa9131b6 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 @@ -745,8 +745,16 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) /* TODO: Fill in these timers with proper values - eventually pass them */ cfg.t.cfg.s.inDLSAP.tmr.t301.enb = TRUE; cfg.t.cfg.s.inDLSAP.tmr.t301.val = 180; - cfg.t.cfg.s.inDLSAP.tmr.t302.enb = TRUE; - cfg.t.cfg.s.inDLSAP.tmr.t302.val = 15; + + /* It looks like ETSI is the only variant that supports Overlap */ + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { + cfg.t.cfg.s.inDLSAP.tmr.t302.enb = TRUE; + cfg.t.cfg.s.inDLSAP.tmr.t302.val = 15; + } else { + cfg.t.cfg.s.inDLSAP.tmr.t302.enb = FALSE; + cfg.t.cfg.s.inDLSAP.tmr.t302.val = 0; + } + cfg.t.cfg.s.inDLSAP.tmr.t303.enb = TRUE; cfg.t.cfg.s.inDLSAP.tmr.t303.val = 4; cfg.t.cfg.s.inDLSAP.tmr.t304.enb = TRUE; 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 b1af8a61c3..242963ec9c 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 @@ -35,6 +35,7 @@ #include "ftmod_sangoma_isdn.h" static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn); static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan); +static ftdm_status_t sngisdn_force_down(ftdm_channel_t *ftdmchan); /* Remote side transmit a SETUP */ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) @@ -191,8 +192,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) strcpy(ftdmchan->caller_data.cid_name, retrieved_str); } } -#endif - +#endif if (signal_data->overlap_dial == SNGISDN_OPT_TRUE && !conEvnt->sndCmplt.eh.pres) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); } else { @@ -831,7 +831,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) { strcpy(ftdmchan->caller_data.cid_name, retrieved_str); } else { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n"); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Failed to retrieve Caller Name from Facility IE\n"); } if (signal_data->facility_timeout) { /* Cancel facility timeout */ @@ -920,36 +920,8 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) switch(call_state) { /* Sere ITU-T Q931 for definition of call states */ case 0: /* Remote switch thinks there are no calls on this channel */ - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_COLLECT: - case FTDM_CHANNEL_STATE_DIALING: - case FTDM_CHANNEL_STATE_UP: - sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - case FTDM_CHANNEL_STATE_TERMINATING: - /* We are in the process of clearing local states, - just make sure we will not send any messages to remote switch */ - sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); - break; - case FTDM_CHANNEL_STATE_HANGUP: - /* This cannot happen, state_advance always sets - ftdmchan to STATE_HANGUP_COMPLETE when in STATE_HANGUP - and we called check_for_state_change earlier so something is very wrong here!!! */ - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "How can we we in FTDM_CHANNEL_STATE_HANGUP after checking for state change?\n"); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - /* We were waiting for remote switch to send RELEASE COMPLETE - but this will not happen, so just clear local state */ - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - break; - case FTDM_CHANNEL_STATE_DOWN: - /* If our local state is down as well, then there is nothing to do */ - 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; + if (sngisdn_force_down(ftdmchan) != FTDM_SUCCESS) { + 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; case 1: @@ -1159,6 +1131,48 @@ static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan) return; } +static ftdm_status_t sngisdn_force_down(ftdm_channel_t *ftdmchan) +{ + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; + ftdm_status_t status = FTDM_SUCCESS; + + ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Forcing channel to DOWN state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); + switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_DOWN: + /* Do nothing */ + break; + case FTDM_CHANNEL_STATE_RESET: + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + break; + case FTDM_CHANNEL_STATE_COLLECT: + case FTDM_CHANNEL_STATE_DIALING: + case FTDM_CHANNEL_STATE_UP: + sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + case FTDM_CHANNEL_STATE_TERMINATING: + /* We are already waiting for usr to respond to SIGEVENT stop. + FreeTDM already scheduled a timout in case the User does respond to + SIGEVENT_STOP, no need to do anything here */ + break; + case FTDM_CHANNEL_STATE_HANGUP: + /* This cannot happen, state_advance always sets + ftdmchan to STATE_HANGUP_COMPLETE when in STATE_HANGUP + and we called check_for_state_change earlier so something is very wrong here!!! */ + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "How can we we in FTDM_CHANNEL_STATE_HANGUP after checking for state change?\n"); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + break; + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + /* We were waiting for remote switch to send RELEASE COMPLETE + but this will not happen, so just clear local state */ + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + break; + default: + status = FTDM_FAIL; + + } + return status; +} void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) { @@ -1171,12 +1185,12 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[dChan].spans[1]; if (!signal_data) { - ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId); + ftdm_log(FTDM_LOG_CRIT, "Received RESTART CFM on unconfigured span (suId:%d)\n", suId); return; } - if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) { - ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n"); + if (rstEvnt->rstInd.eh.pres != PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres != PRSNT_NODEF) { + ftdm_log(FTDM_LOG_DEBUG, "Received RESTART, but Restart Indicator IE not present\n"); return; } @@ -1233,24 +1247,101 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event) } +/* The remote side sent us a RESTART Msg. Trillium automatically acks with RESTART ACK, but + we need to clear our call states if there is a call on this channel */ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event) { + uint8_t chan_no = 0; int16_t suId = sngisdn_event->suId; int16_t dChan = sngisdn_event->dChan; uint8_t ces = sngisdn_event->ces; uint8_t evntType = sngisdn_event->evntType; + Rst *rstEvnt = NULL; + sngisdn_span_data_t *signal_data = NULL; ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - /* Function does not require any info from ssHlEvnt struct for now */ - /*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/ - - ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d %s)\n", suId, dChan, ces, + rstEvnt = &sngisdn_event->event.rstEvnt; + + /* TODO: readjust this when NFAS is implemented as signal_data will not always be the first + * span for that d-channel */ + + signal_data = g_sngisdn_data.dchans[dChan].spans[1]; + + if (!signal_data) { + ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on unconfigured span (suId:%d)\n", suId); + return; + } + + ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART IND (suId:%u dChan:%d ces:%d %s)\n", suId, dChan, ces, (evntType == IN_LNK_DWN)?"LNK_DOWN": (evntType == IN_LNK_UP)?"LNK_UP": (evntType == IN_INDCHAN)?"b-channel": (evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures": (evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown"); + + if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) { + ftdm_log(FTDM_LOG_DEBUG, "Received RESTART IND, but Restart Indicator IE not present\n"); + return; + } + + switch(rstEvnt->rstInd.rstClass.val) { + case IN_CL_INDCHAN: /* Indicated b-channel */ + if (rstEvnt->chanId.eh.pres) { + if (rstEvnt->chanId.intType.val == IN_IT_BASIC) { + if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) { + chan_no = rstEvnt->chanId.infoChanSel.val; + } + } else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) { + if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) { + chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0]; + } + } + } + if (!chan_no) { + ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n"); + return; + } + break; + case IN_CL_SNGINT: /* Single interface */ + case IN_CL_ALLINT: /* All interfaces */ + /* In case restart class indicates all interfaces, we will duplicate + this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm, + so treat it as a single interface anyway */ + break; + default: + ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val); + return; + } + + if (chan_no) { /* For a single channel */ + if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) { + ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on invalid channel:%d\n", chan_no); + } else { + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + + chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); + if (ftdmchan->physical_chan_id == chan_no) { + sngisdn_force_down(ftdmchan); + } + } + ftdm_iterator_free(chaniter); + } + } else { /* for all channels */ + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + + chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + sngisdn_force_down((ftdm_channel_t*)ftdm_iterator_current(curr)); + } + ftdm_iterator_free(chaniter); + } + + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } 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 7b9989dd4c..d1b202e77d 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 @@ -708,7 +708,7 @@ void sngisdn_rcv_q921_ind(BdMngmt *status) void sngisdn_rcv_q931_ind(InMngmt *status) { if (status->t.usta.alarm.cause == 287) { - get_memory_info(); + sngisdn_get_memory_info(); return; } @@ -779,7 +779,6 @@ void sngisdn_rcv_cc_ind(CcMngmt *status) void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) { MsgLen mlen; - MsgLen i; int16_t j; Buffer *tmp; Data *cptr; @@ -802,7 +801,6 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) tmp = mBuf->b_cont; cptr = tmp->b_rptr; data = *cptr++; - i = 0; for(j=0;jftdm_val == ftdm_val) { + return val->trillium_val; + } + } + return default_val; +} + +static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val) +{ + ftdm2trillium_t *val = vals; + while(val++) { + if (val->trillium_val == trillium_val) { + return val->ftdm_val; + } + } + return default_val; +} + void clear_call_data(sngisdn_chan_data_t *sngisdn_info) { @@ -259,11 +302,11 @@ ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) } if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) { - caller_data->dnis.plan = cdPtyNmb->nmbPlanId.val; + caller_data->dnis.plan = get_ftdm_val(npi_codes, cdPtyNmb->nmbPlanId.val, IN_NP_UNK); } if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) { - caller_data->dnis.type = cdPtyNmb->typeNmb0.val; + caller_data->dnis.type = get_ftdm_val(ton_codes, cdPtyNmb->typeNmb0.val, IN_TON_UNK); } if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) { @@ -283,11 +326,11 @@ ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb) } if (redirNmb->nmbPlanId.pres == PRSNT_NODEF) { - caller_data->rdnis.plan = redirNmb->nmbPlanId.val; + caller_data->rdnis.plan = get_ftdm_val(npi_codes, redirNmb->nmbPlanId.val, IN_NP_UNK); } if (redirNmb->typeNmb.pres == PRSNT_NODEF) { - caller_data->rdnis.type = redirNmb->typeNmb.val; + caller_data->rdnis.type = get_ftdm_val(ton_codes, redirNmb->typeNmb.val, IN_TON_UNK); } if (redirNmb->nmbDigits.pres == PRSNT_NODEF) { @@ -382,11 +425,13 @@ ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8 ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd) { uint8_t val; + if (!progInd->eh.pres) { return FTDM_FAIL; } if (progInd->progDesc.pres) { + /* TODO: use get_ftdm_val function and table here */ switch (progInd->progDesc.val) { case IN_PD_NOTETEISDN: val = SNGISDN_PROGIND_DESCR_NETE_ISDN; @@ -464,19 +509,11 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) cgPtyNmb->presInd0.val = caller_data->pres; cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF; - if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) { - cgPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN; - } else { - cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan; - } + cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->cid_num.plan, IN_NP_UNK); cgPtyNmb->typeNmb1.pres = PRSNT_NODEF; - if (caller_data->cid_num.type >= FTDM_TON_INVALID) { - cgPtyNmb->typeNmb1.val = FTDM_TON_UNKNOWN; - } else { - cgPtyNmb->typeNmb1.val = caller_data->cid_num.type; - } + cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, caller_data->cid_num.type, IN_TON_UNK); cgPtyNmb->nmbDigits.pres = PRSNT_NODEF; cgPtyNmb->nmbDigits.len = len; @@ -510,7 +547,7 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) val = FTDM_SCREENING_INVALID; string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.screening_ind"); - if ((string != NULL) && (*string)) { + if (!ftdm_strlen_zero(string)) { val = ftdm_str2ftdm_screening(string); } @@ -527,7 +564,7 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) val = FTDM_PRES_INVALID; string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.presentation_ind"); - if ((string != NULL) && (*string)) { + if (!ftdm_strlen_zero(string)) { val = ftdm_str2ftdm_presentation(string); } @@ -542,14 +579,14 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) val = FTDM_NPI_INVALID; string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.npi"); - if ((string != NULL) && (*string)) { + if (!ftdm_strlen_zero(string)) { val = ftdm_str2ftdm_npi(string); } if (val == FTDM_NPI_INVALID) { cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan; } else { - cgPtyNmb->nmbPlanId.val = val; + cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, val, IN_NP_UNK); } cgPtyNmb->typeNmb1.pres = PRSNT_NODEF; @@ -557,14 +594,14 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) /* Type of Number */ val = FTDM_TON_INVALID; string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.ton"); - if ((string != NULL) && (*string)) { + if (!ftdm_strlen_zero(string)) { val = ftdm_str2ftdm_ton(string); } if (val == FTDM_TON_INVALID) { cgPtyNmb->typeNmb1.val = caller_data->cid_num.type; } else { - cgPtyNmb->typeNmb1.val = val; + cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, val, IN_TON_UNK); } return FTDM_SUCCESS; } @@ -577,21 +614,14 @@ ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) if (!len) { return FTDM_SUCCESS; } - cdPtyNmb->eh.pres = PRSNT_NODEF; - - cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF; - if (caller_data->dnis.plan >= FTDM_NPI_INVALID) { - cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN; - } else { - cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan; - } - cdPtyNmb->typeNmb0.pres = PRSNT_NODEF; - if (caller_data->dnis.type >= FTDM_TON_INVALID) { - cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN; - } else { - cdPtyNmb->typeNmb0.val = caller_data->dnis.type; - } + cdPtyNmb->eh.pres = PRSNT_NODEF; + + cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF; + cdPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->dnis.plan, IN_NP_UNK); + + cdPtyNmb->typeNmb0.pres = PRSNT_NODEF; + cdPtyNmb->typeNmb0.val = get_trillium_val(ton_codes, caller_data->dnis.type, IN_TON_UNK); cdPtyNmb->nmbDigits.pres = PRSNT_NODEF; cdPtyNmb->nmbDigits.len = len; @@ -612,18 +642,10 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb) redirNmb->eh.pres = PRSNT_NODEF; redirNmb->nmbPlanId.pres = PRSNT_NODEF; - if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) { - redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN; - } else { - redirNmb->nmbPlanId.val = caller_data->rdnis.plan; - } + redirNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->rdnis.plan, IN_NP_UNK); redirNmb->typeNmb.pres = PRSNT_NODEF; - if (caller_data->rdnis.type >= FTDM_TON_INVALID) { - redirNmb->typeNmb.val = FTDM_TON_UNKNOWN; - } else { - redirNmb->typeNmb.val = caller_data->rdnis.type; - } + redirNmb->typeNmb.val = get_trillium_val(ton_codes, caller_data->rdnis.type, IN_TON_UNK); redirNmb->nmbDigits.pres = PRSNT_NODEF; redirNmb->nmbDigits.len = len; @@ -743,7 +765,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s int loc = prog_ind.loc; str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.descr"); - if (str && *str) { + if (!ftdm_strlen_zero(str)) { /* User wants to override progress indicator */ descr = ftdm_str2ftdm_sngisdn_progind_descr(str); } @@ -754,7 +776,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s } str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.loc"); - if (str && *str) { + if (!ftdm_strlen_zero(str)) { loc = ftdm_str2ftdm_sngisdn_progind_loc(str); } if (loc == SNGISDN_PROGIND_LOC_INVALID) { @@ -1062,25 +1084,27 @@ ftdm_status_t sngisdn_check_free_ids(void) return FTDM_SUCCESS; } -void get_memory_info(void) +void sngisdn_get_memory_info(void) { U32 availmen = 0; SRegInfoShow(S_REG, &availmen); return; } + uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability) { switch(bearer_capability) { case FTDM_BEARER_CAP_SPEECH: return IN_ITC_SPEECH; - case FTDM_BEARER_CAP_64K_UNRESTRICTED: + case FTDM_BEARER_CAP_UNRESTRICTED: return IN_ITC_UNRDIG; case FTDM_BEARER_CAP_3_1KHZ_AUDIO: return IN_ITC_A31KHZ; case FTDM_BEARER_CAP_INVALID: return IN_ITC_SPEECH; - /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */ + default: + return IN_ITC_SPEECH; } return FTDM_BEARER_CAP_SPEECH; } @@ -1096,7 +1120,8 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_pro return IN_UIL1_G711ALAW; case FTDM_USER_LAYER1_PROT_INVALID: return IN_UIL1_G711ULAW; - /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */ + default: + return IN_UIL1_G711ULAW; } return IN_UIL1_G711ULAW; } @@ -1105,9 +1130,9 @@ ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability) { switch(bearer_capability) { case IN_ITC_SPEECH: - return FTDM_BEARER_CAP_SPEECH; + return FTDM_BEARER_CAP_SPEECH; case IN_ITC_UNRDIG: - return FTDM_BEARER_CAP_64K_UNRESTRICTED; + return FTDM_BEARER_CAP_UNRESTRICTED; case IN_ITC_A31KHZ: return FTDM_BEARER_CAP_3_1KHZ_AUDIO; default: @@ -1131,7 +1156,7 @@ ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_stack(uint8_t layer1_pr return FTDM_USER_LAYER1_PROT_ULAW; } -void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span) +ftdm_status_t sngisdn_show_l1_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span) { L1Mngmt sts; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; @@ -1169,11 +1194,11 @@ void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span) stream->write_function(stream, " TX Errors Details"); stream->write_function(stream, "\n---------------------------------------------------------------------\n"); stream->write_function(stream, "Aborted:\t%u\tFifo:\t\t%u\tCarrier:\t%u\n", sts.t.sts.tx_aborted_errors, sts.t.sts.tx_fifo_errors, sts.t.sts.tx_carrier_errors); - return; + return FTDM_SUCCESS; } -void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span) +ftdm_status_t sngisdn_show_span(ftdm_stream_handle_t *stream, ftdm_span_t *span) { ftdm_signaling_status_t sigstatus; ftdm_alarm_flag_t alarmbits; @@ -1188,18 +1213,18 @@ void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span) stream->write_function(stream, "span:%s physical:%s signalling:%s\n", span->name, alarmbits ? "ALARMED" : "OK", ftdm_signaling_status2str(sigstatus)); - return; + return FTDM_SUCCESS; } -void sngisdn_print_spans(ftdm_stream_handle_t *stream) +ftdm_status_t sngisdn_show_spans(ftdm_stream_handle_t *stream) { int i; for(i=1;i<=MAX_L1_LINKS;i++) { if (g_sngisdn_data.spans[i]) { - sngisdn_print_span(stream, g_sngisdn_data.spans[i]->ftdm_span); + sngisdn_show_span(stream, g_sngisdn_data.spans[i]->ftdm_span); } } - return; + return FTDM_SUCCESS; } ftdm_status_t sngisdn_add_var(sngisdn_chan_data_t *sngisdn_info, const char* var, const char* val) 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 31994c7c6e..f44f1032a3 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 @@ -334,11 +334,12 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset switch(ieId) { case PROT_Q931_IE_BEARER_CAP: { - uint8_t codingStandard, infTransferCap, transferMode, infTransferRate, usrL1Prot; + uint8_t codingStandard, infTransferCap, infTransferRate, usrL1Prot; + /*uint8_t transferMode;*/ codingStandard = get_bits(OCTET(3),6,7); infTransferCap = get_bits(OCTET(3),1,5); - transferMode = get_bits(OCTET(4),6,7); + /*transferMode = get_bits(OCTET(4),6,7);*/ infTransferRate = get_bits(OCTET(4),1,5); usrL1Prot = get_bits(OCTET(5),1,5); @@ -404,8 +405,9 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset uint8_t infoChannelSelection=0; uint8_t prefExclusive=0; uint8_t ifaceIdPresent=0; - uint8_t ifaceIdentifier = 0; /* octet_3_1 */ - uint8_t chanType=0, numberMap=0, codingStandard=0; + /* uint8_t ifaceIdentifier = 0; */ /* octet_3_1 */ + uint8_t chanType=0, numberMap=0; + /* uint8_t codingStandard=0; */ uint8_t channelNo = 0; infoChannelSelection = get_bits(OCTET(3),1,2); @@ -413,15 +415,15 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset ifaceIdPresent = get_bits(OCTET(3),7,7); if (ifaceIdPresent) { - ifaceIdentifier= get_bits(OCTET(4),1,7); + /*ifaceIdentifier= get_bits(OCTET(4),1,7);*/ chanType = get_bits(OCTET(5),1,4); numberMap = get_bits(OCTET(5),5,5); - codingStandard = get_bits(OCTET(5),6,7); + /*codingStandard = get_bits(OCTET(5),6,7);*/ channelNo = get_bits(OCTET(6),1,7); } else { chanType = get_bits(OCTET(4),1,4); numberMap = get_bits(OCTET(4),5,5); - codingStandard = get_bits(OCTET(4),6,7); + /*codingStandard = get_bits(OCTET(4),6,7);*/ channelNo = get_bits(OCTET(5),1,7); } @@ -755,7 +757,7 @@ void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_ { uint32_t k; *str_len += sprintf(&str[*str_len], " [ "); - for(k=index_start; k <= index_end; k++) { + for(k=index_start; k < index_end; k++) { if (k && !(k%32)) { *str_len += sprintf(&str[*str_len], "\n "); } 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 40a712f8e2..0520e9d163 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 @@ -33,12 +33,14 @@ /* INCLUDE ********************************************************************/ #include "ftmod_sangoma_ss7_main.h" + /******************************************************************************/ /* DEFINES ********************************************************************/ /******************************************************************************/ /* GLOBALS ********************************************************************/ + /******************************************************************************/ /* PROTOTYPES *****************************************************************/ @@ -79,14 +81,14 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ /******************************************************************************/ /* FUNCTIONS ******************************************************************/ + ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt) { - SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; char nadi[2]; - + + SS7_FUNC_TRACE_ENTER(__FUNCTION__); memset(nadi, '\0', sizeof(nadi)); /* get the ftdmchan and ss7_chan_data from the circuit */ @@ -185,17 +187,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " "); } - /* fill in rdnis information*/ - if (siConEvnt->redirgNum.eh.pres) { - if (siConEvnt->redirgNum.addrSig.pres) { - /* fill in the rdnis digits */ - copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig, - ftdmchan->caller_data.rdnis.digits, - siConEvnt->cgPtyNum.oddEven); - } - } else { - SS7_DEBUG_CHAN(ftdmchan,"No RDNIS party information in IAM!%s\n", " "); - } + copy_redirgNum_from_sngss7(ftdmchan, &siConEvnt->redirgNum); + + copy_genNmb_from_sngss7(ftdmchan, &siConEvnt->genNmb); + + copy_cgPtyCat_from_sngss7(ftdmchan, &siConEvnt->cgPtyCat); /* fill in the TMR/bearer capability */ if (siConEvnt->txMedReq.eh.pres) { @@ -214,6 +210,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val); sngss7_add_var(sngss7_info, "ss7_cld_nadi", nadi); + if (sngss7_info->circuit->transparent_iam) { + sngss7_save_iam(ftdmchan, siConEvnt); + } + /* check if a COT test is requested */ if ((siConEvnt->natConInd.eh.pres) && (siConEvnt->natConInd.contChkInd.pres) && @@ -237,7 +237,6 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ siConEvnt->cgPtyNum.natAddrInd.val, ftdmchan->caller_data.dnis.digits, siConEvnt->cdPtyNum.natAddrInd.val); - } /* if (channel is usable */ break; @@ -490,6 +489,47 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ case (SUBDIRNUM): SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUB-DIR\n", sngss7_info->circuit->cic); break; +#ifdef SANGOMA_SPIROU + case (CHARGE_ACK): + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx TXA\n", sngss7_info->circuit->cic); + break; + case (CHARGE_UNIT): + { + uint32_t charging_unit = 0; + uint32_t msg_num = 0; + char val[3]; + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ITX\n", sngss7_info->circuit->cic); + + memset(val, '\0', sizeof(val)); + + if (siCnStEvnt->chargUnitNum.eh.pres == PRSNT_NODEF && + siCnStEvnt->chargUnitNum.chargUnitNum.pres == PRSNT_NODEF) { + + charging_unit = siCnStEvnt->chargUnitNum.chargUnitNum.val; + } + + if (siCnStEvnt->msgNum.eh.pres == PRSNT_NODEF && + siCnStEvnt->msgNum.msgNum.pres == PRSNT_NODEF) { + + msg_num = siCnStEvnt->msgNum.msgNum.val; + } + + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Charging Unit:%d Msg Num:%d\n", charging_unit, msg_num); + + sprintf(val, "%d", charging_unit); + sngss7_add_var(sngss7_info, "ss7_itx_charge_unit", val); + + sprintf(val, "%d", msg_num); + sngss7_add_var(sngss7_info, "ss7_itx_msg_num", val); + + if (sngss7_info->circuit->itx_auto_reply) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Auto-reply with TXA msg\n"); + ft_to_sngss7_txa (ftdmchan); + } + } + break; +#endif /**************************************************************************/ default: SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Unknown Msg\n", sngss7_info->circuit->cic); @@ -532,7 +572,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* go to UP */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); - + break; /**************************************************************************/ case FTDM_CHANNEL_STATE_DIALING: @@ -609,6 +649,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); break; /**************************************************************************/ case FTDM_CHANNEL_STATE_RING: + case FTDM_CHANNEL_STATE_RINGING: case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_UP: 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 4f8c069b71..53062b9d56 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 @@ -42,6 +42,7 @@ static sng_isup_event_interface_t sng_event; static ftdm_io_interface_t g_ftdm_sngss7_interface; ftdm_sngss7_data_t g_ftdm_sngss7_data; + /******************************************************************************/ /* PROTOTYPES *****************************************************************/ @@ -509,11 +510,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state)); -#if 0 - /* clear the state change flag...since we might be setting a new state */ - ftdm_channel_complete_state(ftdmchan); -#endif - /*check what state we are supposed to be in */ switch (ftdmchan->state) { /**************************************************************************/ 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 ea31a89c5b..f88202b1a8 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 @@ -60,6 +60,13 @@ #define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */ +typedef struct ftdm2trillium +{ + uint8_t ftdm_val; + uint8_t trillium_val; +}ftdm2trillium_t; + + typedef enum { SNGSS7_CON_IND_EVENT = 0, SNGSS7_CON_CFM_EVENT, @@ -320,8 +327,19 @@ typedef struct sng_isup_ckt { uint32_t clg_nadi; uint32_t cld_nadi; uint8_t rdnis_nadi; + + /* Generic Number defaults */ + uint8_t gn_nmbqual; /* Number Qualifier */ + uint8_t gn_nadi; /* Nature of Address indicator */ + uint8_t gn_screen_ind; /* Screening Indicator */ + uint8_t gn_pres_ind; /* Presentation Indicator */ + uint8_t gn_npi; /* Numbering Plan Indicator */ + uint8_t gn_num_inc_ind; /* Number Incomplete Indicator */ + /* END - Generic Number defaults */ uint32_t min_digits; + uint8_t itx_auto_reply; + uint8_t transparent_iam; void *obj; uint16_t t3; uint16_t t12; @@ -389,6 +407,7 @@ typedef struct sng_ss7_cfg { uint32_t procId; char license[MAX_PATH]; char signature[MAX_PATH]; + uint32_t transparent_iam_max_size; uint32_t flags; sng_relay_t relay[MAX_RELAY_CHANNELS+1]; sng_mtp1_link_t mtp1Link[MAX_MTP_LINKS+1]; @@ -728,6 +747,9 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan); 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); +void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan); +void ft_to_sngss7_txa (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); @@ -745,6 +767,10 @@ void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiR void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt); void sngss7_ssp_sta_cfm(uint32_t infId); +ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt); +ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt); +ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt); + /* 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); @@ -785,12 +811,21 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa 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); +ftdm_status_t copy_cgPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum); +ftdm_status_t copy_cgPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum); +ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum); +ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum); ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum); - +ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum); +ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb); +ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb); +ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat); +ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat); +ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt); +ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd); +ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd); +ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq); +ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA); ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven); ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven); 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 9fe279d7c5..91b8900fef 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 @@ -36,10 +36,8 @@ /******************************************************************************/ /* DEFINES ********************************************************************/ -/******************************************************************************/ /* GLOBALS ********************************************************************/ -/******************************************************************************/ /* PROTOTYPES *****************************************************************/ void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan); @@ -66,243 +64,74 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan); void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan); void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan); -/******************************************************************************/ /* FUNCTIONS ******************************************************************/ 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 *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_chan_data_t *sngss7_info = ftdmchan->call_data;; + + SS7_FUNC_TRACE_ENTER (__FUNCTION__); sngss7_info->suInstId = get_unique_id (); sngss7_info->spInstId = 0; sngss7_info->spId = 1; memset (&iam, 0x0, sizeof (iam)); - - /* copy down the nature of connection indicators */ - iam.natConInd.eh.pres = PRSNT_NODEF; - iam.natConInd.satInd.pres = PRSNT_NODEF; - iam.natConInd.satInd.val = 0; /* no satellite circuit */ - iam.natConInd.contChkInd.pres = PRSNT_NODEF; - iam.natConInd.contChkInd.val = CONTCHK_NOTREQ; - iam.natConInd.echoCntrlDevInd.pres = PRSNT_NODEF; - iam.natConInd.echoCntrlDevInd.val = ECHOCDEV_INCL; - - /* copy down the forward call indicators */ - iam.fwdCallInd.eh.pres = PRSNT_NODEF; - iam.fwdCallInd.natIntCallInd.pres = PRSNT_NODEF; - iam.fwdCallInd.natIntCallInd.val = 0x00; - iam.fwdCallInd.end2EndMethInd.pres = PRSNT_NODEF; - iam.fwdCallInd.end2EndMethInd.val = E2EMTH_NOMETH; - iam.fwdCallInd.intInd.pres = PRSNT_NODEF; - iam.fwdCallInd.intInd.val = INTIND_NOINTW; - iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF; - iam.fwdCallInd.end2EndInfoInd.val = E2EINF_NOINFO; - iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED; - iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_PREFAW; - iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN; - iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF; - iam.fwdCallInd.sccpMethInd.val = SCCPMTH_NOIND; - - /* copy down the calling number information */ - iam.cgPtyCat.eh.pres = PRSNT_NODEF; - iam.cgPtyCat.cgPtyCat.pres = PRSNT_NODEF; - iam.cgPtyCat.cgPtyCat.val = CAT_ORD; /* ordinary suscriber */ - - /* copy down the transmission medium requirements */ - iam.txMedReq.eh.pres = PRSNT_NODEF; - iam.txMedReq.trMedReq.pres = PRSNT_NODEF; - iam.txMedReq.trMedReq.val = ftdmchan->caller_data.bearer_capability; - if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) || - (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) || - (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) { - - /* include only if we're running ANSI */ - iam.fwdCallInd.transCallNInd.pres = PRSNT_NODEF; - iam.fwdCallInd.transCallNInd.val = 0x0; - - iam.usrServInfoA.eh.pres = PRSNT_NODEF; - - iam.usrServInfoA.infoTranCap.pres = PRSNT_NODEF; - switch (ftdmchan->caller_data.bearer_capability) { - /**********************************************************************/ - case (FTDM_BEARER_CAP_SPEECH): - iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */ - break; - /**********************************************************************/ - case (FTDM_BEARER_CAP_64K_UNRESTRICTED): - iam.usrServInfoA.infoTranCap.val = 0x8; /* unrestricted digital as per ATIS-1000113.3.2005 */ - break; - /**********************************************************************/ - case (FTDM_BEARER_CAP_3_1KHZ_AUDIO): - iam.usrServInfoA.infoTranCap.val = 0x10; /* 3.1kHz audio as per ATIS-1000113.3.2005 */ - break; - /**********************************************************************/ - default: - SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " "); - iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */ - break; - /**********************************************************************/ - } /* switch (ftdmchan->caller_data.bearer_capability) */ - - iam.usrServInfoA.cdeStand.pres = PRSNT_NODEF; - iam.usrServInfoA.cdeStand.val = 0x0; /* ITU-T standardized coding */ - iam.usrServInfoA.tranMode.pres = PRSNT_NODEF; - iam.usrServInfoA.tranMode.val = 0x0; /* circuit mode */ - iam.usrServInfoA.infoTranRate0.pres = PRSNT_NODEF; - iam.usrServInfoA.infoTranRate0.val = 0x10; /* 64kbps origination to destination */ - iam.usrServInfoA.infoTranRate1.pres = PRSNT_NODEF; - iam.usrServInfoA.infoTranRate1.val = 0x10; /* 64kbps destination to origination */ - iam.usrServInfoA.chanStruct.pres = PRSNT_NODEF; - iam.usrServInfoA.chanStruct.val = 0x1; /* 8kHz integrity */ - iam.usrServInfoA.config.pres = PRSNT_NODEF; - iam.usrServInfoA.config.val = 0x0; /* point to point configuration */ - iam.usrServInfoA.establish.pres = PRSNT_NODEF; - iam.usrServInfoA.establish.val = 0x0; /* on demand */ - iam.usrServInfoA.symmetry.pres = PRSNT_NODEF; - iam.usrServInfoA.symmetry.val = 0x0; /* bi-directional symmetric */ - iam.usrServInfoA.usrInfLyr1Prot.pres = PRSNT_NODEF; - iam.usrServInfoA.usrInfLyr1Prot.val = 0x2; /* G.711 ulaw */ - iam.usrServInfoA.rateMultiplier.pres = PRSNT_NODEF; - iam.usrServInfoA.rateMultiplier.val = 0x1; /* 1x rate multipler */ - } /* if ANSI */ - - /* copy down the called number information */ - copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum); - - /* copy down the calling number information */ - copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); - - /* check if the user would like a custom NADI value for the calling Pty Num */ - clg_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "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); + if (sngss7_info->circuit->transparent_iam && + sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) { + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic); } else { - iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].clg_nadi; - SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val); - } - - cld_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "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.isupCkt[sngss7_info->circuit->id].cld_nadi; - SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLD, using \"%d\"\n", iam.cdPtyNum.natAddrInd.val); - } + /* Nature of Connection Indicators */ + copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd); - /* check if the user would like us to send a clg_sub-address */ - clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr"); - if ((clg_subAddr != NULL) && (*clg_subAddr)) { - SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr); + /* Forward Call Indicators */ + copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd); + + /* Transmission medium requirements */ + copy_txMedReq_to_sngss7(ftdmchan, &iam.txMedReq); + + /* User Service Info A */ + copy_usrServInfoA_to_sngss7(ftdmchan, &iam.usrServInfoA); - /* 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') */ - } - - copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); - - /* check if the user would like us to send a cld_sub-address */ - cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr"); - if ((cld_subAddr != NULL) && (*cld_subAddr)) { - SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr); + /* Called Number information */ + copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum); - /* clean out the subAddrIE */ - memset(subAddrIE, 0x0, sizeof(subAddrIE)); + /* Calling Number information */ + copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum); - /* 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]) */ + /* Generic Number information */ + copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb); - /* 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)) */ + /* Calling Party's Category */ + copy_cgPtyCat_to_sngss7(ftdmchan, &iam.cgPtyCat); + + /* Redirecting Number */ + copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum); + + /* Access Transport */ + copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt); + + 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, + iam.cgPtyNum.natAddrInd.val, + ftdmchan->caller_data.dnis.digits, + iam.cdPtyNum.natAddrInd.val); + } sng_cc_con_request (sngss7_info->spId, sngss7_info->suInstId, sngss7_info->spInstId, - sngss7_info->circuit->id, - &iam, + sngss7_info->circuit->id, + &iam, 0); - 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, - iam.cgPtyNum.natAddrInd.val, - ftdmchan->caller_data.dnis.digits, - iam.cdPtyNum.natAddrInd.val); - - SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; } -/******************************************************************************/ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) { SS7_FUNC_TRACE_ENTER (__FUNCTION__); @@ -339,7 +168,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) acm.bckCallInd.echoCtrlDevInd.val = 0x1; break; /**********************************************************************/ - case (FTDM_BEARER_CAP_64K_UNRESTRICTED): + case (FTDM_BEARER_CAP_UNRESTRICTED): acm.bckCallInd.echoCtrlDevInd.val = 0x0; break; /**********************************************************************/ @@ -382,7 +211,6 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) return; } -/******************************************************************************/ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) { SS7_FUNC_TRACE_ENTER (__FUNCTION__); @@ -892,6 +720,69 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan) return; } +/* French SPIROU send Charge Unit */ +/* No one calls this function yet, but it has been implemented to complement TXA messages */ +void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan) +{ +#ifndef SANGOMA_SPIROU + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "ITX message not supported!, please update your libsng_ss7\n"); +#else + const char* var = NULL; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + SiCnStEvnt itx; + + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + + memset (&itx, 0x0, sizeof (itx)); + + itx.msgNum.eh.pres = PRSNT_NODEF; + itx.msgNum.msgNum.pres = PRSNT_NODEF; + var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_msg_num"); + if (!ftdm_strlen_zero(var)) { + itx.msgNum.msgNum.val = atoi(var); + } else { + itx.msgNum.msgNum.val = 0x1; + } + + itx.chargUnitNum.eh.pres = PRSNT_NODEF; + itx.chargUnitNum.chargUnitNum.pres = PRSNT_NODEF; + var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_charge_unit"); + if (!ftdm_strlen_zero(var)) { + itx.chargUnitNum.chargUnitNum.val = atoi(var); + } else { + itx.chargUnitNum.chargUnitNum.val = 0x1; + } + + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "ITX Charging Unit:%d Msg Num:%d\n", itx.chargUnitNum.chargUnitNum.val, itx.msgNum.msgNum.val); + sng_cc_con_status (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &itx, CHARGE_UNIT); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ITX\n", sngss7_info->circuit->cic); +#endif + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; +} + +/* French SPIROU send Charging Acknowledgement */ +void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan) +{ +#ifndef SANGOMA_SPIROU + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "TXA message not supported!, please update your libsng_ss7\n"); +#else + SiCnStEvnt txa; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + + memset (&txa, 0x0, sizeof(txa)); + + sng_cc_con_status(1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &txa, CHARGE_ACK); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx TXA\n", sngss7_info->circuit->cic); +#endif + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; +} /******************************************************************************/ /* For Emacs: 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 22b522409f..e61153c8e7 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 @@ -33,6 +33,9 @@ /* INCLUDE ********************************************************************/ #include "ftmod_sangoma_ss7_main.h" +#ifdef HAVE_ZLIB +#include +#endif /******************************************************************************/ /* DEFINES ********************************************************************/ @@ -91,254 +94,288 @@ FTDM_ENUM_NAMES(BLK_FLAGS_NAMES, BLK_FLAGS_STRING) FTDM_STR2ENUM(ftmod_ss7_blk_state2flag, ftmod_ss7_blk_flag2str, sng_ckt_block_flag_t, BLK_FLAGS_NAMES, 31) /* FUNCTIONS ******************************************************************/ -uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) -{ +static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val); +static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val); - return 0; + + +/* Maps generic FreeTDM CPC codes to SS7 CPC codes */ +ftdm2trillium_t cpc_codes[] = { + {FTDM_CPC_UNKNOWN, CAT_UNKNOWN}, + {FTDM_CPC_OPERATOR_FRENCH, CAT_OPLANGFR}, + {FTDM_CPC_OPERATOR_ENGLISH, CAT_OPLANGENG}, + {FTDM_CPC_OPERATOR_GERMAN, CAT_OPLANGGER}, + {FTDM_CPC_OPERATOR_RUSSIAN, CAT_OPLANGRUS}, + {FTDM_CPC_OPERATOR_SPANISH, CAT_OPLANGSP}, + {FTDM_CPC_ORDINARY, CAT_ORD}, + {FTDM_CPC_PRIORITY, CAT_PRIOR}, + {FTDM_CPC_DATA, CAT_DATA}, + {FTDM_CPC_TEST, CAT_TEST}, + {FTDM_CPC_PAYPHONE, CAT_PAYPHONE}, +}; + +ftdm2trillium_t bc_cap_codes[] = { + {FTDM_BEARER_CAP_SPEECH, ITC_SPEECH}, /* speech as per ATIS-1000113.3.2005 */ + {FTDM_BEARER_CAP_UNRESTRICTED, ITC_UNRDIG}, /* unrestricted digital as per ATIS-1000113.3.2005 */ + {FTDM_BEARER_CAP_RESTRICTED, ITC_UNRDIG}, /* Restricted Digital */ + {FTDM_BEARER_CAP_3_1KHZ_AUDIO, ITC_A31KHZ}, /* 3.1kHz audio as per ATIS-1000113.3.2005 */ + {FTDM_BEARER_CAP_7KHZ_AUDIO, ITC_A7KHZ}, /* 7Khz audio */ + {FTDM_BEARER_CAP_15KHZ_AUDIO, ITC_A15KHZ}, /* 15Khz audio */ + {FTDM_BEARER_CAP_VIDEO, ITC_VIDEO}, /* Video */ +}; + +static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val) +{ + ftdm2trillium_t *val = vals; + while(val++) { + if (val->ftdm_val == ftdm_val) { + return val->trillium_val; + } + } + return default_val; } -/******************************************************************************/ -uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) +static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val) { - int k; - int j; - int flag; - int odd; - char tmp[2]; - uint8_t lower; - uint8_t upper; + ftdm2trillium_t *val = vals; + while(val++) { + if (val->trillium_val == trillium_val) { + return val->ftdm_val; + } + } + return default_val; +} + +ftdm_status_t copy_cgPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum) +{ + return FTDM_SUCCESS; +} + +ftdm_status_t copy_cgPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum) +{ + const char *val; + + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - /**************************************************************************/ cgPtyNum->eh.pres = PRSNT_NODEF; - /**************************************************************************/ + cgPtyNum->natAddrInd.pres = PRSNT_NODEF; cgPtyNum->natAddrInd.val = 0x03; - /**************************************************************************/ + + cgPtyNum->scrnInd.pres = PRSNT_NODEF; - cgPtyNum->scrnInd.val = ftdm->screen; - /**************************************************************************/ + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_screen_ind"); + if (!ftdm_strlen_zero(val)) { + cgPtyNum->scrnInd.val = atoi(val); + } else { + cgPtyNum->scrnInd.val = caller_data->screen; + } + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Screening Ind %d\n", cgPtyNum->scrnInd.val); + cgPtyNum->presRest.pres = PRSNT_NODEF; - cgPtyNum->presRest.val = ftdm->pres; - /**************************************************************************/ + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_pres_ind"); + if (!ftdm_strlen_zero(val)) { + cgPtyNum->presRest.val = atoi(val); + } else { + cgPtyNum->presRest.val = caller_data->pres; + } + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Number Presentation Ind %d\n", cgPtyNum->presRest.val); + cgPtyNum->numPlan.pres = PRSNT_NODEF; cgPtyNum->numPlan.val = 0x01; - /**************************************************************************/ + cgPtyNum->niInd.pres = PRSNT_NODEF; cgPtyNum->niInd.val = 0x00; - /**************************************************************************/ - cgPtyNum->addrSig.pres = PRSNT_NODEF; - - /* atoi will search through memory starting from the pointer it is given until - * it finds the \0...since tmp is on the stack it will start going through the - * possibly causing corruption. Hard code a \0 to prevent this - */ - - tmp[1] = '\0'; - k = 0; - j = 0; - flag = 0; - odd = 0; - upper = 0x0; - lower = 0x0; - while (1) { - /* grab a digit from the ftdm digits */ - tmp[0] = ftdm->cid_num.digits[k]; - - /* check if the digit is a number and that is not null */ - while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - /* move on to the next value */ - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } /* while(!(isdigit(tmp))) */ - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push it into the lower nibble */ - lower = strtol(&tmp[0], (char **)NULL, 16); - /* move to the next digit */ - k++; - /* grab a digit from the ftdm digits */ - tmp[0] = ftdm->cid_num.digits[k]; - - /* check if the digit is a number and that is not null */ - while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } /* while(!(isdigit(tmp))) */ - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push the digit into the upper nibble */ - upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4; - } else { - /* there is no upper ... fill in 0 */ - upper = 0x0; - /* throw the odd flag */ - odd = 1; - /* throw the end flag */ - flag = 1; - } /* if (tmp != '\0') */ - } else { - /* keep the odd flag down */ - odd = 0; - /* break right away since we don't need to write the digits */ - break; - } - - /* push the digits into the trillium structure */ - cgPtyNum->addrSig.val[j] = upper | lower; - - /* increment the trillium pointer */ - j++; - - /* if the flag is up we're through all the digits */ - if (flag) break; - - /* move to the next digit */ - k++; - } /* while(1) */ - - cgPtyNum->addrSig.len = j; - - /**************************************************************************/ - cgPtyNum->oddEven.pres = PRSNT_NODEF; - cgPtyNum->oddEven.val = odd; - /**************************************************************************/ - return 0; + return copy_tknStr_to_sngss7(caller_data->cid_num.digits, &cgPtyNum->addrSig, &cgPtyNum->oddEven); } -/******************************************************************************/ -uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) +ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum) { - - return 0; + /* TODO: Implement me */ + return FTDM_SUCCESS; } -/******************************************************************************/ -uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) -{ - int k; - int j; - int flag; - int odd; - char tmp[2]; - uint8_t lower; - uint8_t upper; - /**************************************************************************/ +ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum) +{ + const char *cld_nadi = NULL; + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + cdPtyNum->eh.pres = PRSNT_NODEF; - /**************************************************************************/ + cdPtyNum->natAddrInd.pres = PRSNT_NODEF; - cdPtyNum->natAddrInd.val = 0x03; - /**************************************************************************/ + cld_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_nadi"); + if (!ftdm_strlen_zero(cld_nadi)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Called NADI value \"%s\"\n", cld_nadi); + cdPtyNum->natAddrInd.val = atoi(cld_nadi); + } else { + cdPtyNum->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].cld_nadi; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied NADI value found for CLD, using \"%d\"\n", cdPtyNum->natAddrInd.val); + } + cdPtyNum->numPlan.pres = PRSNT_NODEF; cdPtyNum->numPlan.val = 0x01; - /**************************************************************************/ + cdPtyNum->innInd.pres = PRSNT_NODEF; cdPtyNum->innInd.val = 0x01; - /**************************************************************************/ - cdPtyNum->addrSig.pres = PRSNT_NODEF; - - /* atoi will search through memory starting from the pointer it is given until - * it finds the \0...since tmp is on the stack it will start going through the - * possibly causing corruption. Hard code a \0 to prevent this - */ /* dnis */ - tmp[1] = '\0'; - k = 0; - j = 0; - flag = 0; - odd = 0; - upper = 0x0; - lower = 0x0; - - while (1) { - /* grab a digit from the ftdm digits */ - tmp[0] = ftdm->dnis.digits[k]; - - /* check if the digit is a number and that is not null */ - while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - /* move on to the next value */ - k++; - tmp[0] = ftdm->dnis.digits[k]; - } /* while(!(isdigit(tmp))) */ - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push it into the lower nibble */ - lower = strtol(&tmp[0], (char **)NULL, 16); - /* move to the next digit */ - k++; - /* grab a digit from the ftdm digits */ - tmp[0] = ftdm->dnis.digits[k]; - - /* check if the digit is a number and that is not null */ - while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - k++; - tmp[0] = ftdm->dnis.digits[k]; - } /* while(!(isdigit(tmp))) */ - - /* check if tmp is null or a digit */ - if (tmp[0] != '\0') { - /* push the digit into the upper nibble */ - upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4; - } else { - /* there is no upper ... fill in ST */ - upper = 0xF0; - /* keep the odd flag down */ - odd = 0; - /* throw the end flag */ - flag = 1; - } /* if (tmp != '\0') */ - } else { - /* throw the odd flag */ - odd = 1; - /* need to add the ST */ - lower = 0xF; - upper = 0x0; - /* throw the flag */ - flag = 1; - } - - /* push the digits into the trillium structure */ - cdPtyNum->addrSig.val[j] = upper | lower; - - /* increment the trillium pointer */ - j++; - - /* if the flag is up we're through all the digits */ - if (flag) break; - - /* move to the next digit */ - k++; - } /* while(1) */ - - cdPtyNum->addrSig.len = j; - - /**************************************************************************/ - cdPtyNum->oddEven.pres = PRSNT_NODEF; - - cdPtyNum->oddEven.val = odd; - - /**************************************************************************/ - return 0; + + return copy_tknStr_to_sngss7(caller_data->dnis.digits, &cdPtyNum->addrSig, &cdPtyNum->oddEven); } +ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb) +{ + const char *val = NULL; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_digits"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number qualifier \"%s\"\n", val); + if (copy_tknStr_to_sngss7((char*)val, &genNmb->addrSig, &genNmb->oddEven) != FTDM_SUCCESS) { + return FTDM_FAIL; + } + } else { + return FTDM_SUCCESS; + } + + genNmb->eh.pres = PRSNT_NODEF; + genNmb->addrSig.pres = PRSNT_NODEF; + + genNmb->nmbQual.pres = PRSNT_NODEF; + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_numqual"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"%s\"\n", val); + genNmb->nmbQual.val = atoi(val); + } else { + genNmb->nmbQual.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_nmbqual; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \n"); + } + genNmb->natAddrInd.pres = PRSNT_NODEF; + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_nadi"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"nature of address\" \"%s\"\n", val); + genNmb->natAddrInd.val = atoi(val); + } else { + genNmb->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_nadi; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"nature of address\" \"%d\"\n", genNmb->natAddrInd.val); + } + genNmb->scrnInd.pres = PRSNT_NODEF; + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_screen_ind"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"screening indicator\" \"%s\"\n", val); + genNmb->scrnInd.val = atoi(val); + } else { + genNmb->natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_screen_ind; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"screening indicator\" \"%d\"\n", genNmb->natAddrInd.val); + } + genNmb->presRest.pres = PRSNT_NODEF; + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_pres_ind"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"presentation indicator\" \"%s\"\n", val); + genNmb->presRest.val = atoi(val); + } else { + genNmb->presRest.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_pres_ind; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"presentation indicator\" \"%d\"\n", genNmb->presRest.val); + } + genNmb->numPlan.pres = PRSNT_NODEF; + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_npi"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"numbering plan\" \"%s\"\n", val); + genNmb->numPlan.val = atoi(val); + } else { + genNmb->numPlan.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_npi; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"numbering plan\" \"%d\"\n", genNmb->numPlan.val); + } + genNmb->niInd.pres = PRSNT_NODEF; + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_num_inc_ind"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Generic Number \"number incomplete indicator\" \"%s\"\n", val); + genNmb->niInd.val = atoi(val); + } else { + genNmb->niInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_num_inc_ind; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"number incomplete indicator\" \"%d\"\n", genNmb->niInd.val); + } + return FTDM_SUCCESS; +} + +ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb) +{ + char val[64]; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + memset(val, 0, sizeof(val)); + + if (genNmb->eh.pres != PRSNT_NODEF || genNmb->addrSig.pres != PRSNT_NODEF) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Generic Number available\n"); + return FTDM_SUCCESS; + } + + copy_tknStr_from_sngss7(genNmb->addrSig, val, genNmb->oddEven); + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number:%s\n", val); + sngss7_add_var(sngss7_info, "ss7_gn_digits", val); + + if (genNmb->nmbQual.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", genNmb->nmbQual.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number qualifier\" \n", val); + sngss7_add_var(sngss7_info, "ss7_gn_numqual", val); + } + + if (genNmb->natAddrInd.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", genNmb->natAddrInd.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"nature of address\" \"%s\"\n", val); + sngss7_add_var(sngss7_info, "ss7_gn_nadi", val); + } + + if (genNmb->scrnInd.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", genNmb->scrnInd.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"screening indicator\" \"%s\"\n", val); + sngss7_add_var(sngss7_info, "ss7_gn_screen_ind", val); + } + + if (genNmb->presRest.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", genNmb->presRest.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"presentation indicator\" \"%s\"\n", val); + sngss7_add_var(sngss7_info, "ss7_gn_pres_ind", val); + } + + if (genNmb->numPlan.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", genNmb->numPlan.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"numbering plan\" \"%s\"\n", val); + sngss7_add_var(sngss7_info, "ss7_gn_npi", val); + } + + if (genNmb->niInd.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", genNmb->niInd.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Generic Number \"number incomplete indicator\" \"%s\"\n", val); + sngss7_add_var(sngss7_info, "ss7_gn_num_inc_ind", val); + } + + return FTDM_SUCCESS; +} ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum) { const char* val = NULL; sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - uint8_t len = strlen(caller_data->rdnis.digits); - if (!len) { + + val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits"); + if (!ftdm_strlen_zero(val)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Redirection Number\"%s\"\n", val); + if (copy_tknStr_to_sngss7((char*)val, &redirgNum->addrSig, &redirgNum->oddEven) != FTDM_SUCCESS) { + return FTDM_FAIL; + } + } else if (!ftdm_strlen_zero(caller_data->rdnis.digits)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Redirection Number\"%s\"\n", val); + if (copy_tknStr_to_sngss7(caller_data->rdnis.digits, &redirgNum->addrSig, &redirgNum->oddEven) != FTDM_SUCCESS) { + return FTDM_FAIL; + } + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Redirection Number\n"); return FTDM_SUCCESS; } - SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number %s\n", caller_data->rdnis.digits); redirgNum->eh.pres = PRSNT_NODEF; @@ -351,7 +388,7 @@ ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *red } else { redirgNum->natAddr.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].rdnis_nadi; } - SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number NADI:%d\n", redirgNum->natAddr.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number NADI:%d\n", redirgNum->natAddr.val); /* Screening indicator */ redirgNum->scrInd.pres = PRSNT_NODEF; @@ -361,7 +398,7 @@ ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *red } else { redirgNum->scrInd.val = FTDM_SCREENING_VERIFIED_PASSED; } - SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number Screening Ind:%d\n", redirgNum->scrInd.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Screening Ind:%d\n", redirgNum->scrInd.val); /* Address presentation restricted ind */ redirgNum->presRest.pres = PRSNT_NODEF; @@ -372,7 +409,7 @@ ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *red } else { redirgNum->presRest.val = FTDM_PRES_ALLOWED; } - SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number Address Presentation Restricted Ind:%d\n", redirgNum->presRest.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Address Presentation Restricted Ind:%d\n", redirgNum->presRest.val); /* Numbering plan */ redirgNum->numPlan.pres = PRSNT_NODEF; @@ -384,18 +421,270 @@ ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *red redirgNum->numPlan.val = caller_data->rdnis.plan; } - SS7_DEBUG_CHAN(ftdmchan, "Redirecting Number Numbering plan:%d\n", redirgNum->numPlan.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Numbering plan:%d\n", redirgNum->numPlan.val); return copy_tknStr_to_sngss7(caller_data->rdnis.digits, &redirgNum->addrSig, &redirgNum->oddEven); } +ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum) +{ + char val[20]; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + + if (redirgNum->eh.pres != PRSNT_NODEF || redirgNum->addrSig.pres != PRSNT_NODEF) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Redirecting Number available\n"); + return FTDM_SUCCESS; + } + + copy_tknStr_from_sngss7(redirgNum->addrSig, ftdmchan->caller_data.rdnis.digits, redirgNum->oddEven); + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number:%s\n", ftdmchan->caller_data.rdnis.digits); + snprintf(val, sizeof(val), "%s", ftdmchan->caller_data.rdnis.digits); + sngss7_add_var(sngss7_info, "ss7_rdnis_digits", val); + + + if (redirgNum->natAddr.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", redirgNum->natAddr.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number NADI:%s\n", val); + sngss7_add_var(sngss7_info, "ss7_rdnis_nadi", val); + caller_data->rdnis.type = redirgNum->natAddr.val; + } + + if (redirgNum->scrInd.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", redirgNum->scrInd.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Screening Ind:%s\n", val); + sngss7_add_var(sngss7_info, "ss7_rdnis_screen_ind", val); + } + + if (redirgNum->presRest.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", redirgNum->presRest.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Presentation Ind:%s\n", val); + sngss7_add_var(sngss7_info, "ss7_rdnis_pres_ind", val); + } + + if (redirgNum->numPlan.pres == PRSNT_NODEF) { + snprintf(val, sizeof(val), "%d", redirgNum->numPlan.val); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Redirecting Number Numbering plan:%s\n", val); + sngss7_add_var(sngss7_info, "ss7_rdnis_plan", val); + caller_data->rdnis.plan = redirgNum->numPlan.val; + } + + return FTDM_SUCCESS; +} + +ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat) +{ + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + + cgPtyCat->eh.pres = PRSNT_NODEF; + cgPtyCat->cgPtyCat.pres = PRSNT_NODEF; + + cgPtyCat->cgPtyCat.val = get_trillium_val(cpc_codes, caller_data->cpc, CAT_ORD); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Category:0x%x\n",cgPtyCat->cgPtyCat.val); + return FTDM_SUCCESS; +} + +ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat) +{ + ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; + + if (cgPtyCat->eh.pres == PRSNT_NODEF && + cgPtyCat->cgPtyCat.pres == PRSNT_NODEF) { + + caller_data->cpc = get_ftdm_val(cpc_codes, cgPtyCat->cgPtyCat.val, FTDM_CPC_UNKNOWN); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Category:0x%x\n", cgPtyCat->cgPtyCat.val); + } + return FTDM_SUCCESS; +} + + +ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt) +{ + const char *clg_subAddr = NULL; + const char *cld_subAddr = NULL; + char subAddrIE[MAX_SIZEOF_SUBADDR_IE]; + + /* check if the user would like us to send a clg_sub-address */ + clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr"); + if (!ftdm_strlen_zero(clg_subAddr)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "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: + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "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 (accTrnspt->eh.pres == PRSNT_NODEF) { + /* append the subAddrIE */ + memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2)); + accTrnspt->infoElmts.len = accTrnspt->infoElmts.len +subAddrIE[1] + 2; + } else { + /* fill in from the beginning */ + accTrnspt->eh.pres = PRSNT_NODEF; + accTrnspt->infoElmts.pres = PRSNT_NODEF; + memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2)); + accTrnspt->infoElmts.len = subAddrIE[1] + 2; + } + } + } + + /* check if the user would like us to send a cld_sub-address */ + cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr"); + if ((cld_subAddr != NULL) && (*cld_subAddr)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "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: + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "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 (accTrnspt->eh.pres == PRSNT_NODEF) { + /* append the subAddrIE */ + memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2)); + accTrnspt->infoElmts.len = accTrnspt->infoElmts.len +subAddrIE[1] + 2; + } else { + /* fill in from the beginning */ + accTrnspt->eh.pres = PRSNT_NODEF; + accTrnspt->infoElmts.pres = PRSNT_NODEF; + memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2)); + accTrnspt->infoElmts.len = subAddrIE[1] + 2; + } + } + } /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */ + return FTDM_SUCCESS; +} + +ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd) +{ + /* copy down the nature of connection indicators */ + natConInd->eh.pres = PRSNT_NODEF; + natConInd->satInd.pres = PRSNT_NODEF; + natConInd->satInd.val = 0; /* no satellite circuit */ + natConInd->contChkInd.pres = PRSNT_NODEF; + natConInd->contChkInd.val = CONTCHK_NOTREQ; + natConInd->echoCntrlDevInd.pres = PRSNT_NODEF; + natConInd->echoCntrlDevInd.val = ECHOCDEV_INCL; + return FTDM_SUCCESS; +} + +ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd) +{ + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + fwdCallInd->eh.pres = PRSNT_NODEF; + fwdCallInd->natIntCallInd.pres = PRSNT_NODEF; + fwdCallInd->natIntCallInd.val = 0x00; + fwdCallInd->end2EndMethInd.pres = PRSNT_NODEF; + fwdCallInd->end2EndMethInd.val = E2EMTH_NOMETH; + fwdCallInd->intInd.pres = PRSNT_NODEF; + fwdCallInd->intInd.val = INTIND_NOINTW; + fwdCallInd->end2EndInfoInd.pres = PRSNT_NODEF; + fwdCallInd->end2EndInfoInd.val = E2EINF_NOINFO; + fwdCallInd->isdnUsrPrtInd.pres = PRSNT_NODEF; + fwdCallInd->isdnUsrPrtInd.val = ISUP_USED; + fwdCallInd->isdnUsrPrtPrfInd.pres = PRSNT_NODEF; + fwdCallInd->isdnUsrPrtPrfInd.val = PREF_PREFAW; + fwdCallInd->isdnAccInd.pres = PRSNT_NODEF; + fwdCallInd->isdnAccInd.val = ISDNACC_ISDN; + fwdCallInd->sccpMethInd.pres = PRSNT_NODEF; + fwdCallInd->sccpMethInd.val = SCCPMTH_NOIND; + + if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) { + + /* include only if we're running ANSI */ + fwdCallInd->transCallNInd.pres = PRSNT_NODEF; + fwdCallInd->transCallNInd.val = 0x0; + } + return FTDM_SUCCESS; +} + +ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq) +{ + txMedReq->eh.pres = PRSNT_NODEF; + txMedReq->trMedReq.pres = PRSNT_NODEF; + txMedReq->trMedReq.val = ftdmchan->caller_data.bearer_capability; + + return FTDM_SUCCESS; +} + +ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA) +{ + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) { + + usrServInfoA->eh.pres = PRSNT_NODEF; + + usrServInfoA->infoTranCap.pres = PRSNT_NODEF; + + usrServInfoA->infoTranCap.val = get_trillium_val(bc_cap_codes, ftdmchan->caller_data.bearer_capability, ITC_SPEECH); + + usrServInfoA->cdeStand.pres = PRSNT_NODEF; + usrServInfoA->cdeStand.val = 0x0; /* ITU-T standardized coding */ + usrServInfoA->tranMode.pres = PRSNT_NODEF; + usrServInfoA->tranMode.val = 0x0; /* circuit mode */ + usrServInfoA->infoTranRate0.pres = PRSNT_NODEF; + usrServInfoA->infoTranRate0.val = 0x10; /* 64kbps origination to destination */ + usrServInfoA->infoTranRate1.pres = PRSNT_NODEF; + usrServInfoA->infoTranRate1.val = 0x10; /* 64kbps destination to origination */ + usrServInfoA->chanStruct.pres = PRSNT_NODEF; + usrServInfoA->chanStruct.val = 0x1; /* 8kHz integrity */ + usrServInfoA->config.pres = PRSNT_NODEF; + usrServInfoA->config.val = 0x0; /* point to point configuration */ + usrServInfoA->establish.pres = PRSNT_NODEF; + usrServInfoA->establish.val = 0x0; /* on demand */ + usrServInfoA->symmetry.pres = PRSNT_NODEF; + usrServInfoA->symmetry.val = 0x0; /* bi-directional symmetric */ + usrServInfoA->usrInfLyr1Prot.pres = PRSNT_NODEF; + usrServInfoA->usrInfLyr1Prot.val = 0x2; /* G.711 ulaw */ + usrServInfoA->rateMultiplier.pres = PRSNT_NODEF; + usrServInfoA->rateMultiplier.val = 0x1; /* 1x rate multipler */ + } /* if ANSI */ + return FTDM_SUCCESS; +} + + + ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven) { uint8_t i; uint8_t j; /* check if the token string is present */ - if (str.pres == 1) { j = 0; @@ -491,10 +780,17 @@ ftdm_status_t copy_tknStr_to_sngss7(char* val, TknStr *tknStr, TknU8 *oddEven) /* check if the digit is a number and that is not null */ while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - /* move on to the next value */ - k++; - tmp[0] = val[k]; + if (tmp[0] == '*') { + /* Could not find a spec that specifies this , but on customer system, * was transmitted as 0x0b */ + SS7_DEBUG("Replacing * with 0x0b"); + k++; + tmp[0] = 0x0b; + } else { + SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); + /* move on to the next value */ + k++; + tmp[0] = val[k]; + } } /* while(!(isdigit(tmp))) */ /* check if tmp is null or a digit */ @@ -564,7 +860,7 @@ int check_for_state_change(ftdm_channel_t *ftdmchan) if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { /* the flag is still up...so we have a problem */ - SS7_DEBUG_CHAN(ftdmchan, "FTDM_CHANNEL_STATE_CHANGE flag set for over 500ms, channel state = %s\n", + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "FTDM_CHANNEL_STATE_CHANGE flag set for over 500ms, channel state = %s\n", ftdm_channel_state2str (ftdmchan->state)); return 1; @@ -615,8 +911,6 @@ int check_cics_in_range(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) { - /*SS7_FUNC_TRACE_ENTER(__FUNCTION__);*/ - if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj == NULL) { SS7_ERROR("sngss7_info is Null for circuit #%d\n", circuit); return FTDM_FAIL; @@ -629,7 +923,6 @@ ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_in ftdm_assert_return((*sngss7_info)->ftdmchan, FTDM_FAIL, "received message on signalling link or non-configured cic\n"); *ftdmchan = (*sngss7_info)->ftdmchan; - /*SS7_FUNC_TRACE_EXIT(__FUNCTION__);*/ return FTDM_SUCCESS; } @@ -1258,10 +1551,17 @@ ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int typ /* confirm it is a hex digit */ while ((!isxdigit(tmp[0])) && (tmp[0] != '\0')) { - SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); - /* move to the next character in subAddr */ - x++; - tmp[0] = subAddr[x]; + if (tmp[0] == '*') { + /* Could not find a spec that specifies this, but on customer system, * was transmitted as 0x0b */ + SS7_DEBUG("Replacing * with 0x0b"); + x++; + tmp[0] = 0x0b; + } else { + SS7_INFO("Dropping invalid digit: %c\n", tmp[0]); + /* move to the next character in subAddr */ + x++; + tmp[0] = subAddr[x]; + } } /* check if tmp is null or a digit */ @@ -1606,7 +1906,7 @@ void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_statu ftdm_sigmsg_t sig; ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan; - SS7_DEBUG_CHAN(ftdmchan, "Signalling link status changed to %s\n", + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status)); memset(&sig, 0, sizeof(sig)); @@ -1618,7 +1918,7 @@ void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_statu sig.ev_data.sigstatus.status = status; if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) { - SS7_ERROR_CHAN(ftdmchan, "Failed to change channel status to %s\n", + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n", ftdm_signaling_status2str(status)); } return; @@ -1660,12 +1960,12 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan) /* check if the interface is paused or resumed */ if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is PAUSED\n", sngss7_intf->id); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ISUP intf %d is PAUSED\n", sngss7_intf->id); /* throw the pause flag */ sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); } else { - SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is RESUMED\n", sngss7_intf->id); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ISUP intf %d is RESUMED\n", sngss7_intf->id); /* throw the resume flag */ sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); @@ -1793,6 +2093,336 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan) return FTDM_SUCCESS; } + +ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt) +{ + if (siConEvnt->natConInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natConInd, 0, sizeof(siConEvnt->natConInd)); + if (siConEvnt->fwdCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdCallInd, 0, sizeof(siConEvnt->fwdCallInd)); + if (siConEvnt->cgPtyCat.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyCat, 0, sizeof(siConEvnt->cgPtyCat)); + if (siConEvnt->txMedReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedReq, 0, sizeof(siConEvnt->txMedReq)); +#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) + if (siConEvnt->usrServInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfoA, 0, sizeof(siConEvnt->usrServInfoA)); +#endif + if (siConEvnt->cdPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdPtyNum, 0, sizeof(siConEvnt->cdPtyNum)); +#if TNS_ANSI +#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL) + if (siConEvnt->tranNetSel1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel1, 0, sizeof(siConEvnt->tranNetSel1)); +#endif +#endif + if (siConEvnt->tranNetSel.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel, 0, sizeof(siConEvnt->tranNetSel)); +#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA) + if (siConEvnt->callRefA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRefA, 0, sizeof(siConEvnt->callRefA)); +#endif + if (siConEvnt->callRef.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRef, 0, sizeof(siConEvnt->callRef)); + if (siConEvnt->cgPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum, 0, sizeof(siConEvnt->cgPtyNum)); +#if SS7_BELL + if (siConEvnt->cgPtyNumB.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumB, 0, sizeof(siConEvnt->cgPtyNumB)); +#endif + if (siConEvnt->opFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalInd, 0, sizeof(siConEvnt->opFwdCalInd)); +#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT) + if (siConEvnt->opFwdCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndQ, 0, sizeof(siConEvnt->opFwdCalIndQ)); +#endif +#if SS7_Q767IT + if (siConEvnt->fwdVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdVad, 0, sizeof(siConEvnt->fwdVad)); +#endif +#if SS7_ANS88 + if (siConEvnt->opFwdCalIndA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndA, 0, sizeof(siConEvnt->opFwdCalIndA)); +#endif + if (siConEvnt->redirgNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirgNum, 0, sizeof(siConEvnt->redirgNum)); + if (siConEvnt->redirInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfo, 0, sizeof(siConEvnt->redirInfo)); + if (siConEvnt->cugIntCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCode, 0, sizeof(siConEvnt->cugIntCode)); +#if SS7_ANS88 + if (siConEvnt->cugIntCodeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCodeA, 0, sizeof(siConEvnt->cugIntCodeA)); +#endif +#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA) + if (siConEvnt->connReqA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReqA, 0, sizeof(siConEvnt->connReqA)); +#endif +#if SS7_ANS88 + if (siConEvnt->usr2UsrInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfoA, 0, sizeof(siConEvnt->usr2UsrInfoA)); +#endif + if (siConEvnt->connReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReq, 0, sizeof(siConEvnt->connReq)); + if (siConEvnt->origCdNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCdNum, 0, sizeof(siConEvnt->origCdNum)); + if (siConEvnt->usr2UsrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfo, 0, sizeof(siConEvnt->usr2UsrInfo)); + if (siConEvnt->accTrnspt.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accTrnspt, 0, sizeof(siConEvnt->accTrnspt)); + if (siConEvnt->echoControl.eh.pres != PRSNT_NODEF) memset(&siConEvnt->echoControl, 0, sizeof(siConEvnt->echoControl)); +#if SS7_ANS88 + if (siConEvnt->redirInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfoA, 0, sizeof(siConEvnt->redirInfoA)); +#endif +#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) + if (siConEvnt->chargeNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->chargeNum, 0, sizeof(siConEvnt->chargeNum)); + if (siConEvnt->origLineInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origLineInf, 0, sizeof(siConEvnt->origLineInf)); +#endif + if (siConEvnt->usrServInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo, 0, sizeof(siConEvnt->usrServInfo)); + if (siConEvnt->usr2UsrInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInd, 0, sizeof(siConEvnt->usr2UsrInd)); + if (siConEvnt->propDly.eh.pres != PRSNT_NODEF) memset(&siConEvnt->propDly, 0, sizeof(siConEvnt->propDly)); + if (siConEvnt->usrServInfo1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo1, 0, sizeof(siConEvnt->usrServInfo1)); + if (siConEvnt->netFac.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netFac, 0, sizeof(siConEvnt->netFac)); +#ifdef SS7_CHINA + if (siConEvnt->orgPteCdeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCdeA, 0, sizeof(siConEvnt->orgPteCdeA)); +#endif + if (siConEvnt->orgPteCde.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCde, 0, sizeof(siConEvnt->orgPteCde)); + if (siConEvnt->genDigits.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigits, 0, sizeof(siConEvnt->genDigits)); + if (siConEvnt->genDigitsR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigitsR, 0, sizeof(siConEvnt->genDigitsR)); + if (siConEvnt->usrTSrvInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrTSrvInfo, 0, sizeof(siConEvnt->usrTSrvInfo)); + if (siConEvnt->remotOper.eh.pres != PRSNT_NODEF) memset(&siConEvnt->remotOper, 0, sizeof(siConEvnt->remotOper)); + if (siConEvnt->parmCom.eh.pres != PRSNT_NODEF) memset(&siConEvnt->parmCom, 0, sizeof(siConEvnt->parmCom)); +#if (SS7_ANS92 || SS7_ANS95) + if (siConEvnt->servCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->servCode, 0, sizeof(siConEvnt->servCode)); +#endif +#if SS7_ANS92 + if (siConEvnt->serviceAct1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct1, 0, sizeof(siConEvnt->serviceAct1)); +#endif +#if SS7_CHINA + if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2)); +#endif + if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2)); + if (siConEvnt->serviceAct.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct, 0, sizeof(siConEvnt->serviceAct)); + if (siConEvnt->mlppPrec.eh.pres != PRSNT_NODEF) memset(&siConEvnt->mlppPrec, 0, sizeof(siConEvnt->mlppPrec)); +#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT)) + if (siConEvnt->txMedUsPr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedUsPr, 0, sizeof(siConEvnt->txMedUsPr)); +#endif + if (siConEvnt->bckCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->bckCallInd, 0, sizeof(siConEvnt->bckCallInd)); + if (siConEvnt->cgPtyNum1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum1, 0, sizeof(siConEvnt->cgPtyNum1)); + if (siConEvnt->optBckCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalInd, 0, sizeof(siConEvnt->optBckCalInd)); +#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT) + if (siConEvnt->optBckCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalIndQ, 0, sizeof(siConEvnt->optBckCalIndQ)); +#endif + if (siConEvnt->connNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum, 0, sizeof(siConEvnt->connNum)); +#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT)) + if (siConEvnt->connNum2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum2, 0, sizeof(siConEvnt->connNum2)); +#endif + if (siConEvnt->accDelInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accDelInfo, 0, sizeof(siConEvnt->accDelInfo)); + if (siConEvnt->notifInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd, 0, sizeof(siConEvnt->notifInd)); + if (siConEvnt->notifIndR2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR2, 0, sizeof(siConEvnt->notifIndR2)); + if (siConEvnt->cllHstry.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cllHstry, 0, sizeof(siConEvnt->cllHstry)); + if (siConEvnt->genNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmb, 0, sizeof(siConEvnt->genNmb)); + if (siConEvnt->genNmbR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmbR, 0, sizeof(siConEvnt->genNmbR)); + if (siConEvnt->redirNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirNum, 0, sizeof(siConEvnt->redirNum)); + if (siConEvnt->redirRstr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirRstr, 0, sizeof(siConEvnt->redirRstr)); + +#if SS7_Q767IT + if (siConEvnt->backVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backVad, 0, sizeof(siConEvnt->backVad)); +#endif +#if SS7_SINGTEL + if (siConEvnt->cgPtyNumS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumS, 0, sizeof(siConEvnt->cgPtyNumS)); +#endif +#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL) + if (siConEvnt->businessGrp.eh.pres != PRSNT_NODEF) memset(&siConEvnt->businessGrp, 0, sizeof(siConEvnt->businessGrp)); + if (siConEvnt->infoInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoInd, 0, sizeof(siConEvnt->infoInd)); + if (siConEvnt->carrierId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierId, 0, sizeof(siConEvnt->carrierId)); + if (siConEvnt->carSelInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carSelInf, 0, sizeof(siConEvnt->carSelInf)); + if (siConEvnt->egress.eh.pres != PRSNT_NODEF) memset(&siConEvnt->egress, 0, sizeof(siConEvnt->egress)); + if (siConEvnt->genAddr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddr, 0, sizeof(siConEvnt->genAddr)); + if (siConEvnt->genAddrR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddrR, 0, sizeof(siConEvnt->genAddrR)); + if (siConEvnt->infoReqInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoReqInd, 0, sizeof(siConEvnt->infoReqInd)); + if (siConEvnt->jurisInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->jurisInf, 0, sizeof(siConEvnt->jurisInf)); + if (siConEvnt->netTransport.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netTransport, 0, sizeof(siConEvnt->netTransport)); + if (siConEvnt->specProcReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->specProcReq, 0, sizeof(siConEvnt->specProcReq)); + if (siConEvnt->transReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->transReq, 0, sizeof(siConEvnt->transReq)); +#endif +#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT)) +#if (SS7_ANS92 || SS7_ANS95) + if (siConEvnt->notifInd1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd1, 0, sizeof(siConEvnt->notifInd1)); + if (siConEvnt->notifIndR1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR1, 0, sizeof(siConEvnt->notifIndR1)); +#endif /* SS7_ANS92 */ +#endif /* SIT_PARAMETER || TDS_ROLL_UPGRADE_SUPPORT */ +#if (SS7_BELL || SS7_ANS95) + if (siConEvnt->genName.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genName, 0, sizeof(siConEvnt->genName)); +#endif +#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \ + SS7_BELL || SS7_ANS95 || SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ) + if (siConEvnt->hopCounter.eh.pres != PRSNT_NODEF) memset(&siConEvnt->hopCounter, 0, sizeof(siConEvnt->hopCounter)); +#endif +#if (SS7_BELL || SS7_ITU2000 || SS7_KZ) + if (siConEvnt->redirCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCap, 0, sizeof(siConEvnt->redirCap)); + if (siConEvnt->redirCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCntr, 0, sizeof(siConEvnt->redirCntr)); +#endif +#if (SS7_ETSI || SS7_FTZ) + if (siConEvnt->ccbsParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccbsParam, 0, sizeof(siConEvnt->ccbsParam)); + if (siConEvnt->freePhParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->freePhParam, 0, sizeof(siConEvnt->freePhParam)); +#endif +#ifdef SS7_FTZ + if (siConEvnt->naPaFF.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFF, 0, sizeof(siConEvnt->naPaFF)); + if (siConEvnt->naPaFE.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFE, 0, sizeof(siConEvnt->naPaFE)); + if (siConEvnt->naPaSSP.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSSP, 0, sizeof(siConEvnt->naPaSSP)); + if (siConEvnt->naPaCdPNO.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaCdPNO, 0, sizeof(siConEvnt->naPaCdPNO)); + if (siConEvnt->naPaSPV.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSPV, 0, sizeof(siConEvnt->naPaSPV)); + if (siConEvnt->naPaUKK.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaUKK, 0, sizeof(siConEvnt->naPaUKK)); +#endif +#if SS7_NTT + if (siConEvnt->msgAreaInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->msgAreaInfo, 0, sizeof(siConEvnt->msgAreaInfo)); + if (siConEvnt->subsNumber.eh.pres != PRSNT_NODEF) memset(&siConEvnt->subsNumber, 0, sizeof(siConEvnt->subsNumber)); + if (siConEvnt->rpCllngNo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->rpCllngNo, 0, sizeof(siConEvnt->rpCllngNo)); + if (siConEvnt->supplUserType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->supplUserType, 0, sizeof(siConEvnt->supplUserType)); + if (siConEvnt->carrierInfoTrans.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierInfoTrans, 0, sizeof(siConEvnt->carrierInfoTrans)); + if (siConEvnt->nwFuncType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->nwFuncType, 0, sizeof(siConEvnt->nwFuncType)); +#endif +#if SS7_ANS95 + if (siConEvnt->optrServicesInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optrServicesInfo, 0, sizeof(siConEvnt->optrServicesInfo)); +#endif +#if (SS7_ANS95 || SS7_ITU97 || SS7_RUSS2000|| SS7_ITU2000 || SS7_NZL || SS7_KZ) + if (siConEvnt->cirAsgnMap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cirAsgnMap, 0, sizeof(siConEvnt->cirAsgnMap)); +#endif +#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \ + SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ) + if (siConEvnt->displayInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->displayInfo, 0, sizeof(siConEvnt->displayInfo)); + if (siConEvnt->confTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->confTrtInd, 0, sizeof(siConEvnt->confTrtInd)); + if (siConEvnt->netMgmtControls.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netMgmtControls, 0, sizeof(siConEvnt->netMgmtControls)); + if (siConEvnt->correlationId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->correlationId, 0, sizeof(siConEvnt->correlationId)); + if (siConEvnt->callDivTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callDivTrtInd, 0, sizeof(siConEvnt->callDivTrtInd)); + if (siConEvnt->callInNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callInNmb, 0, sizeof(siConEvnt->callInNmb)); + if (siConEvnt->callOfferTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callOfferTrtInd, 0, sizeof(siConEvnt->callOfferTrtInd)); + if (siConEvnt->scfId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->scfId, 0, sizeof(siConEvnt->scfId)); + if (siConEvnt->uidCapInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->uidCapInd, 0, sizeof(siConEvnt->uidCapInd)); + if (siConEvnt->collCallReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->collCallReq, 0, sizeof(siConEvnt->collCallReq)); + if (siConEvnt->ccss.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccss, 0, sizeof(siConEvnt->ccss)); +#endif +#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ) + if (siConEvnt->backGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backGVNS, 0, sizeof(siConEvnt->backGVNS)); + if (siConEvnt->forwardGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->forwardGVNS, 0, sizeof(siConEvnt->forwardGVNS)); +#endif +#if (SS7_ETSIV3 || SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || \ + SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ) + if (siConEvnt->appTransParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->appTransParam, 0, sizeof(siConEvnt->appTransParam)); +#endif +#if (SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ) + if (siConEvnt->htrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->htrInfo, 0, sizeof(siConEvnt->htrInfo)); + if (siConEvnt->pivotCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCap, 0, sizeof(siConEvnt->pivotCap)); + if (siConEvnt->cadDirNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cadDirNmb, 0, sizeof(siConEvnt->cadDirNmb)); + if (siConEvnt->origCallInNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCallInNum, 0, sizeof(siConEvnt->origCallInNum)); + if (siConEvnt->calgGeoLoc.eh.pres != PRSNT_NODEF) memset(&siConEvnt->calgGeoLoc, 0, sizeof(siConEvnt->calgGeoLoc)); + if (siConEvnt->netRoutNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netRoutNum, 0, sizeof(siConEvnt->netRoutNum)); + if (siConEvnt->qonRelCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->qonRelCap, 0, sizeof(siConEvnt->qonRelCap)); + if (siConEvnt->pivotCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCntr, 0, sizeof(siConEvnt->pivotCntr)); + if (siConEvnt->pivotRtgFwInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgFwInfo, 0, sizeof(siConEvnt->pivotRtgFwInfo)); + if (siConEvnt->pivotRtgBkInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgBkInfo, 0, sizeof(siConEvnt->pivotRtgBkInfo)); + if (siConEvnt->numPortFwdInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->numPortFwdInfo, 0, sizeof(siConEvnt->numPortFwdInfo)); +#endif +#ifdef SS7_UK + if (siConEvnt->natFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalInd, 0, sizeof(siConEvnt->natFwdCalInd)); + if (siConEvnt->presntNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->presntNum, 0, sizeof(siConEvnt->presntNum)); + if (siConEvnt->lstDvrtLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->lstDvrtLineId, 0, sizeof(siConEvnt->lstDvrtLineId)); + if (siConEvnt->pcgLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pcgLineId, 0, sizeof(siConEvnt->pcgLineId)); + if (siConEvnt->natFwdCalIndLnk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalIndLnk, 0, sizeof(siConEvnt->natFwdCalIndLnk)); + if (siConEvnt->cdBascSrvcMrk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdBascSrvcMrk, 0, sizeof(siConEvnt->cdBascSrvcMrk)); +#endif /* SS7_UK */ +#if (defined(CGPN_CHK)) + if (siConEvnt->causeDgnCgPnChk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->causeDgnCgPnChk, 0, sizeof(siConEvnt->causeDgnCgPnChk)); +#endif + return FTDM_SUCCESS; +} + +ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt) +{ +#ifndef HAVE_ZLIB + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n"); + return FTDM_FAIL; +#else + unsigned ret_val = FTDM_FAIL; + char *compressed_iam = NULL; + char *url_encoded_iam = NULL; + uLongf len = sizeof(*siConEvnt); + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + + /* By default, Trillium does not memset their whole structure to zero for + * performance. But we want to memset all the IE's that are not present to + * optimize compressed size */ + sngss7_bufferzero_iam(siConEvnt); + + compressed_iam = ftdm_malloc(sizeof(*siConEvnt)); + if (!compressed_iam) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocate buffer for compressed_iam\n"); + goto done; + } + + /* Compress IAM structure to minimize buffer size */ + ret_val = compress((Bytef *)compressed_iam, &len, (const Bytef *)siConEvnt, (uLong)sizeof(*siConEvnt)); + if (ret_val != Z_OK) { + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to compress IAM (error:%d)\n", ret_val); + ret_val = FTDM_FAIL; + goto done; + } + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", len); + + /* Worst case: size will triple after url encode */ + url_encoded_iam = ftdm_malloc(3*sizeof(*siConEvnt)); + if (!url_encoded_iam) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocated buffer for url_encoded_iam\n"); + ret_val = FTDM_FAIL; + goto done; + } + memset(url_encoded_iam, 0, 2*sizeof(*siConEvnt)); + + /* URL encode buffer to that its safe to store it in a string */ + ftdm_url_encode((const char*)compressed_iam, url_encoded_iam, len); + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(url_encoded_iam)); + + if (strlen(url_encoded_iam) > g_ftdm_sngss7_data.cfg.transparent_iam_max_size) { + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%d max:%d) \n", strlen(url_encoded_iam), g_ftdm_sngss7_data.cfg.transparent_iam_max_size); + ret_val = FTDM_FAIL; + goto done; + } + + sngss7_add_var(sngss7_info, "ss7_iam", url_encoded_iam); +done: + ftdm_safe_free(compressed_iam); + ftdm_safe_free(url_encoded_iam); + return ret_val; +#endif +} + +ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt) +{ +#ifndef HAVE_ZLIB + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n"); + return FTDM_FAIL; +#else + uLongf len = 3*sizeof(*siConEvnt); /* worst case: URL encoded buffer is 3x length of buffer */ + char *val = NULL; + unsigned ret_val = FTDM_FAIL; + void *uncompressed_buffer = NULL; + char *url_encoded_iam = NULL; + ftdm_size_t url_encoded_iam_len; + + val = (char*)ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam"); + if (ftdm_strlen_zero(val)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Transparent IAM info available\n"); + return FTDM_FAIL; + } + + url_encoded_iam = ftdm_strdup(val); + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(val)); + ftdm_url_decode(url_encoded_iam, &url_encoded_iam_len); + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", url_encoded_iam_len); + + uncompressed_buffer = ftdm_malloc(sizeof(*siConEvnt)); + ftdm_assert_return(uncompressed_buffer, FTDM_FAIL, "Failed to allocate buffer for uncompressed buffer\n"); + + ret_val = uncompress(uncompressed_buffer, &len, (const Bytef *)url_encoded_iam, (uLong)url_encoded_iam_len); + if (ret_val != Z_OK) { + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to uncompress IAM (error:%d)\n", ret_val); + goto done; + } + + if (len != sizeof(*siConEvnt)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Incompatible IAM structure size (expected:%d size:%d)\n", sizeof(*siConEvnt), strlen(uncompressed_buffer)); + goto done; + } + + memcpy(siConEvnt, uncompressed_buffer, sizeof(*siConEvnt)); + ret_val = FTDM_SUCCESS; + +done: + ftdm_safe_free(uncompressed_buffer); + ftdm_safe_free(url_encoded_iam); + return ret_val; +#endif +} + /******************************************************************************/ /* For Emacs: * Local Variables: 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 815377b476..a891c50108 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 @@ -124,6 +124,8 @@ typedef struct sng_ccSpan uint32_t cld_nadi; uint32_t rdnis_nadi; uint32_t min_digits; + uint8_t itx_auto_reply; + uint8_t transparent_iam; uint32_t t3; uint32_t t12; uint32_t t13; @@ -465,6 +467,9 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen) SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license); SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature); /**********************************************************************/ + } else if (!strcasecmp(parm->var, "transparent_iam_max_size")) { + g_ftdm_sngss7_data.cfg.transparent_iam_max_size = atoi(parm->val); + SS7_DEBUG("Found a transparent_iam max size = %d\n", g_ftdm_sngss7_data.cfg.transparent_iam_max_size); } else { /**********************************************************************/ SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); @@ -1892,7 +1897,16 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span) sng_ccSpan.typeCntrl = sng_cic_cntrl_type_map[ret].tril_type; SS7_DEBUG("Found an ccSpan typeCntrl = %s\n", sng_cic_cntrl_type_map[ret].sng_type); } - /**********************************************************************/ + } else if (!strcasecmp(parm->var, "itx_auto_reply")) { + sng_ccSpan.itx_auto_reply = ftdm_true(parm->val); + SS7_DEBUG("Found itx_auto_reply %d\n", sng_ccSpan.itx_auto_reply); + } else if (!strcasecmp(parm->var, "transparent_iam")) { +#ifndef HAVE_ZLIB + SS7_CRIT("Cannot enable transparent IAM becauze zlib not installed\n"); +#else + sng_ccSpan.transparent_iam = ftdm_true(parm->val); + SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam); +#endif } else if (!strcasecmp(parm->var, "cicbase")) { /**********************************************************************/ sng_ccSpan.cicbase = atoi(parm->val); @@ -2904,15 +2918,17 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0; } - g_ftdm_sngss7_data.cfg.isupCkt[x].infId = ccSpan->isupInf; - g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = ccSpan->typeCntrl; - g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf; - g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi; - g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi; - g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi; - g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options; - g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType; - g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits; + g_ftdm_sngss7_data.cfg.isupCkt[x].infId = ccSpan->isupInf; + g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = ccSpan->typeCntrl; + g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf; + g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi; + g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi; + g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi; + g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options; + g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType; + g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits; + g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply; + g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam; if (ccSpan->t3 == 0) { g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200; diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 20a173abb2..2bf9f6bc2e 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -950,7 +950,6 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx static FIO_READ_FUNCTION(wanpipe_read) { int rx_len = 0; - int myerrno = 0; wp_tdm_api_rx_hdr_t hdrframe; memset(&hdrframe, 0, sizeof(hdrframe)); @@ -964,7 +963,6 @@ static FIO_READ_FUNCTION(wanpipe_read) } if (rx_len < 0) { - myerrno = errno; snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno)); ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len); return FTDM_FAIL; @@ -1269,7 +1267,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status); ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? FTDM_ALARM_RED : FTDM_ALARM_NONE; ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Link status is %d\n", sangoma_status); - } + } } if (alarms) { @@ -1293,6 +1291,7 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type) { case WP_API_EVENT_LINK_STATUS: { + if (FTDM_IS_DIGITAL_CHANNEL(fchan)) { switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) { case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: /* *event_id = FTDM_OOB_ALARM_CLEAR; */ @@ -1305,6 +1304,22 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc }; /* The WP_API_EVENT_ALARM event should be used to clear alarms */ *event_id = FTDM_OOB_NOOP; + } else { + switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) { + case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: + /* *event_id = FTDM_OOB_ALARM_CLEAR; */ + ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link connected event as alarm clear\n"); + *event_id = FTDM_OOB_ALARM_CLEAR; + fchan->alarm_flags = FTDM_ALARM_NONE; + break; + default: + /* *event_id = FTDM_OOB_ALARM_TRAP; */ + ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link disconnected event as alarm trap\n"); + *event_id = FTDM_OOB_ALARM_TRAP; + fchan->alarm_flags = FTDM_ALARM_RED; + break; + }; + } } break; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 6ab518a6e3..253f256ffa 100755 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -241,12 +241,12 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t) /*! Numbering Plan Identification (NPI) */ typedef enum { FTDM_NPI_UNKNOWN = 0, - FTDM_NPI_ISDN = 1, - FTDM_NPI_DATA = 3, - FTDM_NPI_TELEX = 4, - FTDM_NPI_NATIONAL = 8, - FTDM_NPI_PRIVATE = 9, - FTDM_NPI_RESERVED = 10, + FTDM_NPI_ISDN, + FTDM_NPI_DATA, + FTDM_NPI_TELEX, + FTDM_NPI_NATIONAL, + FTDM_NPI_PRIVATE, + FTDM_NPI_RESERVED, FTDM_NPI_INVALID } ftdm_npi_t; #define NPI_STRINGS "unknown", "ISDN", "data", "telex", "national", "private", "reserved", "invalid" @@ -276,12 +276,16 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t) /*! \brief bearer capability */ typedef enum { - FTDM_BEARER_CAP_SPEECH = 0x00, - FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02, - FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03, + FTDM_BEARER_CAP_SPEECH = 0x00, /* Speech */ + FTDM_BEARER_CAP_UNRESTRICTED, /* Unrestricted Digital */ + FTDM_BEARER_CAP_RESTRICTED, /* Restricted Digital */ + FTDM_BEARER_CAP_3_1KHZ_AUDIO, /* 3.1 Khz Audio */ + FTDM_BEARER_CAP_7KHZ_AUDIO, /* 7 Khz Audio or Unrestricted digital w tones */ + FTDM_BEARER_CAP_15KHZ_AUDIO, /* 15 Khz Audio */ + FTDM_BEARER_CAP_VIDEO, /* Video */ FTDM_BEARER_CAP_INVALID } ftdm_bearer_cap_t; -#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "3.1-Khz-audio", "invalid" +#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "restricted-digital-information", "3.1-Khz-audio", "7-Khz-audio", "15-Khz-audio", "video", "invalid" FTDM_STR2ENUM_P(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t) /*! \brief user information layer 1 protocol */ @@ -298,6 +302,11 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_u typedef enum { FTDM_CPC_UNKNOWN, FTDM_CPC_OPERATOR, + FTDM_CPC_OPERATOR_FRENCH, + FTDM_CPC_OPERATOR_ENGLISH, + FTDM_CPC_OPERATOR_GERMAN, + FTDM_CPC_OPERATOR_RUSSIAN, + FTDM_CPC_OPERATOR_SPANISH, FTDM_CPC_ORDINARY, FTDM_CPC_PRIORITY, FTDM_CPC_DATA, @@ -305,12 +314,14 @@ typedef enum { FTDM_CPC_PAYPHONE, FTDM_CPC_INVALID } ftdm_calling_party_category_t; -#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid" +#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "operator-french", "operator-english", "operator-german", "operator-russian", "operator-spanish", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid" FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t) /*! \brief Digit limit used in DNIS/ANI */ #define FTDM_DIGITS_LIMIT 25 +#define FTDM_SILENCE_VALUE(fchan) (fchan)->native_codec == FTDM_CODEC_ULAW ? 255 : (fchan)->native_codec == FTDM_CODEC_ALAW ? 0xD5 : 0x00 + /*! \brief Number abstraction */ typedef struct { char digits[FTDM_DIGITS_LIMIT]; diff --git a/libs/freetdm/src/include/ftdm_call_utils.h b/libs/freetdm/src/include/ftdm_call_utils.h index 2418273343..975e73e729 100644 --- a/libs/freetdm/src/include/ftdm_call_utils.h +++ b/libs/freetdm/src/include/ftdm_call_utils.h @@ -131,5 +131,24 @@ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number); */ FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target); +/*! + * \brief URL encode a buffer + * + * \param url buffer to convert + * \param buf target to save converted string to + * \param len size of buffer + * + * \retval pointer to converted string + */ +FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len); + +/*! + * \param s buffer to convert + * \param len size of buffer + * + * \retval pointer to converted string + */ +FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len); + #endif /* __FTDM_CALL_UTILS_H__ */ diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index b263b64a2d..e4d2b6900d 100755 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -249,6 +249,8 @@ typedef enum { #define FTDM_CHANNEL_IND_ACK_PENDING (1ULL << 34) /*!< There is someone blocking in the channel waiting for state completion */ #define FTDM_CHANNEL_BLOCKING (1ULL << 35) +/*!< Media is digital */ +#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36) #include "ftdm_state.h" diff --git a/libs/freetdm/src/libteletone_generate.c b/libs/freetdm/src/libteletone_generate.c index 7f37b7a258..c0d6a54349 100644 --- a/libs/freetdm/src/libteletone_generate.c +++ b/libs/freetdm/src/libteletone_generate.c @@ -273,7 +273,7 @@ TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd) { char *data = NULL, *cur = NULL, *end = NULL; - int var = 0, LOOPING = 0; + int LOOPING = 0; if (!cmd) { return -1; @@ -287,7 +287,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm cur = data; while (*cur) { - var = 0; if (*cur == ' ' || *cur == '\r' || *cur == '\n') { cur++; continue; @@ -298,7 +297,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm } if (*(cur + 1) == '=') { - var = 1; switch(*cur) { case 'c': ts->channels = atoi(cur + 2); diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 6793c3df61..bbf26ca5c9 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -242,7 +242,7 @@ static void default_logger(char *file, const char *func, int line, int level, ch vsnprintf(data, sizeof(data), fmt, ap); - fprintf(globals.log_stream, "%s:%d %s() %s", file, line, func, data); + fprintf(globals.log_stream, "%s:%d %s() %s", fp, line, func, data); va_end(ap); @@ -997,9 +997,9 @@ static int on_commands(void *user_data, ikspak *pak) uint8_t is_result = strcasecmp(type, "result") ? 0 : 1; uint8_t is_error = strcasecmp(type, "error") ? 0 : 1; iks *xml, *xsession, *xerror = NULL, *xredir = NULL; - struct iks_tag* tmp; + xml = iks_child (pak->x); - tmp = (struct iks_tag*) xml; + if (is_error) { if ((xerror = working_find(xml, "error"))) { char *code = iks_find_attrib(xerror, "code"); diff --git a/libs/libteletone/src/libteletone_generate.c b/libs/libteletone/src/libteletone_generate.c index ebf62822a4..a5cefac98d 100644 --- a/libs/libteletone/src/libteletone_generate.c +++ b/libs/libteletone/src/libteletone_generate.c @@ -321,7 +321,7 @@ static char *my_strdup (const char *s) TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd) { char *data = NULL, *cur = NULL, *end = NULL; - int var = 0, LOOPING = 0; + int LOOPING = 0; if (!cmd) { return -1; @@ -335,7 +335,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm cur = data; while (*cur) { - var = 0; if (*cur == ' ' || *cur == '\r' || *cur == '\n') { cur++; continue; @@ -346,7 +345,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm } if (*(cur + 1) == '=') { - var = 1; switch(*cur) { case 'c': ts->channels = atoi(cur + 2); diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index ecc88483f6..fafef50c36 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Tue Mar 22 15:01:49 CDT 2011 +Wed Apr 27 11:49:37 CDT 2011 diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c index a665e9d495..5a8f354fa5 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_date.c @@ -182,7 +182,7 @@ int time_d(char const **ss, issize_t msg_date_d(char const **ss, msg_time_t *date) { char const *s = *ss; - char const *wkday; + //char const *wkday; char const *tz; unsigned long day, year, hour, min, sec; int mon; @@ -190,7 +190,8 @@ issize_t msg_date_d(char const **ss, msg_time_t *date) if (!IS_TOKEN(*s) || !date) return -1; - wkday = s; skip_token(&s); if (*s == ',') s++; + //wkday = s; + skip_token(&s); if (*s == ',') s++; while (IS_LWS(*s)) s++; if (is_digit(*s)) { 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 a6c7d49ac6..bd1e63b478 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c +++ b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c @@ -550,7 +550,7 @@ int nea_server_shutdown(nea_server_t *nes, int retry_after) { nea_sub_t *s; - int status = 200; +// int status = 200; int in_callback; if (nes == NULL) @@ -576,8 +576,8 @@ int nea_server_shutdown(nea_server_t *nes, TAG_IF(!retry_after, NEATAG_REASON("deactivated")), TAG_IF(retry_after, NEATAG_RETRY_AFTER(retry_after)), TAG_END()); - else - status = 180; + //else + //status = 180; } nes->nes_in_callback = in_callback; diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index 543f0e135a..b96ec2ba5b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -2307,7 +2307,7 @@ int agent_init_via(nta_agent_t *self, tport_t *primaries, int use_maddr) /* Set via fields for the tports */ for (tp = primaries; tp; tp = tport_next(tp)) { - int maddr, first_via; + int maddr; tp_name_t tpn[1]; char const *comp = NULL; @@ -2339,8 +2339,6 @@ int agent_init_via(nta_agent_t *self, tport_t *primaries, int use_maddr) if (tport_has_tls(tp)) self->sa_tport_tls = 1; - first_via = 1; - ai = tport_get_address(tp); for (; ai; ai = ai->ai_next) { diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c index fd826e0e19..a0dcbb1c4e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_register.c @@ -1879,14 +1879,14 @@ int nua_registration_process_request(nua_registration_t *list, nta_incoming_t *irq, sip_t const *sip) { - sip_call_id_t *i; + //sip_call_id_t *i; nua_registration_t *nr; if (!outbound_targeted_request(sip)) return 0; /* Process by outbound... */ - i = sip->sip_call_id; + //i = sip->sip_call_id; for (nr = list; nr; nr = nr->nr_next) { outbound_t *ob = nr->nr_ob; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index 032c0a04f2..a35669dd3b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -1743,7 +1743,7 @@ static int nua_prack_client_request(nua_client_request_t *cr, nua_client_request_t *cri; int offer_sent = 0, answer_sent = 0, retval; int status = 0; char const *phrase = "PRACK Sent"; - uint32_t rseq = 0; + //uint32_t rseq = 0; if (du == NULL) /* Call terminated */ return nua_client_return(cr, SIP_481_NO_TRANSACTION, msg); @@ -1754,8 +1754,8 @@ static int nua_prack_client_request(nua_client_request_t *cr, cri = du->du_cr; - if (sip->sip_rack) - rseq = sip->sip_rack->ra_response; +// if (sip->sip_rack) +// rseq = sip->sip_rack->ra_response; if (cri->cr_offer_recv && !cri->cr_answer_sent) { if (nh->nh_soa == NULL) diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c index b6e0c01385..6455f4b5c8 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c @@ -1883,12 +1883,11 @@ static char *next(char **message, const char *sep, const char *strip) static int parsing_error(sdp_parser_t *p, char const *fmt, ...) { - int n; va_list ap; va_start(ap, fmt); memset(p->pr_error, 0, sizeof(p->pr_error)); - n = vsnprintf(p->pr_error, sizeof(p->pr_error), fmt, ap); + vsnprintf(p->pr_error, sizeof(p->pr_error), fmt, ap); va_end(ap); p->pr_ok = 0; diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c index e2852b446b..e94c6b6758 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_print.c @@ -685,9 +685,8 @@ static void printing_error(sdp_printer_t *p, const char *fmt, ...) va_list ap; if (p->pr_ok) { - int n; va_start(ap, fmt); - n = vsnprintf(p->pr_buffer, p->pr_bsiz, fmt, ap); + vsnprintf(p->pr_buffer, p->pr_bsiz, fmt, ap); va_end(ap); } 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 e00d3912d8..4152669bfd 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c @@ -1010,7 +1010,6 @@ int soa_sdp_mode_set(sdp_session_t const *user, int retval = 0, i, j; int hold_all; int inactive_all; - int inactive = 0; char const *hold_media = NULL; sdp_mode_t send_mode, recv_mode; @@ -1029,7 +1028,6 @@ int soa_sdp_mode_set(sdp_session_t const *user, for (sm = session->sdp_media; sm; sm = sm->m_next, rm = rm_next, i++) { rm_next = rm ? rm->m_next : NULL; - inactive = 0; if (sm->m_rejected) continue; diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c index e494571f54..ceb7d0f601 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c @@ -3636,6 +3636,10 @@ sres_decode_msg(sres_resolver_t *res, m_get_domain(name, sizeof(name), m, 0); /* Query domain */ qtype = m_get_uint16(m); /* Query type */ qclass = m_get_uint16(m); /* Query class */ + if (qtype && qclass) { + /* XXX: never mind these useless check, this is done to make compiler happy about unused value */ + } + } if (m->m_error) { diff --git a/libs/sofia-sip/libsofia-sip-ua/stun/stun.c b/libs/sofia-sip/libsofia-sip-ua/stun/stun.c index 09ecff41cb..d2fabe3329 100644 --- a/libs/sofia-sip/libsofia-sip-ua/stun/stun.c +++ b/libs/sofia-sip/libsofia-sip-ua/stun/stun.c @@ -673,12 +673,12 @@ static stun_request_t *stun_request_create(stun_discovery_t *sd) void stun_request_destroy(stun_request_t *req) { - stun_handle_t *sh; + //stun_handle_t *sh; assert(req); enter; - sh = req->sr_handle; + //sh = req->sr_handle; if (x_is_inserted(req, sr)) x_remove(req, sr); @@ -1140,14 +1140,14 @@ static stun_discovery_t *stun_discovery_create(stun_handle_t *sh, static int stun_discovery_destroy(stun_discovery_t *sd) { - stun_handle_t *sh; + //stun_handle_t *sh; enter; if (!sd) return errno = EFAULT, -1; - sh = sd->sd_handle; + //sh = sd->sd_handle; if (sd->sd_timer) su_timer_destroy(sd->sd_timer), sd->sd_timer = NULL; @@ -1883,7 +1883,7 @@ static int process_test_lifetime(stun_request_t *req, stun_msg_t *binding_respon stun_discovery_t *sd = req->sr_discovery; stun_request_t *new; stun_handle_t *sh = req->sr_handle; - su_localinfo_t *li; + //su_localinfo_t *li; su_sockaddr_t *sa; su_timer_t *sockfdy_timer = NULL; su_socket_t sockfdy = sd->sd_socket2; @@ -1954,7 +1954,7 @@ static int process_test_lifetime(stun_request_t *req, stun_msg_t *binding_respon /* Rock, we come from sockfdx */ process_binding_request(req, binding_response); - li = &req->sr_localinfo; + //li = &req->sr_localinfo; sa = req->sr_local_addr; stun_free_message(binding_response); @@ -1981,7 +1981,7 @@ static int process_test_lifetime(stun_request_t *req, stun_msg_t *binding_respon static int action_bind(stun_request_t *req, stun_msg_t *binding_response) { - su_localinfo_t *li = NULL; + //su_localinfo_t *li = NULL; su_sockaddr_t *sa = NULL; stun_discovery_t *sd = req->sr_discovery; stun_handle_t *sh = req->sr_handle; @@ -1992,7 +1992,7 @@ static int action_bind(stun_request_t *req, stun_msg_t *binding_response) process_binding_request(req, binding_response); - li = &req->sr_localinfo; + //li = &req->sr_localinfo; sa = req->sr_local_addr; memcpy(sd->sd_addr_seen_outside, sa, sizeof(su_sockaddr_t)); @@ -3039,7 +3039,7 @@ int stun_process_request(su_socket_t s, stun_msg_t *req, su_sockaddr_t mod_addr[1] = {{ 0 }}, src_addr[1] = {{ 0 }}, chg_addr[1] = {{ 0 }}; stun_attr_t *tmp, m_attr[1], s_attr[1], c_attr[1], **p; su_sockaddr_t to_addr; - int c, i; + int i; tmp = stun_get_attr(req->stun_attr, RESPONSE_ADDRESS); @@ -3071,20 +3071,20 @@ int stun_process_request(su_socket_t s, stun_msg_t *req, /* SOURCE-ADDRESS depends on CHANGE_REQUEST */ tmp = stun_get_attr(req->stun_attr, CHANGE_REQUEST); if (!tmp) { - c = 0; + //c = 0; } else { switch (((stun_attr_changerequest_t *) tmp->pattr)->value) { case STUN_CR_CHANGE_IP: - c = 1; + //c = 1; break; case STUN_CR_CHANGE_PORT: - c = 2; + //c = 2; break; case STUN_CR_CHANGE_IP | STUN_CR_CHANGE_PORT: /* bitwise or */ - c = 3; + //c = 3; break; default: diff --git a/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c b/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c index bfbfe77e41..86ef0b2c37 100644 --- a/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c +++ b/libs/sofia-sip/libsofia-sip-ua/stun/stun_dns.c @@ -163,7 +163,10 @@ stun_dns_lookup_t *stun_dns_lookup(stun_magic_t *magic, query = sres_query(self->stun_sres, priv_sres_cb, self, sres_type_srv, srvname); - } + if (query) { + /* TODO Just so compiler doesn't give error */ + } +} else { su_free(NULL, self), self = NULL; } diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c index edc47e5da9..51259ade1a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_alloc.c @@ -429,13 +429,13 @@ void *sub_alloc(su_home_t *home, if (sub == NULL || 3 * sub->sub_used > 2 * sub->sub_n) { /* Resize the hash table */ - size_t i, n, n2, used; + size_t i, n, n2; su_block_t *b2; if (sub) - n = home->suh_blocks->sub_n, n2 = 4 * n + 3, used = sub->sub_used; + n = home->suh_blocks->sub_n, n2 = 4 * n + 3; //, used = sub->sub_used; else - n = 0, n2 = SUB_N, used = 0; + n = 0, n2 = SUB_N; //, used = 0; #if 0 printf("su_alloc(home = %p): realloc block hash of size %d\n", home, n2); diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c index de7279e493..523599c7a7 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_localinfo.c @@ -194,7 +194,8 @@ static void li_sort(su_localinfo_t *i, su_localinfo_t **rresult); int su_getlocalinfo(su_localinfo_t const *hints, su_localinfo_t **return_localinfo) { - int error = 0, ip4 = 0, ip6 = 0; + int error = 0, ip4 = 0; + int ip6 = 0; su_localinfo_t *result = NULL, **rr = &result; su_localinfo_t hh[1] = {{ 0 }}; @@ -231,7 +232,11 @@ int su_getlocalinfo(su_localinfo_t const *hints, break; case 0: - ip6 = ip4 = 1; + ip4 = 1; +#if SU_HAVE_IN6 + ip6 = 1; +#endif + break; default: @@ -260,6 +265,9 @@ int su_getlocalinfo(su_localinfo_t const *hints, } #endif + if (ip6) { + /* Required to make compiler happy */ + } if (!result) error = ELI_NOADDRESS; diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_string.c b/libs/sofia-sip/libsofia-sip-ua/su/su_string.c index 6774d372b6..249e788389 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_string.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_string.c @@ -478,7 +478,7 @@ size_t su_memspn(const void *mem, size_t memlen, * of bytes not in @a reject. * * @param mem pointer to memory area - * @param memlen size of @a mem in bytes + *@param memlen size of @a mem in bytes * @param reject pointer to table containing bytes to reject * @param rejectlen size of @a reject table * diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c index a33b77f3e2..8ebab4fd31 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport.c @@ -1595,7 +1595,7 @@ int tport_bind_server(tport_master_t *mr, { char hostname[TPORT_HOSTPORTSIZE]; char const *canon = NULL, *host, *service; - int error = 0, not_supported, family = 0; + int error = 0, family = 0; tport_primary_t *pri = NULL, **tbf; su_addrinfo_t *ai, *res = NULL; unsigned port, port0, port1, old; @@ -1691,8 +1691,6 @@ int tport_bind_server(tport_master_t *mr, break; } - not_supported = 0; - if (port0 == 0 && port == 0) { port = port1 = ntohs(su->su_port); assert(public != tport_type_server || port != 0); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c index 55f67a9e2c..3233e1c616 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_stun.c @@ -170,10 +170,10 @@ void tport_stun_bind_cb(tport_primary_t *pri, stun_action_t action, stun_state_t event) { - tport_master_t *mr; + //tport_master_t *mr; SU_DEBUG_3(("%s: %s\n", __func__, stun_str_state(event))); - mr = pri->pri_master; + //mr = pri->pri_master; if (event == stun_discovery_done) { tport_stun_bind_done(pri, sh, sd); diff --git a/libs/sofia-sip/libsofia-sip-ua/url/url.c b/libs/sofia-sip/libsofia-sip-ua/url/url.c index bef523e5c9..71544735e1 100644 --- a/libs/sofia-sip/libsofia-sip-ua/url/url.c +++ b/libs/sofia-sip/libsofia-sip-ua/url/url.c @@ -567,7 +567,7 @@ static int _url_d(url_t *url, char *s) { size_t n, p; - char *s0, rest_c, *host, *user; + char rest_c, *host, *user; int have_authority = 1; memset(url, 0, sizeof(*url)); @@ -578,8 +578,6 @@ int _url_d(url_t *url, char *s) return 0; } - s0 = s; - n = strcspn(s, ":/?#"); if (n && s[n] == ':') { diff --git a/libs/spandsp/.update b/libs/spandsp/.update index c79813d90a..bbfb583730 100644 --- a/libs/spandsp/.update +++ b/libs/spandsp/.update @@ -1 +1 @@ -Mon Jun 7 20:09:38 EDT 2010 +Wed May 4 10:03:23 CDT 2011 diff --git a/libs/spandsp/src/plc.c b/libs/spandsp/src/plc.c index fb1cea78be..392a7b01a6 100644 --- a/libs/spandsp/src/plc.c +++ b/libs/spandsp/src/plc.c @@ -165,10 +165,10 @@ SPAN_DECLARE(int) plc_fillin(plc_state_t *s, int16_t amp[], int len) float old_weight; float new_weight; float gain; - int16_t *orig_amp; + //int16_t *orig_amp; int orig_len; - orig_amp = amp; + //orig_amp = amp; orig_len = len; if (s->missing_samples == 0) { diff --git a/libs/spandsp/src/t38_core.c b/libs/spandsp/src/t38_core.c index e7ee967e93..55b524af61 100644 --- a/libs/spandsp/src/t38_core.c +++ b/libs/spandsp/src/t38_core.c @@ -799,7 +799,11 @@ SPAN_DECLARE(int) t38_core_send_indicator(t38_core_state_t *s, int indicator) return len; } span_log(&s->logging, SPAN_LOG_FLOW, "Tx %5d: indicator %s\n", s->tx_seq_no, t38_indicator_to_str(indicator)); - s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, transmissions); + if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, transmissions) < 0) + { + span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx Packet Handler Failure\n"); + return -1; + } s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF; delay = modem_startup_time[indicator].training; if (s->allow_for_tep) @@ -837,7 +841,11 @@ SPAN_DECLARE(int) t38_core_send_data(t38_core_state_t *s, int data_type, int fie span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len); return len; } - s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]); + if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]) < 0) + { + span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx Packet Handler Failure\n"); + return -1; + } s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF; return 0; } @@ -853,7 +861,11 @@ SPAN_DECLARE(int) t38_core_send_data_multi_field(t38_core_state_t *s, int data_t span_log(&s->logging, SPAN_LOG_FLOW, "T.38 data len is %d\n", len); return len; } - s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]); + if (s->tx_packet_handler(s, s->tx_packet_user_data, buf, len, s->category_control[category]) < 0) + { + span_log(&s->logging, SPAN_LOG_PROTOCOL_WARNING, "Tx Packet Handler Failure\n"); + return -1; + } s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF; return 0; } diff --git a/libs/spandsp/src/t38_terminal.c b/libs/spandsp/src/t38_terminal.c index c9961f665b..64b30f4805 100644 --- a/libs/spandsp/src/t38_terminal.c +++ b/libs/spandsp/src/t38_terminal.c @@ -63,10 +63,18 @@ #include "spandsp/v17rx.h" #include "spandsp/t4_rx.h" #include "spandsp/t4_tx.h" -#if defined(SPANDSP_SUPPORT_T85) +#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85) #include "spandsp/t81_t82_arith_coding.h" +#endif +#if defined(SPANDSP_SUPPORT_T85) #include "spandsp/t85.h" #endif +#if defined(SPANDSP_SUPPORT_T42) +#include "spandsp/t42.h" +#endif +#if defined(SPANDSP_SUPPORT_T43) +#include "spandsp/t43.h" +#endif #include "spandsp/t4_t6_decode.h" #include "spandsp/t4_t6_encode.h" #include "spandsp/t30_fcf.h" @@ -78,10 +86,18 @@ #include "spandsp/t38_terminal.h" #include "spandsp/private/logging.h" -#if defined(SPANDSP_SUPPORT_T85) +#if defined(SPANDSP_SUPPORT_T42) || defined(SPANDSP_SUPPORT_T43) | defined(SPANDSP_SUPPORT_T85) #include "spandsp/private/t81_t82_arith_coding.h" +#endif +#if defined(SPANDSP_SUPPORT_T85) #include "spandsp/private/t85.h" #endif +#if defined(SPANDSP_SUPPORT_T42) +#include "spandsp/private/t42.h" +#endif +#if defined(SPANDSP_SUPPORT_T43) +#include "spandsp/private/t43.h" +#endif #include "spandsp/private/t4_t6_decode.h" #include "spandsp/private/t4_t6_encode.h" #include "spandsp/private/t4_rx.h" @@ -629,7 +645,9 @@ static int set_no_signal(t38_terminal_state_t *s) if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS)) { - t38_core_send_indicator(&s->t38_fe.t38, 0x100 | T38_IND_NO_SIGNAL); + if ((delay = t38_core_send_indicator(&s->t38_fe.t38, 0x100 | T38_IND_NO_SIGNAL)) < 0) + return delay; + /*endif*/ s->t38_fe.timed_step = T38_TIMED_STEP_NO_SIGNAL; #if 0 if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_2S_REGULAR_INDICATORS)) @@ -641,7 +659,9 @@ static int set_no_signal(t38_terminal_state_t *s) return s->t38_fe.ms_per_tx_chunk*1000; } /*endif*/ - delay = t38_core_send_indicator(&s->t38_fe.t38, T38_IND_NO_SIGNAL); + if ((delay = t38_core_send_indicator(&s->t38_fe.t38, T38_IND_NO_SIGNAL)) < 0) + return delay; + /*endif*/ s->t38_fe.timed_step = T38_TIMED_STEP_NONE; return delay; } @@ -649,7 +669,11 @@ static int set_no_signal(t38_terminal_state_t *s) static int stream_no_signal(t38_terminal_state_t *s) { - t38_core_send_indicator(&s->t38_fe.t38, 0x100 | T38_IND_NO_SIGNAL); + int delay; + + if ((delay = t38_core_send_indicator(&s->t38_fe.t38, 0x100 | T38_IND_NO_SIGNAL)) < 0) + return delay; + /*endif*/ #if 0 if (s->t38_fe.timeout_tx_samples && s->t38_fe.next_tx_samples >= s->t38_fe.timeout_tx_samples) s->t38_fe.timed_step = T38_TIMED_STEP_NONE; @@ -663,6 +687,7 @@ static int stream_non_ecm(t38_terminal_state_t *s) { t38_terminal_front_end_state_t *fe; uint8_t buf[MAX_OCTETS_PER_UNPACED_CHUNK + 50]; + int res; int delay; int len; @@ -674,9 +699,15 @@ static int stream_non_ecm(t38_terminal_state_t *s) case T38_TIMED_STEP_NON_ECM_MODEM: /* Create a 75ms silence */ if (fe->t38.current_tx_indicator != T38_IND_NO_SIGNAL) - delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL); + { + if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0) + return delay; + /*endif*/ + } else + { delay = 75000; + } /*endif*/ fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_2; #if 0 @@ -690,7 +721,9 @@ static int stream_non_ecm(t38_terminal_state_t *s) #if 0 if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS)) { - delay = t38_core_send_indicator(&fe->t38, 0x100 | fe->next_tx_indicator); + if ((delay = t38_core_send_indicator(&fe->t38, 0x100 | fe->next_tx_indicator)) < 0) + return delay; + /*endif*/ if (fe->next_tx_samples >= fe->timeout_tx_samples) fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_3; /*endif*/ @@ -698,7 +731,9 @@ static int stream_non_ecm(t38_terminal_state_t *s) } /*endif*/ #endif - delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator); + if ((delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator)) < 0) + return delay; + /*endif*/ fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_3; break; case T38_TIMED_STEP_NON_ECM_MODEM_3: @@ -731,7 +766,9 @@ static int stream_non_ecm(t38_terminal_state_t *s) else { /* If we are sending quickly there seems no point in doing any padding */ - t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END); + if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END)) < 0) + return res; + /*endif*/ fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5; delay = 0; break; @@ -739,7 +776,9 @@ static int stream_non_ecm(t38_terminal_state_t *s) /*endif*/ } /*endif*/ - t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA); + if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA)) < 0) + return res; + /*endif*/ delay = bits_to_us(s, 8*len); break; case T38_TIMED_STEP_NON_ECM_MODEM_4: @@ -750,7 +789,9 @@ static int stream_non_ecm(t38_terminal_state_t *s) { len += fe->non_ecm_trailer_bytes; memset(buf, 0, len); - t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END); + if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA_END)) < 0) + return res; + /*endif*/ fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5; /* Allow a bit more time than the data will take to play out, to ensure the far ATA does not cut things short. */ @@ -763,7 +804,9 @@ static int stream_non_ecm(t38_terminal_state_t *s) } /*endif*/ memset(buf, 0, len); - t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA); + if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, T38_PACKET_CATEGORY_IMAGE_DATA)) < 0) + return res; + /*endif*/ delay = bits_to_us(s, 8*len); break; case T38_TIMED_STEP_NON_ECM_MODEM_5: @@ -785,6 +828,7 @@ static int stream_hdlc(t38_terminal_state_t *s) t38_data_field_t data_fields[2]; int category; int previous; + int res; int delay; int i; @@ -796,9 +840,15 @@ static int stream_hdlc(t38_terminal_state_t *s) case T38_TIMED_STEP_HDLC_MODEM: /* Create a 75ms silence */ if (fe->t38.current_tx_indicator != T38_IND_NO_SIGNAL) - delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL); + { + if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0) + return delay; + /*endif*/ + } else + { delay = 75000; + } /*endif*/ fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_2; #if 0 @@ -814,7 +864,9 @@ static int stream_hdlc(t38_terminal_state_t *s) #if 0 if ((s->t38_fe.chunking_modes & T38_CHUNKING_SEND_REGULAR_INDICATORS)) { - delay = t38_core_send_indicator(&fe->t38, 0x100 | fe->next_tx_indicator); + if ((delay = t38_core_send_indicator(&fe->t38, 0x100 | fe->next_tx_indicator)) < 0) + return delay; + /*endif*/ if (fe->next_tx_samples >= fe->timeout_tx_samples) fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3; /*endif*/ @@ -822,8 +874,10 @@ static int stream_hdlc(t38_terminal_state_t *s) } /*endif*/ #endif - delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator) - + t38_core_send_flags_delay(&fe->t38, fe->next_tx_indicator); + if ((delay = t38_core_send_indicator(&fe->t38, fe->next_tx_indicator)) < 0) + return delay; + /*endif*/ + delay += t38_core_send_flags_delay(&fe->t38, fe->next_tx_indicator); fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3; break; case T38_TIMED_STEP_HDLC_MODEM_3: @@ -852,7 +906,9 @@ static int stream_hdlc(t38_terminal_state_t *s) data_fields[1].field = NULL; data_fields[1].field_len = 0; category = (s->t38_fe.current_tx_data_type == T38_DATA_V21) ? T38_PACKET_CATEGORY_CONTROL_DATA_END : T38_PACKET_CATEGORY_IMAGE_DATA_END; - t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category); + if ((res = t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category)) < 0) + return res; + /*endif*/ fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_5; /* We add a bit of extra time here, as with some implementations the carrier falling too abruptly causes data loss. */ @@ -868,7 +924,9 @@ static int stream_hdlc(t38_terminal_state_t *s) data_fields[1].field = NULL; data_fields[1].field_len = 0; category = (s->t38_fe.current_tx_data_type == T38_DATA_V21) ? T38_PACKET_CATEGORY_CONTROL_DATA : T38_PACKET_CATEGORY_IMAGE_DATA; - t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category); + if ((res = t38_core_send_data_multi_field(&fe->t38, fe->current_tx_data_type, data_fields, 2, category)) < 0) + return res; + /*endif*/ fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3; delay = bits_to_us(s, i*8 + fe->hdlc_tx.extra_bits); } @@ -877,14 +935,18 @@ static int stream_hdlc(t38_terminal_state_t *s) } /*endif*/ category = (s->t38_fe.current_tx_data_type == T38_DATA_V21) ? T38_PACKET_CATEGORY_CONTROL_DATA : T38_PACKET_CATEGORY_IMAGE_DATA; - t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &fe->hdlc_tx.buf[fe->hdlc_tx.ptr], i, category); + if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &fe->hdlc_tx.buf[fe->hdlc_tx.ptr], i, category)) < 0) + return res; + /*endif*/ fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_4; } else { i = fe->octets_per_data_packet; category = (s->t38_fe.current_tx_data_type == T38_DATA_V21) ? T38_PACKET_CATEGORY_CONTROL_DATA : T38_PACKET_CATEGORY_IMAGE_DATA; - t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &fe->hdlc_tx.buf[fe->hdlc_tx.ptr], i, category); + if ((res = t38_core_send_data(&fe->t38, fe->current_tx_data_type, T38_FIELD_HDLC_DATA, &fe->hdlc_tx.buf[fe->hdlc_tx.ptr], i, category)) < 0) + return res; + /*endif*/ fe->hdlc_tx.ptr += i; } /*endif*/ @@ -901,7 +963,9 @@ static int stream_hdlc(t38_terminal_state_t *s) { /* End of transmission */ category = (s->t38_fe.current_tx_data_type == T38_DATA_V21) ? T38_PACKET_CATEGORY_CONTROL_DATA_END : T38_PACKET_CATEGORY_IMAGE_DATA_END; - t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK_SIG_END, NULL, 0, category); + if ((res = t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK_SIG_END, NULL, 0, category)) < 0) + return res; + /*endif*/ fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_5; /* We add a bit of extra time here, as with some implementations the carrier falling too abruptly causes data loss. */ @@ -922,7 +986,9 @@ static int stream_hdlc(t38_terminal_state_t *s) /*endif*/ /* Finish the current frame off, and prepare for the next one. */ category = (s->t38_fe.current_tx_data_type == T38_DATA_V21) ? T38_PACKET_CATEGORY_CONTROL_DATA : T38_PACKET_CATEGORY_IMAGE_DATA; - t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK, NULL, 0, category); + if ((res = t38_core_send_data(&fe->t38, previous, T38_FIELD_HDLC_FCS_OK, NULL, 0, category)) < 0) + return res; + /*endif*/ fe->timed_step = T38_TIMED_STEP_HDLC_MODEM_3; /* We should now wait enough time for everything to clear through an analogue modem at the far end. */ delay = bits_to_us(s, fe->hdlc_tx.extra_bits); @@ -955,14 +1021,18 @@ static int stream_ced(t38_terminal_state_t *s) of silence, starting the delay with a no signal indication makes sense. We do need a 200ms delay, as that is a specification requirement. */ fe->timed_step = T38_TIMED_STEP_CED_2; - delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL); + if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0) + return delay; + /*endif*/ delay = 200000; fe->next_tx_samples = fe->samples; break; case T38_TIMED_STEP_CED_2: /* Initial 200ms delay over. Send the CED indicator */ fe->timed_step = T38_TIMED_STEP_CED_3; - delay = t38_core_send_indicator(&fe->t38, T38_IND_CED); + if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_CED)) < 0) + return delay; + /*endif*/ fe->current_tx_data_type = T38_DATA_NONE; break; case T38_TIMED_STEP_CED_3: @@ -994,7 +1064,9 @@ static int stream_cng(t38_terminal_state_t *s) be sending 200ms of silence, according to T.30, starting that delay with a no signal indication makes sense. */ fe->timed_step = T38_TIMED_STEP_CNG_2; - delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL); + if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_NO_SIGNAL)) < 0) + return delay; + /*endif*/ delay = 200000; fe->next_tx_samples = fe->samples; break; @@ -1003,7 +1075,9 @@ static int stream_cng(t38_terminal_state_t *s) coming the other way interrupts it, or a long timeout controlled by the T.30 engine expires. */ fe->timed_step = T38_TIMED_STEP_NONE; - delay = t38_core_send_indicator(&fe->t38, T38_IND_CNG); + if ((delay = t38_core_send_indicator(&fe->t38, T38_IND_CNG)) < 0) + return delay; + /*endif*/ fe->current_tx_data_type = T38_DATA_NONE; return delay; } @@ -1067,6 +1141,12 @@ SPAN_DECLARE(int) t38_terminal_send_timeout(t38_terminal_state_t *s, int samples break; } /*endswitch*/ + if (delay < 0) + { + t30_terminate(&s->t30); + return TRUE; + } + /*endif*/ fe->next_tx_samples += us_to_samples(delay); return FALSE; } diff --git a/libs/sqlite/src/sqliteInt.h b/libs/sqlite/src/sqliteInt.h index 6483912cc9..3686a091e7 100644 --- a/libs/sqlite/src/sqliteInt.h +++ b/libs/sqlite/src/sqliteInt.h @@ -297,7 +297,7 @@ static inline char *strndup_lite(const char *s, size_t n) #define sqliteMalloc(x) zmalloc(x)//sqlite3Malloc(x,1) #define sqliteMallocRaw(x) malloc(x)//sqlite3MallocRaw(x,1) #define sqliteRealloc(x,y) realloc(x, y)//sqlite3Realloc(x,y) -#define sqliteStrDup(x) strdup(x)//sqlite3StrDup(x) +#define sqliteStrDup(x) (x?strdup(x):NULL)//sqlite3StrDup(x) #define sqliteStrNDup(x,y) strndup_lite(x,y) //sqlite3StrNDup(x,y) #define sqliteReallocOrFree(x,y) sqlite3ReallocOrFree(x,y) diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index d8797f7cd0..a4c3bb78d3 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -76,6 +76,7 @@ struct stfu_instance { uint32_t miss_count; uint32_t max_plc; uint32_t qlen; + uint32_t most_qlen; uint32_t max_qlen; uint32_t orig_qlen; uint32_t packet_count; @@ -136,6 +137,11 @@ int32_t stfu_n_get_drift(stfu_instance_t *i) return i->ts_drift; } +int32_t stfu_n_get_most_qlen(stfu_instance_t *i) +{ + return i->most_qlen; +} + void stfu_global_set_logger(stfu_logger_t logger) { if (logger) { @@ -253,6 +259,10 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) s = stfu_n_resize_aqueue(&i->b_queue, qlen); s = stfu_n_resize_aqueue(&i->c_queue, qlen); + if (qlen > i->most_qlen) { + i->most_qlen = qlen; + } + i->qlen = qlen; i->max_plc = 5; i->last_frame = NULL; @@ -506,9 +516,9 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void i->diff_total += i->diff; if ((i->period_packet_in_count > i->period_time)) { - uint32_t avg; + //uint32_t avg; - avg = i->diff_total / least1(i->period_packet_in_count); + //avg = i->diff_total / least1(i->period_packet_in_count); i->period_packet_in_count = 0; @@ -904,7 +914,7 @@ static void default_logger(const char *file, const char *func, int line, int lev ret = stfu_vasprintf(&data, fmt, ap); if (ret != -1) { - fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], file, line, func, data); + fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data); free(data); } diff --git a/libs/stfu/stfu.h b/libs/stfu/stfu.h index d8fbf447af..b802bbaef6 100644 --- a/libs/stfu/stfu.h +++ b/libs/stfu/stfu.h @@ -188,6 +188,7 @@ stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets); void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata); void stfu_n_debug(stfu_instance_t *i, const char *name); int32_t stfu_n_get_drift(stfu_instance_t *i); +int32_t stfu_n_get_most_qlen(stfu_instance_t *i); #define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 0, 1) #define stfu_n_eat(i,t,p,d,l,tt) stfu_n_add_data(i, t, p, d, l, tt, 0) diff --git a/scripts/lua/sound_test.lua b/scripts/lua/sound_test.lua new file mode 100644 index 0000000000..e29c2f9ca7 --- /dev/null +++ b/scripts/lua/sound_test.lua @@ -0,0 +1,74 @@ +-- +-- sound_test.lua +-- +-- accepts two args and then rolls through the sound files +-- arg 1: type +-- arg 2: rate +-- +--[[ Use a dialplan entry like this: + + + + + + + + +Note the syntax of the destination number: +Rate can be 8000, 16000, 32000, or 48000 +Type can be ivr, conference, voicemail, misc, digits, etc. + +Using the extension listed above you could call it with mod_portaudio from fs_cli: + + pa call 16000ivr + pa call 8000conference + pa call 32000conference + + etc. + +]] + +-- Create tables that hold our rates and types + +tbl_types = { + ['ascii'] = 1, + ['base256'] = 1, + ['conference'] = 1, + ['currency'] = 1, + ['digits'] = 1, + ['directory'] = 1, + ['ivr'] = 1, + ['misc'] = 1, + ['phonetic-ascii'] = 1, + ['time'] = 1, + ['voicemail'] = 1, + ['zrtp'] = 1 +}; + +tbl_rates = {['8000'] = 1 ,['16000'] = 1, ['32000'] = 1, ['48000'] = 1}; + +stype = argv[1]; +srate = argv[2]; + +freeswitch.consoleLog("INFO","Args: Type = " .. argv[1] .. ', Rate = ' .. argv[2] .. "\n"); + +if ( tbl_types[stype] == nil ) then + freeswitch.consoleLog("ERR","Type '" .. stype .. "' is not valid.\n"); +elseif ( tbl_rates[srate] == nil ) then + freeswitch.consoleLog("ERR","Rate '" .. srate .. "' is not valid.\n"); +else + -- Looks good, let's play some sound files + sound_base = session:getVariable('sounds_dir') .. '/en/us/callie/' .. stype .. '/' .. srate; + input_file = '/tmp/filez.txt'; + res = os.execute('ls -1 ' .. sound_base .. ' > ' .. input_file); + freeswitch.consoleLog("INFO","Result of system call: " .. res .. "\n"); + if ( res == 0 ) then + for fname in io.lines(input_file) do + freeswitch.consoleLog("NOTICE","Playing file: " .. fname .. "\n"); + session:streamFile(sound_base .. '/' .. fname); + session:sleep(100); + end + else + freeswitch.consoleLog("ERR","Result of system call: " .. res .. "\n"); + end +end \ No newline at end of file diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 0ef64d1079..8c1ac3707c 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -240,6 +240,7 @@ struct switch_runtime { uint32_t debug_level; uint32_t runlevel; uint32_t tipping_point; + uint32_t microseconds_per_tick; int32_t timer_affinity; switch_profile_timer_t *profile_timer; double profile_time; @@ -248,9 +249,12 @@ struct switch_runtime { int max_sql_buffer_len; switch_dbtype_t odbc_dbtype; char hostname[256]; + char *switchname; int multiple_registrations; uint32_t max_db_handles; uint32_t db_handle_timeout; + int curl_count; + int ssl_count; }; extern struct switch_runtime runtime; diff --git a/src/include/switch_caller.h b/src/include/switch_caller.h index bd53a04f68..fde3372105 100644 --- a/src/include/switch_caller.h +++ b/src/include/switch_caller.h @@ -56,6 +56,15 @@ #include SWITCH_BEGIN_EXTERN_C + +typedef struct profile_node_s { + char *var; + char *val; + struct profile_node_s *next; +} profile_node_t; + + + /*! \brief Call Specific Data */ struct switch_caller_profile { @@ -110,6 +119,7 @@ SWITCH_BEGIN_EXTERN_C switch_memory_pool_t *pool; struct switch_caller_profile *next; switch_call_direction_t direction; + profile_node_t *soft; }; /*! \brief An Abstract Representation of a dialplan Application */ diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index febaf40f75..dc8175b202 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -49,6 +49,7 @@ SWITCH_BEGIN_EXTERN_C struct switch_channel_timetable { switch_time_t hungup; switch_time_t transferred; switch_time_t resurrected; + switch_time_t bridged; struct switch_channel_timetable *next; }; @@ -597,7 +598,7 @@ SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *app, switch_cha #define switch_channel_clear_app_flag(_c, _f) switch_channel_clear_app_flag_key(__FILE__, _c, _f) #define switch_channel_test_app_flag(_c, _f) switch_channel_test_app_flag_key(__FILE__, _c, _f) - +SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel); SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel); SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel); SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel); diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 684cc4f777..ee890a80c9 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -57,6 +57,7 @@ SWITCH_BEGIN_EXTERN_C struct switch_app_log { char *app; char *arg; + switch_time_t stamp; struct switch_app_log *next; }; @@ -434,6 +435,9 @@ SWITCH_DECLARE(void) switch_core_session_rwunlock(_In_ switch_core_session_t *se */ SWITCH_DECLARE(int) switch_core_add_state_handler(_In_ const switch_state_handler_table_t *state_handler); +SWITCH_DECLARE(int) switch_core_curl_count(int *val); +SWITCH_DECLARE(int) switch_core_ssl_count(int *val); + /*! \brief Remove a global state handler \param state_handler the state handler to remove @@ -762,6 +766,7 @@ SWITCH_DECLARE(char *) switch_core_get_variable(_In_z_ const char *varname); SWITCH_DECLARE(char *) switch_core_get_variable_dup(_In_z_ const char *varname); SWITCH_DECLARE(char *) switch_core_get_variable_pdup(_In_z_ const char *varname, switch_memory_pool_t *pool); SWITCH_DECLARE(const char *) switch_core_get_hostname(void); +SWITCH_DECLARE(const char *) switch_core_get_switchname(void); /*! \brief Add a global variable to the core @@ -2205,6 +2210,7 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries); SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_cache_db_handle_t *dbh, char *sql, uint32_t retries); +SWITCH_DECLARE(void) switch_core_set_signal_handlers(void); 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); diff --git a/src/include/switch_curl.h b/src/include/switch_curl.h new file mode 100644 index 0000000000..3820ba8693 --- /dev/null +++ b/src/include/switch_curl.h @@ -0,0 +1,81 @@ +/* + * 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 / Soft-Switch Application + * + * 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): + * + * + * switch_curl.h + * + */ + +#ifndef __SWITCH_CURL_H +#define __SWITCH_CURL_H + +#include +#include + +static inline void switch_curl_init(void) +{ + int curl_count = switch_core_curl_count(NULL); + + if (curl_count == 0) { + curl_global_init(CURL_GLOBAL_ALL); +#if defined(HAVE_OPENSSL) + switch_ssl_init_ssl_locks(); +#endif + } + + curl_count++; + switch_core_curl_count(&curl_count); +} + +static inline void switch_curl_destroy() +{ + int curl_count = switch_core_curl_count(NULL); + + curl_count--; + + if (curl_count == 0) { + +#if defined(HAVE_OPENSSL) + switch_ssl_destroy_ssl_locks(); +#endif + curl_global_cleanup(); + } + switch_core_curl_count(&curl_count); +} + +#endif + + +/* 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/include/switch_event.h b/src/include/switch_event.h index 56acbd3a4b..9046bc711a 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -285,7 +285,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_free_subclass_detailed(const char * SWITCH_DECLARE(switch_status_t) switch_event_serialize(switch_event_t *event, char **str, switch_bool_t encode); SWITCH_DECLARE(switch_status_t) switch_event_serialize_json(switch_event_t *event, char **str); SWITCH_DECLARE(switch_status_t) switch_event_create_json(switch_event_t **event, const char *json); -SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data); +SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data, switch_bool_t dup); #ifndef SWIG /*! diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index 15b3277404..609dde8b7a 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -223,15 +223,15 @@ typedef intptr_t switch_ssize_t; #ifdef WIN32 #ifdef WIN64 -#define SWITCH_SSIZE_T_FMT "I64d" -#define SWITCH_SIZE_T_FMT "I64d" +#define SWITCH_SSIZE_T_FMT "lld" +#define SWITCH_SIZE_T_FMT "lld" #else #define SWITCH_SSIZE_T_FMT "d" #define SWITCH_SIZE_T_FMT "d" #endif -#define SWITCH_INT64_T_FMT "I64d" -#define SWITCH_UINT64_T_FMT "I64u" +#define SWITCH_INT64_T_FMT "lld" +#define SWITCH_UINT64_T_FMT "llu" #ifndef TIME_T_FMT #define TIME_T_FMT SWITCH_INT64_T_FMT diff --git a/src/include/switch_ssl.h b/src/include/switch_ssl.h new file mode 100644 index 0000000000..4f72192c52 --- /dev/null +++ b/src/include/switch_ssl.h @@ -0,0 +1,107 @@ +/* + * 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 / Soft-Switch Application + * + * 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): + * + * + * switch_ssl.h + * + */ + +#ifndef __SWITCH_SSL_H +#define __SWITCH_SSL_H + +#if defined(HAVE_OPENSSL) +#include + +static switch_mutex_t **ssl_mutexes; +static switch_memory_pool_t *ssl_pool = NULL; + + +static inline void switch_ssl_ssl_lock_callback(int mode, int type, char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + switch_mutex_lock(ssl_mutexes[type]); + } + else { + switch_mutex_unlock(ssl_mutexes[type]); + } +} + +static inline unsigned long switch_ssl_ssl_thread_id(void) +{ + return (unsigned long) switch_thread_self(); +} + +static inline void switch_ssl_init_ssl_locks(void) +{ + + int ssl_count = switch_core_ssl_count(NULL); + int i, num; + + if (ssl_count == 0) { + num = CRYPTO_num_locks(); + + ssl_mutexes = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(switch_mutex_t*)); + switch_assert(ssl_mutexes != NULL); + + switch_core_new_memory_pool(&ssl_pool); + + for (i = 0; i < num; i++) { + switch_mutex_init(&(ssl_mutexes[i]), SWITCH_MUTEX_NESTED, ssl_pool); + switch_assert(ssl_mutexes[i] != NULL); + } + + CRYPTO_set_id_callback(switch_ssl_ssl_thread_id); + CRYPTO_set_locking_callback((void (*)(int, int, const char*, int))switch_ssl_ssl_lock_callback); + } + + ssl_count++; + switch_core_ssl_count(&ssl_count); +} + +static inline void switch_ssl_destroy_ssl_locks() +{ + int i; + int ssl_count = switch_core_ssl_count(NULL); + + ssl_count--; + + if (ssl_count == 0) { + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + switch_mutex_destroy(ssl_mutexes[i]); + } + + OPENSSL_free(ssl_mutexes); + } + + switch_core_ssl_count(&ssl_count); + +} +#else +static inline void switch_ssl_init_ssl_locks(void) { return; } +static inline void switch_ssl_destroy_ssl_locks(void) { return; } +#endif + +#endif diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 2ab4a18b85..6664dc0653 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -136,6 +136,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE "execute_on_media" #define SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE "api_on_answer" #define SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE "execute_on_ring" +#define SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE "execute_on_tone_detect" #define SWITCH_CALL_TIMEOUT_VARIABLE "call_timeout" #define SWITCH_HOLDING_UUID_VARIABLE "holding_uuid" #define SWITCH_SOFT_HOLDING_UUID_VARIABLE "soft_holding_uuid" @@ -488,6 +489,7 @@ typedef struct { switch_size_t dtmf_packet_count; switch_size_t cng_packet_count; switch_size_t flush_packet_count; + switch_size_t largest_jb_size; } switch_rtp_numbers_t; diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index b08c204889..88c13379b3 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -239,20 +239,23 @@ SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_size SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size); SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone); SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame); +SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str); /*! \brief Evaluate the truthfullness of a string expression \param expr a string expression \return true or false */ -#define switch_true(expr)\ -((expr && ( !strcasecmp(expr, "yes") ||\ -!strcasecmp(expr, "on") ||\ -!strcasecmp(expr, "true") ||\ -!strcasecmp(expr, "enabled") ||\ -!strcasecmp(expr, "active") ||\ -!strcasecmp(expr, "allow") ||\ -(switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE) +static inline int switch_true(const char *expr) +{ + return ((expr && ( !strcasecmp(expr, "yes") || + !strcasecmp(expr, "on") || + !strcasecmp(expr, "true") || + !strcasecmp(expr, "enabled") || + !strcasecmp(expr, "active") || + !strcasecmp(expr, "allow") || + (switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE); +} #define switch_true_buf(expr)\ ((( !strcasecmp(expr, "yes") ||\ @@ -268,14 +271,16 @@ SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame); \param expr a string expression \return true or false */ -#define switch_false(expr)\ -((expr && ( !strcasecmp(expr, "no") ||\ -!strcasecmp(expr, "off") ||\ -!strcasecmp(expr, "false") ||\ -!strcasecmp(expr, "disabled") ||\ -!strcasecmp(expr, "inactive") ||\ -!strcasecmp(expr, "disallow") ||\ -(switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE) +static inline int switch_false(const char *expr) +{ + return ((expr && ( !strcasecmp(expr, "no") || + !strcasecmp(expr, "off") || + !strcasecmp(expr, "false") || + !strcasecmp(expr, "disabled") || + !strcasecmp(expr, "inactive") || + !strcasecmp(expr, "disallow") || + (switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE); +} SWITCH_DECLARE(switch_status_t) switch_resolve_host(const char *host, char *buf, size_t buflen); @@ -500,6 +505,23 @@ static inline char *switch_clean_string(char *s) } +static inline char *switch_clean_name_string(char *s) +{ + char *p; + for (p = s; p && *p; p++) { + uint8_t x = (uint8_t) * p; + if ((x < 32) || x == '\'' || x == '"' || x == '<' || x == '>' || x == '\\' || x == ':' || x == '@' || x == '/') { + *p = ' '; + } + if ( (p == s) && (*p == ' ') ) { + s++; + } + } + + return s; +} + + /*! \brief Free a pointer and set it to NULL unless it already is NULL @@ -653,7 +675,7 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in); SWITCH_DECLARE(unsigned int) switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen); SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen); -SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str); + SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup); SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str); SWITCH_DECLARE(char *) switch_strip_commas(char *in, char *out, switch_size_t len); diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h index f1164cee2e..2d3f994878 100644 --- a/src/include/switch_xml.h +++ b/src/include/switch_xml.h @@ -417,6 +417,8 @@ SWITCH_DECLARE(switch_xml_section_t) switch_xml_parse_section_string(_In_opt_z_ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond); +SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language); + SWITCH_END_EXTERN_C ///\} #endif // _SWITCH_XML_H diff --git a/src/mod/.gitignore b/src/mod/.gitignore index b75dbcb9cf..73caeb6ca1 100644 --- a/src/mod/.gitignore +++ b/src/mod/.gitignore @@ -9,8 +9,6 @@ /applications/mod_conference/Makefile /applications/mod_db/Makefile /applications/mod_dptools/Makefile -/applications/mod_enum/Makefile -/applications/mod_enum/Makefile.in /applications/mod_enum/mod_enum.log /applications/mod_expr/Makefile /applications/mod_expr/Makefile.in diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 8e6f2e124d..d0c9f6e419 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -479,7 +479,7 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame) double success = 0.0; double amp = 0.0; double s_rate; - double e_rate; +// double e_rate; double avg_a; double sine_len; uint32_t sine_len_i; @@ -523,7 +523,7 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame) /*! Every once in a while we evaluate the desa2 and amplitude results */ if(((pos + 1) % sine_len_i) == 0){ s_rate = success / (error + success); - e_rate = error / (error + success); +// e_rate = error / (error + success); avg_a = amp / sine_len; /*! Results out of these ranges are considered invalid */ diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.2008.vcproj b/src/mod/applications/mod_callcenter/mod_callcenter.2008.vcproj new file mode 100644 index 0000000000..85c60c56cf --- /dev/null +++ b/src/mod/applications/mod_callcenter/mod_callcenter.2008.vcproj @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.2010.vcxproj b/src/mod/applications/mod_callcenter/mod_callcenter.2010.vcxproj new file mode 100644 index 0000000000..224de6286f --- /dev/null +++ b/src/mod/applications/mod_callcenter/mod_callcenter.2010.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_callcenter + {47886A6C-CCA6-4F9F-A7D4-F97D06FB2B1A} + mod_callcenter + 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} + false + + + + + + diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index f8beb7c0f7..c2c1c0c624 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -37,10 +37,7 @@ #define CC_AGENT_TYPE_UUID_STANDBY "uuid-standby" #define CC_SQLITE_DB_NAME "callcenter" -/* TODO - drop caller if no agent login - dont allow new caller - */ + /* Prototypes */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_callcenter_shutdown); SWITCH_MODULE_RUNTIME_FUNCTION(mod_callcenter_runtime); @@ -249,6 +246,16 @@ static char tiers_sql[] = static switch_xml_config_int_options_t config_int_0_86400 = { SWITCH_TRUE, 0, SWITCH_TRUE, 86400 }; +/* TODO This is temporary until we either move it to the core, or use it differently in the module */ +switch_time_t local_epoch_time_now(switch_time_t *t) +{ + switch_time_t now = switch_micro_time_now() / 1000000; /* APR_USEC_PER_SEC */ + if (t) { + *t = now; + } + return now; +} + const char * cc_tier_state2str(cc_tier_state_t state) { uint8_t x; @@ -656,8 +663,6 @@ static cc_queue_t *load_queue(const char *queue_name) cc_queue_t *queue = NULL; switch_xml_t x_queues, x_queue, cfg, xml; switch_event_t *event = NULL; - switch_cache_db_handle_t *dbh = NULL; - char *sql = NULL; if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); @@ -700,30 +705,10 @@ static cc_queue_t *load_queue(const char *queue_name) queue->last_agent_exist = 0; queue->last_agent_exist_check = 0; - if (!(dbh = cc_get_db_handle())) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n"); - goto end; - } - - switch_cache_db_test_reactive(dbh, "select count(session_uuid) from members", "drop table members", members_sql); - switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", NULL, "alter table agents add ready_time integer not null default 0;" - "alter table agents add reject_delay_time integer not null default 0;" - "alter table agents add busy_delay_time integer not null default 0;"); - switch_cache_db_test_reactive(dbh, "select count(no_answer_delay_time) from agents", NULL, "alter table agents add no_answer_delay_time integer not null default 0;"); - switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", "drop table agents", agents_sql); - switch_cache_db_test_reactive(dbh, "select count(queue) from tiers", "drop table tiers" , tiers_sql); switch_mutex_init(&queue->mutex, SWITCH_MUTEX_NESTED, queue->pool); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added queue %s\n", queue->name); switch_core_hash_insert(globals.queue_hash, queue->name, queue); - /* Reset a unclean shutdown */ - sql = switch_mprintf("UPDATE agents SET state = 'Waiting', uuid = '' WHERE system = 'single_box';" - "UPDATE tiers SET state = 'Ready' WHERE agent IN (SELECT name FROM agents WHERE system = 'single_box');" - "UPDATE members SET state = '%q', session_uuid = '' WHERE system = 'single_box';", - cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); - - cc_execute_sql(NULL, sql, NULL); - switch_safe_free(sql); } end: @@ -925,13 +910,13 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen if (cc_agent_str2status(value) != CC_AGENT_STATUS_UNKNOWN) { /* Reset values on available only */ if (cc_agent_str2status(value) == CC_AGENT_STATUS_AVAILABLE) { - sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%ld', talk_time = 0, calls_answered = 0, no_answer_count = 0" + sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%" SWITCH_TIME_T_FMT "', talk_time = 0, calls_answered = 0, no_answer_count = 0" " WHERE name = '%q' AND NOT status = '%q'", - value, (long) switch_epoch_time_now(NULL), + value, local_epoch_time_now(NULL), agent, value); } else { - sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%ld' WHERE name = '%q'", - value, (long) switch_epoch_time_now(NULL), agent); + sql = switch_mprintf("UPDATE agents SET status = '%q', last_status_change = '%" SWITCH_TIME_T_FMT "' WHERE name = '%q'", + value, local_epoch_time_now(NULL), agent); } cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); @@ -943,7 +928,7 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); switch_safe_free(sql); if (!switch_strlen_zero(res)) { - switch_core_session_hupall_matching_var("cc_member_uuid", res, SWITCH_CAUSE_ORIGINATOR_CANCEL); + switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", res, SWITCH_CAUSE_ORIGINATOR_CANCEL); } } @@ -966,8 +951,8 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen if (cc_agent_str2state(value) != CC_AGENT_STATE_RECEIVING) { sql = switch_mprintf("UPDATE agents SET state = '%q' WHERE name = '%q'", value, agent); } else { - sql = switch_mprintf("UPDATE agents SET state = '%q', last_offered_call = '%ld' WHERE name = '%q'", - value, (long) switch_epoch_time_now(NULL), agent); + sql = switch_mprintf("UPDATE agents SET state = '%q', last_offered_call = '%" SWITCH_TIME_T_FMT "' WHERE name = '%q'", + value, local_epoch_time_now(NULL), agent); } cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); @@ -1262,11 +1247,15 @@ end: static switch_status_t load_config(void) { + switch_status_t status = SWITCH_STATUS_SUCCESS; switch_xml_t cfg, xml, settings, param, x_queues, x_queue, x_agents, x_agent, x_tiers, x_tier; - + switch_cache_db_handle_t *dbh = NULL; + char *sql = NULL; + if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); - return SWITCH_STATUS_TERM; + status = SWITCH_STATUS_TERM; + goto end; } switch_mutex_lock(globals.mutex); @@ -1297,6 +1286,30 @@ static switch_status_t load_config(void) globals.dbname = strdup(CC_SQLITE_DB_NAME); } + /* Initialize database */ + if (!(dbh = cc_get_db_handle())) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n"); + status = SWITCH_STATUS_TERM; + goto end; + } + switch_cache_db_test_reactive(dbh, "select count(session_uuid) from members", "drop table members", members_sql); + switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", NULL, "alter table agents add ready_time integer not null default 0;" + "alter table agents add reject_delay_time integer not null default 0;" + "alter table agents add busy_delay_time integer not null default 0;"); + switch_cache_db_test_reactive(dbh, "select count(no_answer_delay_time) from agents", NULL, "alter table agents add no_answer_delay_time integer not null default 0;"); + switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", "drop table agents", agents_sql); + switch_cache_db_test_reactive(dbh, "select count(queue) from tiers", "drop table tiers" , tiers_sql); + + switch_cache_db_release_db_handle(&dbh); + + /* Reset a unclean shutdown */ + sql = switch_mprintf("update agents set state = 'Waiting', uuid = '' where system = 'single_box';" + "update tiers set state = 'Ready' where agent IN (select name from agents where system = 'single_box');" + "update members set state = '%q', session_uuid = '' where system = 'single_box';", + cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); + cc_execute_sql(NULL, sql, NULL); + switch_safe_free(sql); + /* Loading queue into memory struct */ if ((x_queues = switch_xml_child(cfg, "queues"))) { for (x_queue = switch_xml_child(x_queues, "queue"); x_queue; x_queue = x_queue->next) { @@ -1342,11 +1355,14 @@ static switch_status_t load_config(void) } } +end: switch_mutex_unlock(globals.mutex); - switch_xml_free(xml); + if (xml) { + switch_xml_free(xml); + } - return SWITCH_STATUS_SUCCESS; + return status; } static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *thread, void *obj) @@ -1371,8 +1387,11 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa /* member is gone before we could process it */ if (!member_session) { - sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q' AND state != '%q'", - cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), h->member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Member %s <%s> with uuid %s in queue %s is gone just before we assigned an agent\n", h->member_cid_name, h->member_cid_number, h->member_session_uuid, h->queue_name); + + + sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE system = 'single_box' AND uuid = '%q' AND state != '%q'", + cc_member_state2str(CC_MEMBER_STATE_ABANDONED), local_epoch_time_now(NULL), h->member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); @@ -1405,7 +1424,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_side", "%s", "agent"); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true"); - t_agent_called = switch_epoch_time_now(NULL); + t_agent_called = local_epoch_time_now(NULL); dialstr = switch_mprintf("%s", h->originate_string); status = switch_ivr_originate(NULL, &agent_session, &cause, dialstr, 60, NULL, h->member_cid_name, h->member_cid_number, NULL, ovars, SOF_NONE, NULL); switch_safe_free(dialstr); @@ -1440,7 +1459,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa cc_agent_update("uuid", "", h->agent_name); } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid agent type '%s' for agent '%s', aborting member offering", h->agent_type, h->agent_name); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Invalid agent type '%s' for agent '%s', aborting member offering", h->agent_type, h->agent_name); status = SWITCH_CAUSE_USER_NOT_REGISTERED; } @@ -1507,7 +1526,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", h->member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL); } - t_agent_answered = switch_epoch_time_now(NULL); + t_agent_answered = local_epoch_time_now(NULL); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(agent_channel, event); @@ -1516,9 +1535,9 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%" SWITCH_TIME_T_FMT, t_agent_answered); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name); @@ -1527,12 +1546,12 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa } /* for xml_cdr needs */ switch_channel_set_variable(member_channel, "cc_agent", h->agent_name); - switch_channel_set_variable_printf(member_channel, "cc_queue_answered_epoch", "%ld", (long) switch_epoch_time_now(NULL)); + switch_channel_set_variable_printf(member_channel, "cc_queue_answered_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); /* Set UUID of the Agent channel */ - sql = switch_mprintf("UPDATE agents SET uuid = '%q', last_bridge_start = '%ld', calls_answered = calls_answered + 1, no_answer_count = 0" + sql = switch_mprintf("UPDATE agents SET uuid = '%q', last_bridge_start = '%" SWITCH_TIME_T_FMT "', calls_answered = calls_answered + 1, no_answer_count = 0" " WHERE name = '%q' AND system = '%q'", - agent_uuid, (long) switch_epoch_time_now(NULL), + agent_uuid, local_epoch_time_now(NULL), h->agent_name, h->agent_system); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); @@ -1551,13 +1570,16 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s answered \"%s\" <%s> from queue %s%s\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s answered \"%s\" <%s> from queue %s%s\n", h->agent_name, h->member_cid_name, h->member_cid_number, h->queue_name, (h->record_template?" (Recorded)":"")); + switch_ivr_uuid_bridge(h->member_session_uuid, switch_core_session_get_uuid(agent_session)); - /* This is used for the waiting caller to quit waiting for a agent */ switch_channel_set_variable(member_channel, "cc_agent_uuid", agent_uuid); + /* This is used for the waiting caller to quit waiting for a agent */ + switch_channel_set_variable(member_channel, "cc_agent_found", "true"); + /* Wait until the member hangup or the agent hangup. This will quit also if the agent transfer the call */ while(switch_channel_up(member_channel) && switch_channel_up(agent_channel) && globals.running) { switch_yield(100000); @@ -1572,10 +1594,10 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Bridge-Terminated-Time", "%ld", (long) switch_epoch_time_now(NULL)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%" SWITCH_TIME_T_FMT, t_agent_answered); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Bridge-Terminated-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name); @@ -1583,12 +1605,12 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_fire(&event); } /* for xml_cdr needs */ - switch_channel_set_variable_printf(member_channel, "cc_queue_terminated_epoch", "%ld", (long) switch_epoch_time_now(NULL)); + switch_channel_set_variable_printf(member_channel, "cc_queue_terminated_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); /* Update Agents Items */ /* Do not remove uuid of the agent if we are a standby agent */ - 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); + sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %" SWITCH_TIME_T_FMT ", talk_time = talk_time + (%" SWITCH_TIME_T_FMT "-last_bridge_start) WHERE name = '%q' AND system = '%q';" + , (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), local_epoch_time_now(NULL), local_epoch_time_now(NULL), h->agent_name, h->agent_system); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); @@ -1607,10 +1629,10 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%ld", (long) switch_epoch_time_now(NULL)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%" SWITCH_TIME_T_FMT, t_agent_answered); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", h->member_session_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", h->member_cid_name); @@ -1629,7 +1651,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s Origination Canceled : %s\n", h->agent_name, switch_channel_cause2str(cause)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s Origination Canceled : %s\n", h->agent_name, switch_channel_cause2str(cause)); switch (cause) { /* When we hang-up agents that did not answer in ring-all strategy */ @@ -1658,7 +1680,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa /* Put Agent on break because he didn't answer often */ if (h->max_no_answer > 0 && (h->no_answer_count + 1) >= h->max_no_answer) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s reach maximum no answer of %d, Putting agent on break\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s reach maximum no answer of %d, Putting agent on break\n", h->agent_name, h->max_no_answer); cc_agent_update("status", cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), h->agent_name); } @@ -1668,9 +1690,9 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa /* Put agent to sleep for some time if necessary */ if (delay_next_agent_call > 0) { char ready_epoch[64]; - switch_snprintf(ready_epoch, sizeof(ready_epoch), "%" SWITCH_TIME_T_FMT, switch_epoch_time_now(NULL) + delay_next_agent_call); + switch_snprintf(ready_epoch, sizeof(ready_epoch), "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL) + delay_next_agent_call); cc_agent_update("ready_time", ready_epoch , h->agent_name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s sleeping for %d seconds\n", h->agent_name, delay_next_agent_call); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Agent %s sleeping for %d seconds\n", h->agent_name, delay_next_agent_call); } /* Fire up event when contact agent fails */ @@ -1763,9 +1785,10 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames const char *agent_wrap_up_time = argv[11]; const char *agent_state = argv[12]; const char *agent_ready_time = argv[13]; - const char *agent_tier_level = argv[14]; - const char *agent_type = argv[15]; - const char *agent_uuid = argv[16]; + const char *agent_tier_position = argv[14]; + const char *agent_tier_level = argv[15]; + const char *agent_type = argv[16]; + const char *agent_uuid = argv[17]; switch_bool_t contact_agent = SWITCH_TRUE; @@ -1778,11 +1801,11 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames if (cbt->tier_rule_no_agent_no_wait == SWITCH_TRUE && cbt->tier_agent_available == 0) { cbt->tier = atoi(agent_tier_level); /* Multiple the tier level by the tier wait time */ - } else if (cbt->tier_rule_wait_multiply_level == SWITCH_TRUE && (long) switch_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= atoi(agent_tier_level) * cbt->tier_rule_wait_second) { + } else if (cbt->tier_rule_wait_multiply_level == SWITCH_TRUE && (long) local_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= atoi(agent_tier_level) * cbt->tier_rule_wait_second) { cbt->tier = atoi(agent_tier_level); cbt->tier_agent_available = 0; /* Just check if joined is bigger than next tier wait time */ - } else if (cbt->tier_rule_wait_multiply_level == SWITCH_FALSE && (long) switch_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= cbt->tier_rule_wait_second) { + } else if (cbt->tier_rule_wait_multiply_level == SWITCH_FALSE && (long) local_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= cbt->tier_rule_wait_second) { cbt->tier = atoi(agent_tier_level); cbt->tier_agent_available = 0; } else { @@ -1799,10 +1822,10 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames if (! (!strcasecmp(agent_state, cc_agent_state2str(CC_AGENT_STATE_WAITING)))) { contact_agent = SWITCH_FALSE; } - if (! (atol(agent_last_bridge_end) < ((long) switch_epoch_time_now(NULL) - atol(agent_wrap_up_time)))) { + if (! (atol(agent_last_bridge_end) < ((long) local_epoch_time_now(NULL) - atol(agent_wrap_up_time)))) { contact_agent = SWITCH_FALSE; } - if (! (atol(agent_ready_time) <= (long) switch_epoch_time_now(NULL))) { + if (! (atol(agent_ready_time) <= (long) local_epoch_time_now(NULL))) { contact_agent = SWITCH_FALSE; } if (! (strcasecmp(agent_status, cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK)))) { @@ -1877,8 +1900,16 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames h->reject_delay_time = atoi(agent_reject_delay_time); h->busy_delay_time = atoi(agent_busy_delay_time); h->no_answer_delay_time = atoi(agent_no_answer_delay_time); - + if (!strcasecmp(cbt->strategy, "top-down")) { + switch_core_session_t *member_session = switch_core_session_locate(cbt->member_session_uuid); + if (member_session) { + switch_channel_t *member_channel = switch_core_session_get_channel(member_session); + switch_channel_set_variable(member_channel, "cc_last_agent_tier_position", agent_tier_position); + switch_channel_set_variable(member_channel, "cc_last_agent_tier_level", agent_tier_level); + switch_core_session_rwunlock(member_session); + } + } cc_agent_update("state", cc_agent_state2str(CC_AGENT_STATE_RECEIVING), h->agent_name); sql = switch_mprintf( @@ -1918,7 +1949,6 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName switch_bool_t tier_rule_wait_multiply_level; switch_bool_t tier_rule_no_agent_no_wait; uint32_t discard_abandoned_after; - switch_bool_t abandoned_resume_allowed; agent_callback_t cbt; const char *member_state = NULL; const char *member_abandoned_epoch = NULL; @@ -1945,7 +1975,7 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName tier_rule_wait_multiply_level = queue->tier_rule_wait_multiply_level; tier_rule_no_agent_no_wait = queue->tier_rule_no_agent_no_wait; discard_abandoned_after = queue->discard_abandoned_after; - abandoned_resume_allowed = queue->abandoned_resume_allowed; + if (queue->record_template) { queue_record_template = strdup(queue->record_template); } @@ -1955,13 +1985,13 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName /* Checking for cleanup Abandonded calls from the db */ if (!strcasecmp(member_state, cc_member_state2str(CC_MEMBER_STATE_ABANDONED))) { - long abandoned_epoch = atol(member_abandoned_epoch); + switch_time_t abandoned_epoch = atoll(member_abandoned_epoch); if (abandoned_epoch == 0) { - abandoned_epoch = atol(cbt.member_joined_epoch); + abandoned_epoch = atoll(cbt.member_joined_epoch); } /* Once we pass a certain point, we want to get rid of the abandoned call */ - if (abandoned_epoch + discard_abandoned_after < (long) switch_epoch_time_now(NULL)) { - sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q' AND (abandoned_epoch = '%ld' OR joined_epoch = '%q')", cbt.member_uuid, abandoned_epoch, cbt.member_joined_epoch); + if (abandoned_epoch + discard_abandoned_after < local_epoch_time_now(NULL)) { + sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q' AND (abandoned_epoch = '%" SWITCH_TIME_T_FMT "' OR joined_epoch = '%q')", cbt.member_uuid, abandoned_epoch, cbt.member_joined_epoch); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); } @@ -1985,45 +2015,104 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName cbt.strategy = queue_strategy; cbt.record_template = queue_record_template; cbt.agent_found = SWITCH_FALSE; - - if (!strcasecmp(queue->strategy, "longest-idle-agent")) { - sql_order_by = switch_mprintf("level, agents.last_offered_call, position"); - } else if (!strcasecmp(queue_strategy, "agent-with-least-talk-time")) { - sql_order_by = switch_mprintf("level, agents.talk_time, position"); - } else if (!strcasecmp(queue_strategy, "agent-with-fewest-calls")) { - sql_order_by = switch_mprintf("level, agents.calls_answered, position"); - } else if (!strcasecmp(queue_strategy, "ring-all")) { - sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'", - cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt.member_uuid); - cc_execute_sql(NULL, sql, NULL); - switch_safe_free(sql); - sql_order_by = switch_mprintf("level, position"); - } else if(!strcasecmp(queue_strategy, "sequentially-by-agent-order")) { - sql_order_by = switch_mprintf("level, position, agents.last_offered_call"); /* Default to last_offered_call, let add new strategy if needing it differently */ - } else { - /* If the strategy doesn't exist, just fallback to the following */ - sql_order_by = switch_mprintf("level, position, agents.last_offered_call"); - } - sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.level, agents.type, agents.uuid FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)" - " WHERE tiers.queue = '%q'" - " AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')" - " ORDER BY %q", - queue_name, - cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND), - sql_order_by); + if (!strcasecmp(queue->strategy, "top-down")) { + /* WARNING this use channel variable to help dispatch... might need to be reviewed to save it in DB to make this multi server prooft in the future */ + switch_core_session_t *member_session = switch_core_session_locate(cbt.member_session_uuid); + int position = 0, level = 0; + const char *last_agent_tier_position, *last_agent_tier_level; + if (member_session) { + switch_channel_t *member_channel = switch_core_session_get_channel(member_session); + + if ((last_agent_tier_position = switch_channel_get_variable(member_channel, "cc_last_agent_tier_position"))) { + position = atoi(last_agent_tier_position); + } + if ((last_agent_tier_level = switch_channel_get_variable(member_channel, "cc_last_agent_tier_level"))) { + level = atoi(last_agent_tier_level); + } + switch_core_session_rwunlock(member_session); + } + + sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)" + " WHERE tiers.queue = '%q'" + " AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')" + " AND tiers.position > %d" + " AND tiers.level = %d" + " UNION " + "SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)" + " WHERE tiers.queue = '%q'" + " AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')" + " ORDER BY dyn_order asc, tiers_level, tiers_position, agents_last_offered_call", + queue_name, + cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND), + position, + level, + queue_name, + cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND) + ); + } else if (!strcasecmp(queue->strategy, "round-robin")) { + sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)" + " WHERE tiers.queue = '%q'" + " AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')" + " AND tiers.position > (SELECT tiers.position FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent) WHERE tiers.queue = '%q' AND agents.last_offered_call > 0 ORDER BY agents.last_offered_call DESC LIMIT 1)" + " AND tiers.level = (SELECT tiers.level FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent) WHERE tiers.queue = '%q' AND agents.last_offered_call > 0 ORDER BY agents.last_offered_call DESC LIMIT 1)" + " UNION " + "SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)" + " WHERE tiers.queue = '%q'" + " AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')" + " ORDER BY dyn_order asc, tiers_level, tiers_position, agents_last_offered_call", + queue_name, + cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND), + queue_name, + queue_name, + queue_name, + cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND) + ); + + } else { + + if (!strcasecmp(queue->strategy, "longest-idle-agent")) { + sql_order_by = switch_mprintf("level, agents.last_offered_call, position"); + } else if (!strcasecmp(queue_strategy, "agent-with-least-talk-time")) { + sql_order_by = switch_mprintf("level, agents.talk_time, position"); + } else if (!strcasecmp(queue_strategy, "agent-with-fewest-calls")) { + sql_order_by = switch_mprintf("level, agents.calls_answered, position"); + } else if (!strcasecmp(queue_strategy, "ring-all")) { + sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'", + cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt.member_uuid); + cc_execute_sql(NULL, sql, NULL); + switch_safe_free(sql); + sql_order_by = switch_mprintf("level, position"); + } else if(!strcasecmp(queue_strategy, "random")) { + sql_order_by = switch_mprintf("level, random()"); + } else if(!strcasecmp(queue_strategy, "sequentially-by-agent-order")) { + sql_order_by = switch_mprintf("level, position, agents.last_offered_call"); /* Default to last_offered_call, let add new strategy if needing it differently */ + } else { + /* If the strategy doesn't exist, just fallback to the following */ + sql_order_by = switch_mprintf("level, position, agents.last_offered_call"); + } + + sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position, tiers.level, agents.type, agents.uuid FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)" + " WHERE tiers.queue = '%q'" + " AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')" + " ORDER BY %q", + queue_name, + cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE), cc_agent_status2str(CC_AGENT_STATUS_ON_BREAK), cc_agent_status2str(CC_AGENT_STATUS_AVAILABLE_ON_DEMAND), + sql_order_by); + switch_safe_free(sql_order_by); + + } cc_execute_sql_callback(NULL /* queue */, NULL /* mutex */, sql, agents_callback, &cbt /* Call back variables */); switch_safe_free(sql); - switch_safe_free(sql_order_by); /* We update a field in the queue struct so we can kick caller out if waiting for too long with no agent */ if (!cbt.queue_name || !(queue = get_queue(cbt.queue_name))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found locally, skip this member\n", cbt.queue_name); goto end; } else { - queue->last_agent_exist_check = switch_epoch_time_now(NULL); + queue->last_agent_exist_check = local_epoch_time_now(NULL); if (cbt.agent_found) { queue->last_agent_exist = queue->last_agent_exist_check; } @@ -2062,9 +2151,9 @@ void *SWITCH_THREAD_FUNC cc_agent_dispatch_thread_run(switch_thread_t *thread, v while (globals.running == 1) { char *sql = NULL; - sql = switch_mprintf("SELECT queue,uuid,session_uuid,cid_number,cid_name,joined_epoch,(%ld-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch FROM members" + sql = switch_mprintf("SELECT queue,uuid,session_uuid,cid_number,cid_name,joined_epoch,(%" SWITCH_TIME_T_FMT "-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch FROM members" " WHERE state = '%q' OR state = '%q' OR (serving_agent = 'ring-all' AND state = '%q') ORDER BY score DESC", - (long) switch_epoch_time_now(NULL), + local_epoch_time_now(NULL), cc_member_state2str(CC_MEMBER_STATE_WAITING), cc_member_state2str(CC_MEMBER_STATE_ABANDONED), cc_member_state2str(CC_MEMBER_STATE_TRYING)); cc_execute_sql_callback(NULL /* queue */, NULL /* mutex */, sql, members_callback, NULL /* Call back variables */); @@ -2113,6 +2202,8 @@ struct member_thread_helper { const char *queue_name; const char *member_uuid; const char *member_session_uuid; + const char *member_cid_name; + const char *member_cid_number; switch_time_t t_member_called; cc_member_cancel_reason_t member_cancel_reason; @@ -2126,10 +2217,6 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj switch_core_session_t *member_session = switch_core_session_locate(m->member_session_uuid); switch_channel_t *member_channel = NULL; - switch_mutex_lock(globals.mutex); - globals.threads++; - switch_mutex_unlock(globals.mutex); - if (member_session) { member_channel = switch_core_session_get_channel(member_session); } else { @@ -2137,15 +2224,20 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj return NULL; } + switch_mutex_lock(globals.mutex); + globals.threads++; + switch_mutex_unlock(globals.mutex); + while(switch_channel_ready(member_channel) && m->running && globals.running) { cc_queue_t *queue = NULL; if (!m->queue_name || !(queue = get_queue(m->queue_name))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found\n", m->queue_name); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "Queue %s not found\n", m->queue_name); break; } /* Make the Caller Leave if he went over his max wait time */ - if (queue->max_wait_time > 0 && queue->max_wait_time <= switch_epoch_time_now(NULL) - m->t_member_called) { + if (queue->max_wait_time > 0 && queue->max_wait_time <= local_epoch_time_now(NULL) - m->t_member_called) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> in queue '%s' reached max wait time\n", m->member_cid_name, m->member_cid_number, m->queue_name); m->member_cancel_reason = CC_MEMBER_CANCEL_REASON_TIMEOUT; switch_channel_set_flag_value(member_channel, CF_BREAK, 2); } @@ -2153,6 +2245,7 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj /* Will drop the caller if no agent was found for more than X seconds */ if (queue->max_wait_time_with_no_agent > 0 && m->t_member_called < queue->last_agent_exist_check - queue->max_wait_time_with_no_agent_time_reached && queue->last_agent_exist_check - queue->last_agent_exist >= queue->max_wait_time_with_no_agent) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> in queue '%s' reached max wait with no agent time\n", m->member_cid_name, m->member_cid_number, m->queue_name); m->member_cancel_reason = CC_MEMBER_CANCEL_REASON_NO_AGENT_TIMEOUT; switch_channel_set_flag_value(member_channel, CF_BREAK, 2); } @@ -2218,7 +2311,6 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, SWITCH_STANDARD_APP(callcenter_function) { - int argc = 0; char *argv[6] = { 0 }; char *mydata = NULL; cc_queue_t *queue = NULL; @@ -2238,17 +2330,19 @@ SWITCH_STANDARD_APP(callcenter_function) const char *cur_moh = NULL; char start_epoch[64]; switch_event_t *event; - switch_time_t t_member_called = switch_epoch_time_now(NULL); + switch_time_t t_member_called = local_epoch_time_now(NULL); long abandoned_epoch = 0; - const char *agent_uuid = NULL; switch_uuid_t smember_uuid; char member_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = ""; + switch_bool_t agent_found = SWITCH_FALSE; + switch_bool_t moh_valid = SWITCH_TRUE; + const char *p; if (!zstr(data)) { mydata = switch_core_session_strdup(member_session, data); - argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Queue name provided\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "No Queue name provided\n"); goto end; } @@ -2257,7 +2351,7 @@ SWITCH_STANDARD_APP(callcenter_function) } if (!queue_name || !(queue = get_queue(queue_name))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found\n", queue_name); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "Queue %s not found\n", queue_name); goto end; } @@ -2303,7 +2397,7 @@ SWITCH_STANDARD_APP(callcenter_function) /* If system, will add the total time the session is up to the base score */ if (!switch_strlen_zero(start_epoch) && !strcasecmp("system", queue->time_base_score)) { - cc_base_score_int += ((long) switch_epoch_time_now(NULL) - atol(start_epoch)); + cc_base_score_int += ((long) local_epoch_time_now(NULL) - atol(start_epoch)); } if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { @@ -2317,19 +2411,21 @@ SWITCH_STANDARD_APP(callcenter_function) switch_event_fire(&event); } /* for xml_cdr needs */ - switch_channel_set_variable_printf(member_channel, "cc_queue_joined_epoch", "%ld", (long) switch_epoch_time_now(NULL)); + switch_channel_set_variable_printf(member_channel, "cc_queue_joined_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); switch_channel_set_variable(member_channel, "cc_queue", queue_name); if (abandoned_epoch == 0) { /* Add the caller to the member queue */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> joining queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name); + sql = switch_mprintf("INSERT INTO members" " (queue,system,uuid,session_uuid,system_epoch,joined_epoch,base_score,skill_score,cid_number,cid_name,serving_agent,serving_system,state)" - " VALUES('%q','single_box','%q','%q','%q','%ld','%d','%d','%q','%q','%q','','%q')", + " VALUES('%q','single_box','%q','%q','%q','%" SWITCH_TIME_T_FMT "','%d','%d','%q','%q','%q','','%q')", queue_name, member_uuid, member_session_uuid, start_epoch, - (long) switch_epoch_time_now(NULL), + local_epoch_time_now(NULL), cc_base_score_int, 0 /*TODO SKILL score*/, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), @@ -2340,21 +2436,24 @@ SWITCH_STANDARD_APP(callcenter_function) switch_safe_free(sql); } else { char res[256]; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> restoring it previous position in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name); + /* Update abandoned member */ - sql = switch_mprintf("UPDATE members SET session_uuid = '%q', state = '%q', rejoined_epoch = '%ld' WHERE uuid = '%q' AND state = '%q'", - member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), (long) switch_epoch_time_now(NULL), member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); + sql = switch_mprintf("UPDATE members SET session_uuid = '%q', state = '%q', rejoined_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND state = '%q'", + member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), local_epoch_time_now(NULL), member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); cc_execute_sql(queue, sql, NULL); switch_safe_free(sql); /* Confirm we took that member in */ - sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q' AND session_uuid = '%q' AND state = '%q' AND queue = '%q'", member_session, member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), queue_name); + sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q' AND session_uuid = '%q' AND state = '%q' AND queue = '%q'", member_uuid, member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), queue_name); cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); switch_safe_free(sql); if (atol(res) == 0) { /* Failed to get the member !!! */ /* TODO Loop back to just create a uuid and add the member as a new member */ - /* TODO ERROR MSG */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_ERROR, "Member %s <%s> restoring action failed in queue %s, exiting\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name); queue_rwunlock(queue); goto end; } @@ -2371,6 +2470,8 @@ SWITCH_STANDARD_APP(callcenter_function) h->pool = pool; h->member_uuid = switch_core_strdup(h->pool, member_uuid); h->member_session_uuid = switch_core_strdup(h->pool, member_session_uuid); + h->member_cid_name = switch_core_strdup(h->pool, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name"))); + h->member_cid_number = switch_core_strdup(h->pool, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number"))); h->queue_name = switch_core_strdup(h->pool, queue_name); h->t_member_called = t_member_called; h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_NONE; @@ -2399,7 +2500,7 @@ SWITCH_STANDARD_APP(callcenter_function) args.buflen = sizeof(h); /* An agent was found, time to exit and let the bridge do it job */ - if ((agent_uuid = switch_channel_get_variable(member_channel, "cc_agent_uuid"))) { + if ((p = switch_channel_get_variable(member_channel, "cc_agent_found")) && (agent_found = switch_true(p))) { break; } /* If the member thread set a different reason, we monitor it so we can quit the wait */ @@ -2409,10 +2510,15 @@ SWITCH_STANDARD_APP(callcenter_function) switch_core_session_flush_private_events(member_session); - if (cur_moh) { + if (moh_valid && cur_moh) { switch_status_t status = switch_ivr_play_file(member_session, NULL, cur_moh, &args); - if (!SWITCH_READ_ACCEPTABLE(status)) { + if (status == SWITCH_STATUS_FALSE /* Invalid Recording */ && SWITCH_READ_ACCEPTABLE(status)) { + /* Sadly, there doesn't seem to be a return to switch_ivr_play_file that tell you the file wasn't found. FALSE also mean that the channel got switch to BRAKE state, so we check for read acceptable */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_WARNING, "Couldn't play file '%s', continuing wait with no audio\n", cur_moh); + moh_valid = SWITCH_FALSE; + + } else if (!SWITCH_READ_ACCEPTABLE(status)) { break; } @@ -2424,34 +2530,42 @@ SWITCH_STANDARD_APP(callcenter_function) } + /* Make sure that an agent was not found, since we could have break out before settign it previously */ + if (!agent_found && (p = switch_channel_get_variable(member_channel, "cc_agent_found"))) { + agent_found = switch_true(p); + } + /* Stop Member Thread */ if (h) { h->running = 0; } /* Check if we were removed be cause FS Core(BREAK) asked us too */ - if (h->member_cancel_reason == CC_MEMBER_CANCEL_REASON_NONE && !switch_channel_get_variable(member_channel, "cc_agent_uuid")) { + if (h->member_cancel_reason == CC_MEMBER_CANCEL_REASON_NONE && !agent_found) { h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_BREAK_OUT; } + switch_channel_set_variable(member_channel, "cc_agent_found", NULL); /* Canceled for some reason */ if (!switch_channel_up(member_channel) || h->member_cancel_reason != CC_MEMBER_CANCEL_REASON_NONE) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> abandoned waiting in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name); + /* Update member state */ - sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q'", - cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), member_uuid); + sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE system = 'single_box' AND uuid = '%q'", + cc_member_state2str(CC_MEMBER_STATE_ABANDONED), local_epoch_time_now(NULL), member_uuid); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); /* Hangup any callback agents */ - switch_core_session_hupall_matching_var("cc_member_uuid", member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL); + switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL); /* Generate an event */ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(member_channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", queue_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "member-queue-end"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%ld", (long) switch_epoch_time_now(NULL)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%ld", (long) t_member_called); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cause", "Cancel"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cancel-Reason", cc_member_cancel_reason2str(h->member_cancel_reason)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", member_uuid); @@ -2462,20 +2576,22 @@ SWITCH_STANDARD_APP(callcenter_function) } /* Update some channel variables for xml_cdr needs */ - switch_channel_set_variable_printf(member_channel, "cc_queue_canceled_epoch", "%ld", (long) switch_epoch_time_now(NULL)); + switch_channel_set_variable_printf(member_channel, "cc_queue_canceled_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL)); switch_channel_set_variable_printf(member_channel, "cc_cause", "%s", "cancel"); switch_channel_set_variable_printf(member_channel, "cc_cancel_reason", "%s", cc_member_cancel_reason2str(h->member_cancel_reason)); /* Print some debug log information */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member \"%s\" <%s> exit queue %s due to %s\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member \"%s\" <%s> exit queue %s due to %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name, cc_member_cancel_reason2str(h->member_cancel_reason)); } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> is answered by an agent in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name); + /* Update member state */ - sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q'", - cc_member_state2str(CC_MEMBER_STATE_ANSWERED), (long) switch_epoch_time_now(NULL), member_uuid); + sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%" SWITCH_TIME_T_FMT "' WHERE system = 'single_box' AND uuid = '%q'", + cc_member_state2str(CC_MEMBER_STATE_ANSWERED), local_epoch_time_now(NULL), member_uuid); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); diff --git a/src/mod/applications/mod_cidlookup/mod_cidlookup.c b/src/mod/applications/mod_cidlookup/mod_cidlookup.c index 2ec41f19e4..64e5fc7520 100755 --- a/src/mod/applications/mod_cidlookup/mod_cidlookup.c +++ b/src/mod/applications/mod_cidlookup/mod_cidlookup.c @@ -366,7 +366,6 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha switch_time_t time_diff = 0; CURL *curl_handle = NULL; long httpRes = 0; - char hostname[256] = ""; struct http_data http_data; @@ -375,8 +374,6 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha http_data.max_bytes = 10240; SWITCH_STANDARD_STREAM(http_data.stream); - gethostname(hostname, sizeof(hostname)); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "url: %s\n", query); curl_handle = curl_easy_init(); @@ -729,6 +726,9 @@ SWITCH_STANDARD_APP(cidlookup_app_function) if (!session && pool) { switch_core_destroy_memory_pool(&pool); } + /* This is so compile doesn't failed because status is never used */ + if (status) { + } } SWITCH_STANDARD_API(cidlookup_function) diff --git a/src/mod/applications/mod_cluechoo/mod_cluechoo.c b/src/mod/applications/mod_cluechoo/mod_cluechoo.c index 2699d82fc4..b4eaee0acb 100644 --- a/src/mod/applications/mod_cluechoo/mod_cluechoo.c +++ b/src/mod/applications/mod_cluechoo/mod_cluechoo.c @@ -217,7 +217,7 @@ int go(int i) int vgo(int i, switch_core_session_t *session) { int x; - int sleep_len = 40000; + //int sleep_len = 40000; switch_channel_t *channel = switch_core_session_get_channel(session); switch_frame_t *read_frame; switch_status_t status; @@ -233,9 +233,9 @@ int vgo(int i, switch_core_session_t *session) printf("%s", SWITCH_SEQ_CLEARSCR); - if (i > 0) { - sleep_len = i; - } + //if (i > 0) { + //sleep_len = i; + //} initscr(); signal(SIGINT, SIG_IGN); diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index ab402db8f5..d7d67223e4 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -249,9 +249,13 @@ SWITCH_STANDARD_API(banner_function) SWITCH_STANDARD_API(hostname_api_function) { - char hostname[256] = ""; - gethostname(hostname, sizeof(hostname)); - stream->write_function(stream, "%s", hostname); + stream->write_function(stream, "%s", switch_core_get_hostname()); + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_STANDARD_API(switchname_api_function) +{ + stream->write_function(stream, "%s", switch_core_get_switchname()); return SWITCH_STATUS_SUCCESS; } @@ -520,7 +524,7 @@ SWITCH_STANDARD_API(timer_test_function) timer_name = argv[2]; } - if (mss != 10 && mss != 20 && mss != 30 && mss != 40 && mss != 60 && mss != 120) { + if (mss != 10 && mss != 20 && mss != 30 && mss != 32 && mss != 40 && mss != 60 && mss != 120) { stream->write_function(stream, "parameter missing: %s\n", TIMER_TEST_SYNTAX); goto end; } @@ -2601,7 +2605,6 @@ SWITCH_STANDARD_API(uuid_broadcast_function) { char *mycmd = NULL, *argv[4] = { 0 }; int argc = 0; - switch_status_t status = SWITCH_STATUS_FALSE; if (!zstr(cmd) && (mycmd = strdup(cmd))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -2635,7 +2638,7 @@ SWITCH_STANDARD_API(uuid_broadcast_function) flags = SMF_ECHO_ALEG | SMF_HOLD_BLEG; } - status = switch_ivr_broadcast(argv[0], argv[1], flags); + switch_ivr_broadcast(argv[0], argv[1], flags); stream->write_function(stream, "+OK Message Sent\n"); } @@ -2648,7 +2651,6 @@ SWITCH_STANDARD_API(sched_broadcast_function) { char *mycmd = NULL, *argv[4] = { 0 }; int argc = 0; - switch_status_t status = SWITCH_STATUS_FALSE; if (!zstr(cmd) && (mycmd = strdup(cmd))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -2678,7 +2680,7 @@ SWITCH_STANDARD_API(sched_broadcast_function) flags |= SMF_ECHO_ALEG; } - status = switch_ivr_schedule_broadcast(when, argv[1], argv[2], flags); + switch_ivr_schedule_broadcast(when, argv[1], argv[2], flags); stream->write_function(stream, "+OK Message Scheduled\n"); } @@ -2763,8 +2765,6 @@ SWITCH_STANDARD_API(uuid_buglist_function) char *mydata = NULL, *argv[2] = { 0 }; int argc = 0; - switch_status_t status = SWITCH_STATUS_FALSE; - if (zstr(cmd)) { goto error; } @@ -2781,7 +2781,7 @@ SWITCH_STANDARD_API(uuid_buglist_function) switch_core_session_t *lsession = NULL; if ((lsession = switch_core_session_locate(argv[0]))) { - status = switch_core_media_bug_enumerate(lsession, stream); + switch_core_media_bug_enumerate(lsession, stream); switch_core_session_rwunlock(lsession); } goto ok; @@ -3863,13 +3863,10 @@ SWITCH_STANDARD_API(show_function) struct holder holder = { 0 }; int help = 0; char *mydata = NULL, *argv[6] = { 0 }; - int argc; char *command = NULL, *as = NULL; switch_core_flag_t cflags = switch_core_flags(); switch_status_t status = SWITCH_STATUS_SUCCESS; - char hostname[256] = ""; - gethostname(hostname, sizeof(hostname)); - + const char *hostname = switch_core_get_switchname(); if (!(cflags & SCF_USE_SQL)) { stream->write_function(stream, "-ERR SQL DISABLED NO DATA AVAILABLE!\n"); @@ -3884,7 +3881,7 @@ SWITCH_STANDARD_API(show_function) holder.justcount = 0; if (cmd && (mydata = strdup(cmd))) { - argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); command = argv[0]; if (argv[2] && !strcasecmp(argv[1], "as")) { as = argv[2]; @@ -4378,10 +4375,10 @@ SWITCH_STANDARD_API(uuid_fileman_function) char *cmd = argv[1]; if ((psession = switch_core_session_locate(uuid))) { - switch_channel_t *channel; + //switch_channel_t *channel; switch_file_handle_t *fh = NULL; - channel = switch_core_session_get_channel(psession); + //channel = switch_core_session_get_channel(psession); if (switch_ivr_get_file_handle(psession, &fh) == SWITCH_STATUS_SUCCESS) { switch_ivr_process_fh(psession, cmd, fh); @@ -4689,13 +4686,12 @@ SWITCH_STANDARD_API(strftime_tz_api_function) SWITCH_STANDARD_API(hupall_api_function) { char *mycmd = NULL, *argv[3] = { 0 }; - int argc = 0; char *var = NULL; char *val = NULL; switch_call_cause_t cause = SWITCH_CAUSE_MANAGER_REQUEST; if (!zstr(cmd) && (mycmd = strdup(cmd))) { - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); switch_assert(argv[0]); if ((cause = switch_channel_str2cause(argv[0])) == SWITCH_CAUSE_NONE) { cause = SWITCH_CAUSE_MANAGER_REQUEST; @@ -5156,6 +5152,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "help", "Show help for all the api commands", help_function, ""); SWITCH_ADD_API(commands_api_interface, "host_lookup", "host_lookup", host_lookup_function, ""); SWITCH_ADD_API(commands_api_interface, "hostname", "Returns the system hostname", hostname_api_function, ""); + SWITCH_ADD_API(commands_api_interface, "switchname", "Returns the switch name", switchname_api_function, ""); SWITCH_ADD_API(commands_api_interface, "hupall", "hupall", hupall_api_function, " [ ]"); SWITCH_ADD_API(commands_api_interface, "in_group", "determine if a user is in a group", in_group_function, "[@] "); SWITCH_ADD_API(commands_api_interface, "is_lan_addr", "see if an ip is a lan addr", lan_addr_function, ""); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 7de7f4fdea..a69b18b578 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -156,7 +156,9 @@ typedef enum { CFLAG_VID_FLOOR = (1 << 8), CFLAG_WASTE_BANDWIDTH = (1 << 9), CFLAG_OUTCALL = (1 << 10), - CFLAG_INHASH = (1 << 11) + CFLAG_INHASH = (1 << 11), + CFLAG_EXIT_SOUND = (1 << 12), + CFLAG_ENTER_SOUND = (1 << 13) } conf_flag_t; typedef enum { @@ -198,7 +200,6 @@ typedef enum { EFLAG_FLOOR_CHANGE = (1 << 25), EFLAG_MUTE_DETECT = (1 << 26), EFLAG_RECORD = (1 << 27), - EFLAG_AUTO_GAIN_LEVEL = (1 << 28) } event_type_t; typedef struct conference_file_node { @@ -717,12 +718,14 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe if (!switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ) && !zstr(conference->enter_sound)) { const char * enter_sound = switch_channel_get_variable(channel, "conference_enter_sound"); - if (!zstr(enter_sound)) { - conference_play_file(conference, (char *)enter_sound, CONF_DEFAULT_LEADIN, - switch_core_session_get_channel(member->session), !switch_test_flag(conference, CFLAG_WAIT_MOD) ? 0 : 1); - } else { - conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session), - !switch_test_flag(conference, CFLAG_WAIT_MOD) ? 0 : 1); + if (switch_test_flag(conference, CFLAG_ENTER_SOUND)) { + if (!zstr(enter_sound)) { + conference_play_file(conference, (char *)enter_sound, CONF_DEFAULT_LEADIN, + switch_core_session_get_channel(member->session), !switch_test_flag(conference, CFLAG_WAIT_MOD) ? 0 : 1); + } else { + conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session), + !switch_test_flag(conference, CFLAG_WAIT_MOD) ? 0 : 1); + } } } } @@ -774,7 +777,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe } switch_channel_clear_app_flag_key("conf_silent", channel, CONF_SILENT_REQ); - + switch_channel_set_app_flag_key("conf_silent", channel, CONF_SILENT_DONE); switch_ivr_dmachine_create(&member->dmachine, "mod_conference", NULL, 500, 0, NULL, NULL, NULL); @@ -811,12 +814,19 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe switch_event_t *event; conference_file_node_t *member_fnode; switch_speech_handle_t *member_sh; + const char *exit_sound = NULL; switch_assert(conference != NULL); switch_assert(member != NULL); switch_thread_rwlock_wrlock(member->rwlock); + if (member->session && (exit_sound = switch_channel_get_variable(switch_core_session_get_channel(member->session), "conference_exit_sound"))) { + conference_play_file(conference, (char *)exit_sound, CONF_DEFAULT_LEADIN, + switch_core_session_get_channel(member->session), !switch_test_flag(conference, CFLAG_WAIT_MOD) ? 0 : 1); + } + + lock_member(member); member_fnode = member->fnode; member_sh = member->sh; @@ -906,7 +916,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe || (switch_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0)) { switch_set_flag(conference, CFLAG_DESTRUCT); } else { - if (conference->exit_sound) { + if (!exit_sound && conference->exit_sound && switch_test_flag(conference, CFLAG_EXIT_SOUND)) { conference_play_file(conference, conference->exit_sound, 0, switch_core_session_get_channel(member->session), 0); } if (conference->count == 1 && conference->alone_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)) { @@ -944,7 +954,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr conference_member_t *imember; switch_frame_t *vid_frame; switch_status_t status; - int has_vid = 1, req_iframe = 0; + int has_vid = 1;// req_iframe = 0; int yield = 0; uint32_t last_member = 0; switch_core_session_t *session; @@ -979,7 +989,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr if (!SWITCH_READ_ACCEPTABLE(status) || !conference->floor_holder || switch_test_flag(vid_frame, SFF_CNG)) { conference->floor_holder = NULL; - req_iframe = 0; + //req_iframe = 0; goto do_continue; } @@ -1014,7 +1024,7 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr goto do_continue; } - req_iframe = 0; + //req_iframe = 0; } last_member = conference->floor_holder->id; @@ -1619,7 +1629,7 @@ static void conference_loop_fn_energy_up(conference_member_t *member, caller_con if (member == NULL) return; - lock_member(member); + member->energy_level += 200; if (member->energy_level > 1800) { member->energy_level = 1800; @@ -1632,7 +1642,6 @@ static void conference_loop_fn_energy_up(conference_member_t *member, caller_con switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); //conference_member_say(member, msg, 0); @@ -1656,7 +1665,6 @@ static void conference_loop_fn_energy_equ_conf(conference_member_t *member, call if (member == NULL) return; - lock_member(member); member->energy_level = member->conference->energy_level; if (test_eflag(member->conference, EFLAG_ENERGY_LEVEL) && @@ -1666,7 +1674,6 @@ static void conference_loop_fn_energy_equ_conf(conference_member_t *member, call switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); //conference_member_say(member, msg, 0); @@ -1687,7 +1694,6 @@ static void conference_loop_fn_energy_dn(conference_member_t *member, caller_con if (member == NULL) return; - lock_member(member); member->energy_level -= 200; if (member->energy_level < 0) { member->energy_level = 0; @@ -1700,7 +1706,6 @@ static void conference_loop_fn_energy_dn(conference_member_t *member, caller_con switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); //conference_member_say(member, msg, 0); @@ -1721,7 +1726,6 @@ static void conference_loop_fn_volume_talk_up(conference_member_t *member, calle if (member == NULL) return; - lock_member(member); member->volume_out_level++; switch_normalize_volume(member->volume_out_level); @@ -1732,7 +1736,6 @@ static void conference_loop_fn_volume_talk_up(conference_member_t *member, calle switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); //conference_member_say(member, msg, 0); @@ -1755,7 +1758,6 @@ static void conference_loop_fn_volume_talk_zero(conference_member_t *member, cal if (member == NULL) return; - lock_member(member); member->volume_out_level = 0; if (test_eflag(member->conference, EFLAG_VOLUME_LEVEL) && @@ -1765,7 +1767,6 @@ static void conference_loop_fn_volume_talk_zero(conference_member_t *member, cal switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); //conference_member_say(member, msg, 0); @@ -1788,7 +1789,6 @@ static void conference_loop_fn_volume_talk_dn(conference_member_t *member, calle if (member == NULL) return; - lock_member(member); member->volume_out_level--; switch_normalize_volume(member->volume_out_level); @@ -1799,7 +1799,6 @@ static void conference_loop_fn_volume_talk_dn(conference_member_t *member, calle switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); //conference_member_say(member, msg, 0); @@ -1821,7 +1820,6 @@ static void conference_loop_fn_volume_listen_up(conference_member_t *member, cal if (member == NULL) return; - lock_member(member); member->volume_in_level++; switch_normalize_volume(member->volume_in_level); @@ -1832,7 +1830,6 @@ static void conference_loop_fn_volume_listen_up(conference_member_t *member, cal switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); //conference_member_say(member, msg, 0); @@ -1855,7 +1852,6 @@ static void conference_loop_fn_volume_listen_zero(conference_member_t *member, c if (member == NULL) return; - lock_member(member); member->volume_in_level = 0; if (test_eflag(member->conference, EFLAG_GAIN_LEVEL) && @@ -1865,7 +1861,6 @@ static void conference_loop_fn_volume_listen_zero(conference_member_t *member, c switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); //conference_member_say(member, msg, 0); @@ -1888,7 +1883,6 @@ static void conference_loop_fn_volume_listen_dn(conference_member_t *member, cal if (member == NULL) return; - lock_member(member); member->volume_in_level--; switch_normalize_volume(member->volume_in_level); @@ -1899,7 +1893,6 @@ static void conference_loop_fn_volume_listen_dn(conference_member_t *member, cal switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); switch_event_fire(&event); } - unlock_member(member); //switch_snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); //conference_member_say(member, msg, 0); @@ -1992,22 +1985,20 @@ static void conference_loop_fn_exec_app(conference_member_t *member, caller_cont switch_event_fire(&event); } - if ((mydata = switch_core_session_strdup(member->session, action->expanded_data))) { - if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - if (argc > 0) { - app = argv[0]; - } - if (argc > 1) { - arg = argv[1]; - } + mydata = strdup(action->expanded_data); + switch_assert(mydata); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Empty execute app string [%s]\n", - (char *) action->expanded_data); - goto done; + if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { + if (argc > 0) { + app = argv[0]; } + if (argc > 1) { + arg = argv[1]; + } + } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Unable to allocate memory to duplicate execute_app data.\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Empty execute app string [%s]\n", + (char *) action->expanded_data); goto done; } @@ -2025,8 +2016,11 @@ static void conference_loop_fn_exec_app(conference_member_t *member, caller_cont switch_core_session_execute_application(member->session, app, arg); switch_core_session_set_read_codec(member->session, &member->read_codec); switch_channel_clear_app_flag(channel, CF_APP_TAGGED); + done: + switch_safe_free(mydata); + return; } @@ -2068,7 +2062,7 @@ static void clear_avg(conference_member_t *member) static void check_agc_levels(conference_member_t *member) { - int x = 0, y = member->agc_volume_in_level; + int x = 0; if (!member->avg_score) return; @@ -2083,8 +2077,6 @@ static void check_agc_levels(conference_member_t *member) } if (x) { - switch_event_t *event; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7, "AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d %s\n", member->conference->name, @@ -2092,17 +2084,6 @@ static void check_agc_levels(conference_member_t *member) member->score, member->avg_score, member->agc_volume_in_level, x > 0 ? "+++" : "---"); clear_avg(member); - - - if (test_eflag(member->conference, EFLAG_AUTO_GAIN_LEVEL) && - 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", "auto-gain-level"); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-Level", "%d", y); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->agc_volume_in_level); - switch_event_fire(&event); - } - } } @@ -2507,30 +2488,20 @@ static void conference_loop_output(conference_member_t *member) switch_timer_t timer = { 0 }; uint32_t interval; uint32_t samples; - uint32_t csamples; + //uint32_t csamples; uint32_t tsamples; uint32_t flush_len; uint32_t low_count, bytes; call_list_t *call_list, *cp; - int restarting = -1; switch_codec_implementation_t read_impl = { 0 }; - top: - switch_core_session_get_read_impl(member->session, &read_impl); - restarting++; - - if (switch_test_flag(member, MFLAG_RESTART)) { - switch_clear_flag(member, MFLAG_RESTART); - switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER); - switch_core_timer_destroy(&timer); - } channel = switch_core_session_get_channel(member->session); interval = read_impl.microseconds_per_packet / 1000; samples = switch_samples_per_packet(member->conference->rate, interval); - csamples = samples; + //csamples = samples; tsamples = member->orig_read_impl.samples_per_packet; flush_len = 0; low_count = 0; @@ -2552,82 +2523,77 @@ static void conference_loop_output(conference_member_t *member) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Setup timer %s success interval: %u samples: %u\n", member->conference->timer_name, interval, tsamples); - if (!restarting) { - write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE); - write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; - } + + write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE); + write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; + write_frame.codec = &member->write_codec; - if (!restarting) { - /* Start the input thread */ - launch_conference_loop_input(member, switch_core_session_get_pool(member->session)); + /* Start the input thread */ + launch_conference_loop_input(member, switch_core_session_get_pool(member->session)); - if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { - const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name"); - const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number"); - const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); - const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags"); - const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile"); - const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); - const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); - int to = 60; - - if (ann && !switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { - member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); - } - - switch_channel_set_private(channel, "_conference_autocall_list_", NULL); - - switch_set_flag(member->conference, CFLAG_OUTCALL); - - if (toval) { - to = atoi(toval); - if (to < 10 || to > 500) { - to = 60; - } - } - - for (cp = call_list; cp; cp = cp->next) { - int argc; - char *argv[512] = { 0 }; - char *cpstr = strdup(cp->string); - int x = 0; - - switch_assert(cpstr); - argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); - switch_assert(dial_str); - conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL, - profile, &member->conference->cancel_cause); - switch_safe_free(dial_str); - } - switch_safe_free(cpstr); - } - - do { - switch_ivr_sleep(member->session, 500, SWITCH_TRUE, NULL); - } while(switch_channel_up(channel) && member->conference->originating); - - if (!switch_channel_ready(channel)) { - member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; - goto end; - } - - conference_member_play_file(member, "tone_stream://%(500,0,640)", 0); + if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { + const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name"); + const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number"); + const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); + const char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags"); + const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile"); + const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); + const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); + int to = 60; + if (ann && !switch_channel_test_app_flag_key("conf_silent", channel, CONF_SILENT_REQ)) { + member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); } + + switch_channel_set_private(channel, "_conference_autocall_list_", NULL); + + switch_set_flag(member->conference, CFLAG_OUTCALL); + + if (toval) { + to = atoi(toval); + if (to < 10 || to > 500) { + to = 60; + } + } + + for (cp = call_list; cp; cp = cp->next) { + int argc; + char *argv[512] = { 0 }; + char *cpstr = strdup(cp->string); + int x = 0; + + switch_assert(cpstr); + argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); + switch_assert(dial_str); + conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL, + profile, &member->conference->cancel_cause); + switch_safe_free(dial_str); + } + switch_safe_free(cpstr); + } + + switch_channel_set_app_flag(channel, CF_APP_TAGGED); + do { + switch_ivr_sleep(member->session, 500, SWITCH_TRUE, NULL); + } while(switch_channel_up(channel) && member->conference->originating); + switch_channel_clear_app_flag(channel, CF_APP_TAGGED); + + if (!switch_channel_ready(channel)) { + member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; + goto end; + } + + conference_member_play_file(member, "tone_stream://%(500,0,640)", 0); } if (!switch_test_flag(member->conference, CFLAG_ANSWERED)) { switch_channel_answer(channel); } - if (restarting) { - switch_channel_clear_app_flag(channel, CF_APP_TAGGED); - } - /* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */ /* you better not block this thread loop for more than the duration of member->conference->timer_name! */ while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD) @@ -2640,11 +2606,6 @@ static void conference_loop_output(conference_member_t *member) switch_mutex_lock(member->write_mutex); - if (switch_test_flag(member, MFLAG_RESTART)) { - switch_mutex_unlock(member->write_mutex); - goto top; - } - if (switch_core_session_dequeue_event(member->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { if (event->event_id == SWITCH_EVENT_MESSAGE) { char *from = switch_event_get_header(event, "from"); @@ -2830,7 +2791,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th conference_record_t *rec = (conference_record_t *) obj; conference_obj_t *conference = rec->conference; uint32_t samples = switch_samples_per_packet(conference->rate, conference->interval); - uint32_t low_count = 0, mux_used; + uint32_t mux_used; char *vval; switch_timer_t timer = { 0 }; uint32_t rlen; @@ -2957,7 +2918,7 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th if (mux_used >= data_buf_len) { /* Flush the output buffer and write all the data (presumably muxed) to the file */ switch_mutex_lock(member->audio_out_mutex); - low_count = 0; + //low_count = 0; if ((rlen = (uint32_t) switch_buffer_read(member->mux_buffer, data_buf, data_buf_len))) { len = (switch_size_t) rlen / sizeof(int16_t); @@ -2993,14 +2954,14 @@ static void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *th end: - for(;;) { - switch_mutex_lock(member->audio_out_mutex); + while(!no_data) { + switch_mutex_lock(member->audio_out_mutex); if ((rlen = (uint32_t) switch_buffer_read(member->mux_buffer, data_buf, data_buf_len))) { len = (switch_size_t) rlen / sizeof(int16_t); switch_core_file_write(&fh, data_buf, &len); } else { - break; - } + no_data = 1; + } switch_mutex_unlock(member->audio_out_mutex); } @@ -3780,18 +3741,18 @@ static switch_status_t conf_api_sub_kick(conference_member_t *member, switch_str { switch_event_t *event; - if (member == NULL) + if (member == NULL) { return SWITCH_STATUS_GENERR; - - lock_member(member); + } + switch_clear_flag(member, MFLAG_RUNNING); switch_set_flag_locked(member, MFLAG_KICKED); - switch_core_session_kill_channel(member->session, SWITCH_SIG_BREAK); - unlock_member(member); + if (stream != NULL) { stream->write_function(stream, "OK kicked %u\n", member->id); } + if (member->conference && test_eflag(member->conference, EFLAG_KICK_MEMBER)) { if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_add_event_member_data(member, event); @@ -3799,6 +3760,7 @@ static switch_status_t conf_api_sub_kick(conference_member_t *member, switch_str switch_event_fire(&event); } } + return SWITCH_STATUS_SUCCESS; } @@ -4023,7 +3985,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer switch_snprintf(i, sizeof(i), "%u", conference->rate); switch_xml_set_attr_d(x_conference, "rate", ival); switch_xml_set_attr_d(x_conference, "uuid", conference->uuid_str); - + if (switch_test_flag(conference, CFLAG_LOCKED)) { switch_xml_set_attr_d(x_conference, "locked", "true"); } @@ -4056,6 +4018,14 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer switch_xml_set_attr_d(x_conference, "dynamic", "true"); } + if (switch_test_flag(conference, CFLAG_EXIT_SOUND)) { + switch_xml_set_attr_d(x_conference, "exit_sound", "true"); + } + + if (switch_test_flag(conference, CFLAG_ENTER_SOUND)) { + switch_xml_set_attr_d(x_conference, "enter_sound", "true"); + } + if (conference->record_count > 0) { switch_xml_set_attr_d(x_conference, "recording", "true"); } @@ -4078,7 +4048,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer switch_channel_t *channel; switch_caller_profile_t *profile; char *uuid; - char *name; + //char *name; uint32_t count = 0; switch_xml_t x_tag; int toff = 0; @@ -4091,7 +4061,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer uuid = switch_core_session_get_uuid(member->session); channel = switch_core_session_get_channel(member->session); profile = switch_channel_get_caller_profile(channel); - name = switch_channel_get_name(channel); + //name = switch_channel_get_name(channel); x_member = switch_xml_add_child_d(x_members, "member", moff++); @@ -4516,6 +4486,107 @@ static switch_status_t conf_api_sub_unlock(conference_obj_t *conference, switch_ return 0; } +static switch_status_t conf_api_sub_exit_sound(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) +{ + switch_event_t *event; + + switch_assert(conference != NULL); + switch_assert(stream != NULL); + + if (argc <= 2) { + stream->write_function(stream, "Not enough args\n"); + return SWITCH_STATUS_GENERR; + } + + if ( !strcasecmp(argv[2], "on") ) { + switch_set_flag_locked(conference, CFLAG_EXIT_SOUND); + stream->write_function(stream, "OK %s exit sounds on (%s)\n", argv[0], conference->exit_sound); + if (test_eflag(conference, EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sounds-on"); + switch_event_fire(&event); + } + } else if ( !strcasecmp(argv[2], "off") || !strcasecmp(argv[2], "none") ) { + switch_clear_flag_locked(conference, CFLAG_EXIT_SOUND); + stream->write_function(stream, "OK %s exit sounds off (%s)\n", argv[0], conference->exit_sound); + if (test_eflag(conference, EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sounds-off"); + switch_event_fire(&event); + } + } else if ( !strcasecmp(argv[2], "file") ) { + if (! argv[3]) { + stream->write_function(stream, "No filename specified\n"); + } else { + /* TODO: if possible, verify file exists before setting it */ + stream->write_function(stream,"Old exit sound: [%s]\n", conference->exit_sound); + conference->exit_sound = switch_core_strdup(conference->pool, argv[3]); + stream->write_function(stream, "OK %s exit sound file set to %s\n", argv[0], conference->exit_sound); + if (test_eflag(conference, EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "exit-sound-file-changed"); + switch_event_fire(&event); + } + } + } else { + stream->write_function(stream, "Bad args\n"); + return SWITCH_STATUS_GENERR; + } + + return 0; +} + + +static switch_status_t conf_api_sub_enter_sound(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) +{ + switch_event_t *event; + + switch_assert(conference != NULL); + switch_assert(stream != NULL); + + if (argc <= 2) { + stream->write_function(stream, "Not enough args\n"); + return SWITCH_STATUS_GENERR; + } + + if ( !strcasecmp(argv[2], "on") ) { + switch_set_flag_locked(conference, CFLAG_ENTER_SOUND); + stream->write_function(stream, "OK %s enter sounds on (%s)\n", argv[0], conference->enter_sound); + if (test_eflag(conference, EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sounds-on"); + switch_event_fire(&event); + } + } else if ( !strcasecmp(argv[2], "off") || !strcasecmp(argv[2], "none") ) { + switch_clear_flag_locked(conference, CFLAG_ENTER_SOUND); + stream->write_function(stream, "OK %s enter sounds off (%s)\n", argv[0], conference->enter_sound); + if (test_eflag(conference, EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sounds-off"); + switch_event_fire(&event); + } + } else if ( !strcasecmp(argv[2], "file") ) { + if (! argv[3]) { + stream->write_function(stream, "No filename specified\n"); + } else { + /* TODO: verify file exists before setting it */ + conference->enter_sound = switch_core_strdup(conference->pool, argv[3]); + stream->write_function(stream, "OK %s enter sound file set to %s\n", argv[0], conference->enter_sound); + if (test_eflag(conference, EFLAG_LOCK) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + conference_add_event_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "enter-sound-file-changed"); + switch_event_fire(&event); + } + } + } else { + stream->write_function(stream, "Bad args\n"); + return SWITCH_STATUS_GENERR; + } + + return 0; +} + + static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { switch_call_cause_t cause; @@ -4720,7 +4791,9 @@ typedef enum { CONF_API_COMMAND_BGDIAL, CONF_API_COMMAND_TRANSFER, CONF_API_COMMAND_RECORD, - CONF_API_COMMAND_NORECORD + CONF_API_COMMAND_NORECORD, + CONF_API_COMMAND_EXIT_SOUND, + CONF_API_COMMAND_ENTER_SOUND, } api_command_type_t; /* API Interface Function sub-commands */ @@ -4750,6 +4823,8 @@ static api_command_t conf_api_sub_commands[] = { {"transfer", (void_fn_t) & conf_api_sub_transfer, CONF_API_SUB_ARGS_SPLIT, "transfer", " [...]"}, {"record", (void_fn_t) & conf_api_sub_record, CONF_API_SUB_ARGS_SPLIT, "record", ""}, {"norecord", (void_fn_t) & conf_api_sub_norecord, CONF_API_SUB_ARGS_SPLIT, "norecord", "<[filename|all]>"}, + {"exit_sound", (void_fn_t) & conf_api_sub_exit_sound, CONF_API_SUB_ARGS_SPLIT, "exit_sound", "on|off|none|file "}, + {"enter_sound", (void_fn_t) & conf_api_sub_enter_sound, CONF_API_SUB_ARGS_SPLIT, "enter_sound", "on|off|none|file "}, {"pin", (void_fn_t) & conf_api_sub_pin, CONF_API_SUB_ARGS_SPLIT, "pin", ""}, {"nopin", (void_fn_t) & conf_api_sub_pin, CONF_API_SUB_ARGS_SPLIT, "nopin", ""}, }; @@ -5330,7 +5405,7 @@ static void set_cflags(const char *flags, uint32_t *f) } else if (!strcasecmp(argv[i], "waste-bandwidth")) { *f |= CFLAG_WASTE_BANDWIDTH; } - } + } free(dup); } @@ -5543,7 +5618,7 @@ static int setup_media(conference_member_t *member, conference_obj_t *conference SWITCH_STANDARD_APP(conference_function) { switch_codec_t *read_codec = NULL; - uint32_t flags = 0; + //uint32_t flags = 0; conference_member_t member = { 0 }; conference_obj_t *conference = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -5931,7 +6006,7 @@ SWITCH_STANDARD_APP(conference_function) member.pool = switch_core_session_get_pool(session); if (setup_media(&member, conference)) { - flags = 0; + //flags = 0; goto done; } @@ -6220,7 +6295,6 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c uint32_t announce_count = 0; char *maxmember_sound = NULL; uint32_t rate = 8000, interval = 20; - switch_status_t status; int comfort_noise_level = 0; char *suppress_events = NULL; char *verbose_events = NULL; @@ -6434,7 +6508,6 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c /* Setup a memory pool to use. */ if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n"); - status = SWITCH_STATUS_TERM; conference = NULL; goto end; } @@ -6443,7 +6516,6 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c /* Create the conference object. */ if (!(conference = switch_core_alloc(pool, sizeof(*conference)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n"); - status = SWITCH_STATUS_TERM; conference = NULL; goto end; } @@ -6620,7 +6692,10 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c switch_uuid_format(uuid_str, &uuid); conference->uuid_str = switch_core_strdup(conference->pool, uuid_str); - + /* Set enter sound and exit sound flags so that default is on */ + switch_set_flag(conference, CFLAG_ENTER_SOUND); + switch_set_flag(conference, CFLAG_EXIT_SOUND); + /* Activate the conference mutex for exclusivity */ switch_mutex_init(&conference->mutex, SWITCH_MUTEX_NESTED, conference->pool); switch_mutex_init(&conference->flag_mutex, SWITCH_MUTEX_NESTED, conference->pool); diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index 633e4c80e2..adcfe453de 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -104,7 +104,6 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c CURL *curl_handle = NULL; long httpRes = 0; - char hostname[256] = ""; http_data_t *http_data = NULL; @@ -115,8 +114,6 @@ static http_data_t *do_lookup_url(switch_memory_pool_t *pool, const char *url, c http_data->max_bytes = 64000; SWITCH_STANDARD_STREAM(http_data->stream); - gethostname(hostname, sizeof(hostname)); - if (!method) { method = "get"; } diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index e611d036ea..165e02e949 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -598,7 +598,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_db_load) switch_limit_interface_t *limit_interface; memset(&globals, 0, sizeof(&globals)); - gethostname(globals.hostname, sizeof(globals.hostname)); + strncpy(globals.hostname, switch_core_get_switchname(), sizeof(globals.hostname)); globals.pool = pool; diff --git a/src/mod/applications/mod_directory/mod_directory.c b/src/mod/applications/mod_directory/mod_directory.c index 0127363064..b4c7d94e78 100644 --- a/src/mod/applications/mod_directory/mod_directory.c +++ b/src/mod/applications/mod_directory/mod_directory.c @@ -67,7 +67,7 @@ static switch_xml_config_int_options_t config_int_ht_0 = { SWITCH_TRUE, 0 }; static struct { switch_hash_t *profile_hash; - char hostname[256]; + const char *hostname; int integer; int debug; char *dbname; @@ -949,7 +949,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_directory_load) /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); - gethostname(globals.hostname, sizeof(globals.hostname)); + globals.hostname = switch_core_get_switchname(); globals.dbname = switch_core_sprintf(pool, "directory"); diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index c51c5422a5..5b982111d5 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1552,7 +1552,8 @@ SWITCH_STANDARD_APP(tone_detect_session_function) int argc; char *mydata = NULL; time_t to = 0; - int hits = 1; + int hits = 0; + const char *hp = NULL; if (zstr(data) || !(mydata = switch_core_session_strdup(session, data))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "INVALID ARGS!\n"); @@ -1582,10 +1583,16 @@ SWITCH_STANDARD_APP(tone_detect_session_function) } } - if (argv[6]) { - hits = atoi(argv[6]); + if (argv[4] && argv[5]) { + hp = argv[6]; + } else if (argv[4] && !argv[6]) { + hp = argv[4]; + } + + if (hp) { + hits = atoi(hp); if (hits < 0) { - hits = 1; + hits = 0; } } @@ -2291,14 +2298,14 @@ SWITCH_STANDARD_APP(record_function) char *path; switch_input_args_t args = { 0 }; switch_file_handle_t fh = { 0 }; - int argc; + //int argc; char *mydata, *argv[4] = { 0 }; char *l = NULL; const char *tmp; int rate; if (!zstr(data) && (mydata = switch_core_session_strdup(session, data))) { - argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No file specified.\n"); return; @@ -2483,7 +2490,7 @@ SWITCH_STANDARD_APP(audio_bridge_function) const char *transfer_on_fail = NULL; char *tof_data = NULL; char *tof_array[4] = { 0 }; - int tof_arrayc = 0; + //int tof_arrayc = 0; const char *continue_on_fail = NULL, *failure_causes = NULL, *v_campon = NULL, *v_campon_retries, *v_campon_sleep, *v_campon_timeout, *v_campon_fallback_exten = NULL; switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING; @@ -2503,7 +2510,7 @@ SWITCH_STANDARD_APP(audio_bridge_function) transfer_on_fail = switch_channel_get_variable(caller_channel, "transfer_on_fail"); tof_data = switch_core_session_strdup(session, transfer_on_fail); - tof_arrayc = switch_split(tof_data, ' ', tof_array); + switch_split(tof_data, ' ', tof_array); transfer_on_fail = tof_array[0]; failure_causes = switch_channel_get_variable(caller_channel, "failure_causes"); diff --git a/src/mod/applications/mod_enum/mod_enum.c b/src/mod/applications/mod_enum/mod_enum.c index d1bb286857..670f5443c5 100644 --- a/src/mod/applications/mod_enum/mod_enum.c +++ b/src/mod/applications/mod_enum/mod_enum.c @@ -70,6 +70,8 @@ static struct { switch_memory_pool_t *pool; int auto_reload; int timeout; + int retries; + int random; } globals; SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_root, globals.root); @@ -109,6 +111,10 @@ static switch_status_t load_config(void) goto done; } + globals.timeout = 5000; + globals.retries = 3; + globals.random = 0; + 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"); @@ -120,7 +126,13 @@ static switch_status_t load_config(void) } else if (!strcasecmp(var, "auto-reload")) { globals.auto_reload = switch_true(val); } else if (!strcasecmp(var, "query-timeout")) { + globals.timeout = atoi(val) * 1000; + } else if (!strcasecmp(var, "query-timeout-ms")) { globals.timeout = atoi(val); + } else if (!strcasecmp(var, "query-timeout-retry")) { + globals.retries = atoi(val); + } else if (!strcasecmp(var, "random-nameserver")) { + globals.random = switch_true(val); } else if (!strcasecmp(var, "default-isn-root")) { set_global_isn_root(val); } else if (!strcasecmp(var, "log-level-trace")) { @@ -164,6 +176,7 @@ static switch_status_t load_config(void) if(buf[data_sz - 1] != 0) { buf[data_sz] = 0; } + switch_replace_char(buf, ' ', 0, SWITCH_FALSE); /* only use the first entry ex "192.168.1.1 192.168.1.2" */ globals.server = buf; } } @@ -403,6 +416,7 @@ switch_status_t ldns_lookup(const char *number, const char *root, const char *se ldns_rdf *serv_rdf; switch_status_t status = SWITCH_STATUS_FALSE; char *name = NULL; + struct timeval to = { 0, 0}; if (!(name = reverse_number(number, root))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parse Error!\n"); @@ -430,6 +444,13 @@ switch_status_t ldns_lookup(const char *number, const char *root, const char *se goto end; } + to.tv_sec = globals.timeout / 1000; + to.tv_usec = (globals.timeout % 1000) * 1000; + + ldns_resolver_set_timeout(res, to); + ldns_resolver_set_retry(res, (uint8_t)globals.retries); + ldns_resolver_set_random(res, globals.random); + if ((p = ldns_resolver_query(res, domain, LDNS_RR_TYPE_NAPTR, diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index a2f8ddb8cd..39952f2a8c 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -71,7 +71,7 @@ SWITCH_STANDARD_APP(bcast_function) switch_port_t rtp_port; char guess_ip[25]; ls_how_t ready = SEND_TYPE_UNKNOWN; - int argc; + //int argc; char *mydata, *argv[5]; char *mcast_ip = "224.168.168.168"; switch_port_t mcast_port = 34567; @@ -87,7 +87,7 @@ SWITCH_STANDARD_APP(bcast_function) mydata = switch_core_session_strdup(session, data); assert(mydata != NULL); - argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); if ((var = switch_channel_get_variable(channel, "esf_multicast_ip"))) { mcast_ip = switch_core_session_strdup(session, var); diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 2e074138ba..1984406eff 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1167,7 +1167,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; switch_call_cause_t cancel_cause = 0; char *uuid_list = NULL; - int connected = 0, total = 0; + int total = 0; const char *codec; struct call_helper *rows[MAX_ROWS] = { 0 }; int rowcount = 0; @@ -1238,7 +1238,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void struct call_helper *h = cbh->rows[i]; char *parsed = NULL; - switch_event_create_brackets(h->originate_string, '{', '}', ',', &ovars, &parsed); + switch_event_create_brackets(h->originate_string, '{', '}', ',', &ovars, &parsed, SWITCH_TRUE); switch_event_del_header(ovars, "fifo_outbound_uuid"); if (!h->timeout) h->timeout = node->ring_timeout; @@ -1417,8 +1417,6 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void goto end; } - connected = 1; - channel = switch_core_session_get_channel(session); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { @@ -1513,7 +1511,6 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) switch_status_t status = SWITCH_STATUS_FALSE; switch_event_t *event = NULL; char *sql = NULL; - int connected = 0; if (!globals.running) return NULL; @@ -1592,8 +1589,6 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) goto end; } - connected = 1; - channel = switch_core_session_get_channel(session); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { @@ -3870,7 +3865,7 @@ static void extract_fifo_outbound_uuid(char *string, char *uuid, switch_size_t l switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS); - switch_event_create_brackets(string, '{', '}', ',', &ovars, &parsed); + switch_event_create_brackets(string, '{', '}', ',', &ovars, &parsed, SWITCH_TRUE); if ((fifo_outbound_uuid = switch_event_get_header(ovars, "fifo_outbound_uuid"))) { switch_snprintf(uuid, len, "%s", fifo_outbound_uuid); @@ -3890,7 +3885,7 @@ static switch_status_t load_config(int reload, int del_all) switch_cache_db_handle_t *dbh = NULL; fifo_node_t *node; - gethostname(globals.hostname, sizeof(globals.hostname)); + strncpy(globals.hostname, switch_core_get_switchname(), sizeof(globals.hostname)); if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); diff --git a/src/mod/applications/mod_hash/mod_hash.c b/src/mod/applications/mod_hash/mod_hash.c index e3f01cec96..f9b808fad1 100644 --- a/src/mod/applications/mod_hash/mod_hash.c +++ b/src/mod/applications/mod_hash/mod_hash.c @@ -531,16 +531,33 @@ SWITCH_STANDARD_API(hash_api_function) return SWITCH_STATUS_SUCCESS; } -#define HASH_DUMP_SYNTAX "all|limit|db" +#define HASH_DUMP_SYNTAX "all|limit|db []" SWITCH_STANDARD_API(hash_dump_function) { int mode; switch_hash_index_t *hi; + int argc = 0; + char *argv[4] = { 0 }; + char *mydata = NULL; + int realm = 0; + char *realmvalue = NULL; - if (zstr(cmd)) { + if (!zstr(cmd)) { + mydata = strdup(cmd); + switch_assert(mydata); + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } else { + realmvalue = "test"; + realm = 0; stream->write_function(stream, "Usage: "HASH_DUMP_SYNTAX"\n"); return SWITCH_STATUS_SUCCESS; - } + } + + cmd = strdup(argv[0]); + if (argc == 2) { + realm = 1; + realmvalue = switch_mprintf("%s_", argv[1]); + } if (!strcmp(cmd, "all")) { mode = 3; @@ -553,7 +570,6 @@ SWITCH_STANDARD_API(hash_dump_function) return SWITCH_STATUS_SUCCESS; } - if (mode & 1) { switch_thread_rwlock_rdlock(globals.limit_hash_rwlock); for (hi = switch_hash_first(NULL, globals.limit_hash); hi; hi = switch_hash_next(hi)) { @@ -577,8 +593,13 @@ SWITCH_STANDARD_API(hash_dump_function) const void *key; switch_ssize_t keylen; switch_hash_this(hi, &key, &keylen, &val); - - stream->write_function(stream, "D/%s/%s\n", key, (char*)val); + if (realm) { + if (strstr(key, realmvalue)) { + stream->write_function(stream, "D/%s/%s\n", key, (char*)val); + } + } else { + stream->write_function(stream, "D/%s/%s\n", key, (char*)val); + } } switch_thread_rwlock_unlock(globals.db_hash_rwlock); } @@ -590,7 +611,7 @@ SWITCH_STANDARD_API(hash_dump_function) #define HASH_REMOTE_SYNTAX "list|kill [name]|rescan" SWITCH_STANDARD_API(hash_remote_function) { - int argc; + //int argc; char *argv[10]; char *dup = NULL; @@ -601,7 +622,7 @@ SWITCH_STANDARD_API(hash_remote_function) dup = strdup(cmd); - argc = switch_split(dup, ' ', argv); + switch_split(dup, ' ', argv); if (argv[0] && !strcmp(argv[0], "list")) { switch_hash_index_t *hi; stream->write_function(stream, "Remote connections:\nName\t\t\tState\n"); diff --git a/src/mod/applications/mod_ladspa/mod_ladspa.c b/src/mod/applications/mod_ladspa/mod_ladspa.c index 43ea87a3ca..bab6ff5216 100644 --- a/src/mod/applications/mod_ladspa/mod_ladspa.c +++ b/src/mod/applications/mod_ladspa/mod_ladspa.c @@ -565,12 +565,11 @@ switch_status_t ladspa_session(switch_core_session_t *session, const char *flags static void ladspa_parse(switch_core_session_t *session, const char *data) { char *argv[5] = { 0 }; - int argc; char *lbuf; if (data) { lbuf = strdup(data); - argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0]))); ladspa_session(session, argv[0], argv[1], argv[2], argv[3]); free(lbuf); } diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 17bbb443b1..c0d99dfc35 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -133,6 +133,7 @@ struct callback_obj { profile_t *profile; switch_core_session_t *session; switch_event_t *event; + float max_rate; }; typedef struct callback_obj callback_t; @@ -247,14 +248,13 @@ static char *get_bridge_data(switch_memory_pool_t *pool, char *dialed_number, ch size_t tstrip; char *data = NULL; char *destination_number = NULL; - char *orig_destination_number = NULL; char *codec = NULL; char *cid = NULL; char *header = NULL; char *user_rate = NULL; char *export_fields = NULL; - orig_destination_number = destination_number = switch_core_strdup(pool, dialed_number); + destination_number = switch_core_strdup(pool, dialed_number); tstrip = ((cur_route->digit_len - cur_route->tstrip) + 1); lstrip = cur_route->lstrip; @@ -621,6 +621,9 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa } else if (CF("lcr_carrier_name")) { additional->carrier_name = switch_core_strdup(pool, switch_str_nil(argv[i])); } else if (CF("lcr_rate_field")) { + if (!argv[i] || zstr(argv[i])) { + goto end; + } additional->rate = (float)atof(switch_str_nil(argv[i])); additional->rate_str = switch_core_sprintf(pool, "%0.5f", additional->rate); } else if (CF("lcr_gw_prefix")) { @@ -666,9 +669,14 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa r = 0; goto end; } - + for (current = cbt->head; current; current = current->next) { - + if (cbt->max_rate && (cbt->max_rate < additional->rate)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Skipping [%s] because [%f] is higher than the max_rate of [%f]\n", + additional->carrier_name, additional->rate, cbt->max_rate); + break; + } + key = switch_core_sprintf(pool, "%s:%s", additional->gw_prefix, additional->gw_suffix); if (switch_core_hash_find(cbt->dedup_hash, key)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, @@ -760,10 +768,14 @@ static switch_status_t is_intrastatelata(callback_t *cb_struct) */ if (!cb_struct->lookup_number || strlen(cb_struct->lookup_number) != 11 || *cb_struct->lookup_number != '1' || !switch_is_number(cb_struct->lookup_number)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, + "%s doesn't appear to be a NANP number\n", cb_struct->lookup_number); /* dest doesn't appear to be NANP number */ return SWITCH_STATUS_GENERR; } if (!cb_struct->cid || strlen(cb_struct->cid) != 11 || *cb_struct->cid != '1' || !switch_is_number(cb_struct->cid)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, + "%s doesn't appear to be a NANP number\n", cb_struct->cid); /* cid not NANP */ return SWITCH_STATUS_GENERR; } @@ -821,6 +833,7 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) digits_expanded = expand_digits(cb_struct->pool, digits_copy, cb_struct->profile->quote_in_list); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "Has NPA NXX: [%u == %u]\n", profile->profile_has_npanxx, SWITCH_TRUE); if (profile->profile_has_npanxx == SWITCH_TRUE) { is_intrastatelata(cb_struct); } @@ -843,6 +856,10 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) if (cb_struct->session) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "we have a session\n"); if ((channel = switch_core_session_get_channel(cb_struct->session))) { + const char *max_rate = switch_channel_get_variable(channel, "max_rate"); + if (!zstr(max_rate)) { + cb_struct->max_rate = atof(max_rate); + } switch_channel_set_variable_var_check(channel, "lcr_rate_field", rate_field, SWITCH_FALSE); switch_channel_set_variable_var_check(channel, "lcr_user_rate_field", user_rate_field, SWITCH_FALSE); switch_channel_set_variable_var_check(channel, "lcr_query_digits", digits_copy, SWITCH_FALSE); @@ -1062,13 +1079,17 @@ static switch_status_t lcr_load_config() if (zstr(custom_sql)) { /* use default sql */ sql_stream.write_function(&sql_stream, - "SELECT l.digits AS lcr_digits, c.carrier_name AS lcr_carrier_name, l.${lcr_rate_field} AS lcr_rate_field, cg.prefix AS lcr_gw_prefix, cg.suffix AS lcr_gw_suffix, l.lead_strip AS lcr_lead_strip, l.trail_strip AS lcr_trail_strip, l.prefix AS lcr_prefix, l.suffix AS lcr_suffix " + "SELECT l.digits AS lcr_digits, c.carrier_name AS lcr_carrier_name, l.${lcr_rate_field} AS lcr_rate_field, \ + cg.prefix AS lcr_gw_prefix, cg.suffix AS lcr_gw_suffix, l.lead_strip AS lcr_lead_strip, \ + l.trail_strip AS lcr_trail_strip, l.prefix AS lcr_prefix, l.suffix AS lcr_suffix " ); if (db_check("SELECT codec from carrier_gateway limit 1") == SWITCH_TRUE) { sql_stream.write_function(&sql_stream, ", cg.codec AS lcr_codec "); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "codec field defined.\n"); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "codec field not defined, please update your lcr carrier_gateway database schema.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "codec field not defined, please update your lcr carrier_gateway database schema.\n" + ); } if (db_check("SELECT cid from lcr limit 1") == SWITCH_TRUE) { sql_stream.write_function(&sql_stream, ", l.cid AS lcr_cid "); @@ -1076,12 +1097,15 @@ static switch_status_t lcr_load_config() } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cid field not defined, please update your lcr database schema.\n"); } - sql_stream.write_function(&sql_stream, "FROM lcr l JOIN carriers c ON l.carrier_id=c.id JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN ("); + sql_stream.write_function(&sql_stream, "FROM lcr l JOIN carriers c ON l.carrier_id=c.id \ + JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE \ + c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN ("); sql_stream.write_function(&sql_stream, "${lcr_query_expanded_digits}"); sql_stream.write_function(&sql_stream, ") AND CURRENT_TIMESTAMP BETWEEN date_start AND date_end "); if (profile->id > 0) { sql_stream.write_function(&sql_stream, "AND lcr_profile=%d ", profile->id); } + sql_stream.write_function(&sql_stream, "ORDER BY digits DESC%s", profile->order_by); if (db_random) { @@ -1238,7 +1262,6 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session, const char *intralata = NULL; switch_core_session_t *mysession = NULL; switch_channel_t *channel = NULL; - switch_caller_profile_t *caller_profile = NULL; dest = strdup(outbound_profile->destination_number); @@ -1265,7 +1288,6 @@ static switch_call_cause_t lcr_outgoing_channel(switch_core_session_t *session, timelimit = atoi(var); } routes.session = session; - caller_profile = switch_channel_get_caller_profile(channel); intrastate = switch_channel_get_variable(channel, "intrastate"); intralata = switch_channel_get_variable(channel, "intralata"); cid_name_override = switch_channel_get_variable(channel, "origination_caller_id_name"); @@ -1642,10 +1664,10 @@ static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, con SWITCH_STANDARD_API(dialplan_lcr_function) { - char *argv[4] = { 0 }; + char *argv[9] = { 0 }; int argc; char *mydata = NULL; - char *dialstring = NULL; + //char *dialstring = NULL; char *lcr_profile = NULL; lcr_route current = NULL; max_obj_t maximum_lengths = { 0 }; @@ -1767,7 +1789,8 @@ SWITCH_STANDARD_API(dialplan_lcr_function) current = cb_struct.head; while (current) { - dialstring = get_bridge_data(pool, cb_struct.lookup_number, cb_struct.cid, current, cb_struct.profile, cb_struct.session); + //dialstring = + get_bridge_data(pool, cb_struct.lookup_number, cb_struct.cid, current, cb_struct.profile, cb_struct.session); rowcount++; if (as_xml) { @@ -1802,7 +1825,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function) if (as_xml) { event_xml = switch_event_xmlize(current->fields, SWITCH_VA_NONE); event_str = switch_xml_toxml(event_xml, SWITCH_FALSE); - stream->write_function(stream, event_str); + stream->write_function(stream, "%s", event_str); switch_xml_free(event_xml); switch_safe_free(event_str); } @@ -1880,16 +1903,11 @@ SWITCH_STANDARD_API(dialplan_lcr_admin_function) stream->write_function(stream, " has intrastate:\t%s\n", profile->profile_has_intrastate ? "true" : "false"); stream->write_function(stream, " has intralata:\t%s\n", profile->profile_has_intralata ? "true" : "false"); stream->write_function(stream, " has npanxx:\t%s\n", profile->profile_has_npanxx ? "true" : "false"); - stream->write_function(stream, " Reorder rate:\t%s\n", - profile->reorder_by_rate ? "enabled" : "disabled"); - stream->write_function(stream, " Info in headers:\t%s\n", - profile->info_in_headers ? "enabled" : "disabled"); - stream->write_function(stream, " Quote IN() List:\t%s\n", - profile->quote_in_list ? "enabled" : "disabled"); - stream->write_function(stream, " Sip Redirection Mode:\t%s\n", - profile->enable_sip_redir ? "enabled" : "disabled"); - stream->write_function(stream, " Import fields:\t%s\n", - profile->export_fields_str ? profile->export_fields_str : "(null)"); + stream->write_function(stream, " Reorder rate:\t%s\n", profile->reorder_by_rate ? "enabled" : "disabled"); + stream->write_function(stream, " Info in headers:\t%s\n", profile->info_in_headers ? "enabled" : "disabled"); + stream->write_function(stream, " Quote IN() List:\t%s\n", profile->quote_in_list ? "enabled" : "disabled"); + stream->write_function(stream, " Sip Redirection Mode:\t%s\n", profile->enable_sip_redir ? "enabled" : "disabled"); + stream->write_function(stream, " Import fields:\t%s\n", profile->export_fields_str ? profile->export_fields_str : "(null)"); stream->write_function(stream, " Limit type:\t%s\n", profile->limit_type); stream->write_function(stream, "\n"); } diff --git a/src/mod/applications/mod_mongo/Makefile b/src/mod/applications/mod_mongo/Makefile new file mode 100644 index 0000000000..26687b5ac6 --- /dev/null +++ b/src/mod/applications/mod_mongo/Makefile @@ -0,0 +1,29 @@ +BASE=../../../.. + +MONGO_CXX_DRIVER_VERSION=v1.8 +MONGO_CXX_DRIVER_URL=http://downloads.mongodb.org/cxx-driver +MONGO_CXX_DRIVER_TARBALL=mongodb-linux-x86_64-$(MONGO_CXX_DRIVER_VERSION)-latest.tgz +MONGO_CXX_DRIVER_SRC=$(BASE)/libs/mongo-cxx-driver-$(MONGO_CXX_DRIVER_VERSION) +LIBMONGOCLIENT_A =$(MONGO_CXX_DRIVER_SRC)/libmongoclient.a + +LOCAL_SOURCES=mongo_conn.cpp +LOCAL_OBJS=mongo_conn.o + +LOCAL_CFLAGS=-I$(MONGO_CXX_DRIVER_SRC)/mongo +LOCAL_LIBADD=$(LIBMONGOCLIENT_A) +LOCAL_LDFLAGS=-lboost_thread -lboost_filesystem-mt -lboost_system-mt +MODDIR=$(shell pwd) + + +include $(BASE)/build/modmake.rules + +$(MONGO_CXX_DRIVER_SRC): + $(GETLIB) $(MONGO_CXX_DRIVER_URL) $(MONGO_CXX_DRIVER_TARBALL) + cd $(MONGO_CXX_DRIVER_SRC) && patch -p0 -i $(MODDIR)/fpic_hack.diff + $(TOUCH_TARGET) + + +$(LIBMONGOCLIENT_A): $(MONGO_CXX_DRIVER_SRC) + cd $(MONGO_CXX_DRIVER_SRC) && scons + $(TOUCH_TARGET) + diff --git a/src/mod/applications/mod_mongo/fpic_hack.diff b/src/mod/applications/mod_mongo/fpic_hack.diff new file mode 100644 index 0000000000..882f3c899a --- /dev/null +++ b/src/mod/applications/mod_mongo/fpic_hack.diff @@ -0,0 +1,11 @@ +--- SConstruct.orig 2011-04-28 19:00:36.000000000 +0200 ++++ SConstruct 2011-04-28 19:01:19.000000000 +0200 +@@ -45,7 +45,7 @@ + linux = True + + if nix: +- env.Append( CPPFLAGS=" -O3" ) ++ env.Append( CPPFLAGS=" -I../pcre -fPIC -O3" ) + env.Append( LIBS=["pthread"] ) + if linux: + env.Append( LINKFLAGS=" -Wl,--as-needed -Wl,-zdefs " ) diff --git a/src/mod/applications/mod_mongo/mod_mongo.cpp b/src/mod/applications/mod_mongo/mod_mongo.cpp new file mode 100644 index 0000000000..bb82c840e0 --- /dev/null +++ b/src/mod/applications/mod_mongo/mod_mongo.cpp @@ -0,0 +1,151 @@ +#include +#include "mod_mongo.h" + + +static struct { + mongo_connection_pool_t *conn_pool; +} globals; + + +static const char *SYNTAX = "mongo_find_one ns; query; fields"; + +SWITCH_STANDARD_API(mongo_find_one_function) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + char *ns = NULL, *json_query = NULL, *json_fields = NULL; + char delim = ';'; + + ns = strdup(cmd); + switch_assert(ns != NULL); + + if ((json_query = strchr(ns, delim))) { + *json_query++ = '\0'; + if ((json_fields = strchr(json_query, delim))) { + *json_fields++ = '\0'; + } + } + + if (!zstr(ns) && !zstr(json_query) && !zstr(json_fields)) { + + DBClientConnection *conn = NULL; + + try { + BSONObj query = fromjson(json_query); + BSONObj fields = fromjson(json_fields); + + conn = mongo_connection_pool_get(globals.conn_pool); + if (conn) { + BSONObj res = conn->findOne(ns, Query(query), &fields); + mongo_connection_pool_put(globals.conn_pool, conn); + + stream->write_function(stream, "-OK\n%s\n", res.toString().c_str()); + } else { + stream->write_function(stream, "-ERR\nNo connection\n"); + } + } catch (DBException &e) { + if (conn) { + mongo_connection_destroy(&conn); + } + stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str()); + } + + + } else { + stream->write_function(stream, "-ERR\n%s\n", SYNTAX); + } + + switch_safe_free(ns); + + return status; +} + +static switch_status_t config(void) +{ + const char *cf = "mongo.conf"; + switch_xml_t cfg, xml, settings, param; + switch_status_t status = SWITCH_STATUS_SUCCESS; + const char *host = "127.0.0.1"; + switch_size_t min_connections = 1, max_connections = 1; + + if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); + return SWITCH_STATUS_GENERR; + } + + if ((settings = switch_xml_child(cfg, "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"); + int tmp; + + if (!strcmp(var, "host")) { + host = val; + } else if (!strcmp(var, "min-connections")) { + if ((tmp = atoi(val)) > 0) { + min_connections = tmp; + } + } else if (!strcmp(var, "max-connections")) { + if ((tmp = atoi(val)) > 0) { + max_connections = tmp; + } + } + } + } + + if (mongo_connection_pool_create(&globals.conn_pool, min_connections, max_connections, host) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Can't create connection pool\n"); + status = SWITCH_STATUS_GENERR; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Mongo connection pool created [%s %d/%d]\n", host, (int)min_connections, (int)max_connections); + } + + switch_xml_free(xml); + + return status; +} + + +SWITCH_BEGIN_EXTERN_C + +SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown); +SWITCH_MODULE_DEFINITION(mod_mongo, mod_mongo_load, mod_mongo_shutdown, NULL); + + +SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load) +{ + switch_api_interface_t *api_interface; + switch_application_interface_t *app_interface; + + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + memset(&globals, 0, sizeof(globals)); + + if (config() != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_TERM; + } + + SWITCH_ADD_API(api_interface, "mongo_find_one", "mongo", mongo_find_one_function, SYNTAX); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown) +{ + mongo_connection_pool_destroy(&globals.conn_pool); + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_END_EXTERN_C + +/* 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/applications/mod_mongo/mod_mongo.h b/src/mod/applications/mod_mongo/mod_mongo.h new file mode 100644 index 0000000000..91c14bb29b --- /dev/null +++ b/src/mod/applications/mod_mongo/mod_mongo.h @@ -0,0 +1,38 @@ +#ifndef MOD_MONGO_H +#define MOD_MONGO_H + + +#include +#include +#include +#include + +using namespace mongo; + +typedef struct { + char *host; + + switch_size_t min_connections; + switch_size_t max_connections; + switch_size_t size; + switch_queue_t *connections; + switch_mutex_t *mutex; + switch_memory_pool_t *pool; + +} mongo_connection_pool_t; + + +switch_status_t mongo_connection_create(DBClientConnection **connection, const char *host); +void mongo_connection_destroy(DBClientConnection **conn); + +switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections, + const char *host); +void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool); + + +DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool); +switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientConnection *conn); + + +#endif + diff --git a/src/mod/applications/mod_mongo/mongo_conn.cpp b/src/mod/applications/mod_mongo/mongo_conn.cpp new file mode 100644 index 0000000000..ee702b8470 --- /dev/null +++ b/src/mod/applications/mod_mongo/mongo_conn.cpp @@ -0,0 +1,161 @@ +#include +#include "mod_mongo.h" + + /* + we could use the driver's connection pool, + if we could set the max connections (PoolForHost::setMaxPerHost) + + ScopedDbConnection scoped_conn("host"); + DBClientConnection *conn = dynamic_cast< DBClientConnection* >(&scoped_conn.conn()); + scoped_conn.done(); + */ + +switch_status_t mongo_connection_create(DBClientConnection **connection, const char *host) +{ + DBClientConnection *conn = new DBClientConnection(); + + try { + conn->connect(host); + } catch (DBException &e) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]\n", host); + return SWITCH_STATUS_GENERR; + } + + *connection = conn; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", host); + + return SWITCH_STATUS_SUCCESS; +} + +void mongo_connection_destroy(DBClientConnection **conn) +{ + switch_assert(*conn != NULL); + delete *conn; + + *conn = NULL; +} + +switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections, + const char *host) +{ + switch_memory_pool_t *pool = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + mongo_connection_pool_t *cpool = NULL; + DBClientConnection *conn = NULL; + + if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) { + return status; + } + + if (!(cpool = (mongo_connection_pool_t *)switch_core_alloc(pool, sizeof(mongo_connection_pool_t)))) { + switch_goto_status(SWITCH_STATUS_MEMERR, done); + } + + if ((status = switch_mutex_init(&cpool->mutex, SWITCH_MUTEX_NESTED, pool)) != SWITCH_STATUS_SUCCESS) { + goto done; + } + + if ((status = switch_queue_create(&cpool->connections, max_connections, pool)) != SWITCH_STATUS_SUCCESS) { + goto done; + } + + cpool->min_connections = min_connections; + cpool->max_connections = max_connections; + cpool->host = switch_core_strdup(pool, host); + + cpool->pool = pool; + + for (cpool->size = 0; cpool->size < min_connections; cpool->size++) { + + if (mongo_connection_create(&conn, host) == SWITCH_STATUS_SUCCESS) { + mongo_connection_pool_put(cpool, conn); + } else { + break; + } + } + + done: + + if (status == SWITCH_STATUS_SUCCESS) { + *conn_pool = cpool; + } else { + switch_core_destroy_memory_pool(&pool); + } + + + return status; +} + +void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool) +{ + mongo_connection_pool_t *cpool = *conn_pool; + void *data = NULL; + + switch_assert(cpool != NULL); + + while (switch_queue_trypop(cpool->connections, &data) == SWITCH_STATUS_SUCCESS) { + mongo_connection_destroy((DBClientConnection **)&data); + } + + switch_mutex_destroy(cpool->mutex); + switch_core_destroy_memory_pool(&cpool->pool); + + *conn_pool = NULL; +} + + +DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool) +{ + DBClientConnection *conn = NULL; + void *data = NULL; + + switch_assert(conn_pool != NULL); + + switch_mutex_lock(conn_pool->mutex); + + if (switch_queue_trypop(conn_pool->connections, &data) == SWITCH_STATUS_SUCCESS) { + conn = (DBClientConnection *) data; + } else if (mongo_connection_create(&conn, conn_pool->host) == SWITCH_STATUS_SUCCESS) { + if (++conn_pool->size > conn_pool->max_connections) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Connection pool is empty. You may want to increase 'max-connections'\n"); + } + } + + switch_mutex_unlock(conn_pool->mutex); + +#ifdef MONGO_POOL_DEBUG + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL get: size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn); +#endif + + return conn; +} + +switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientConnection *conn) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_assert(conn_pool != NULL); + switch_assert(conn != NULL); + + switch_mutex_lock(conn_pool->mutex); + if (conn_pool->size > conn_pool->max_connections) { +#ifdef MONGO_POOL_DEBUG + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: Destroy connection %p\n", conn); +#endif + mongo_connection_destroy(&conn); + conn_pool->size--; + } else { +#ifdef MONGO_POOL_DEBUG + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: push connection %p\n", conn); +#endif + status = switch_queue_push(conn_pool->connections, conn); + } + + switch_mutex_unlock(conn_pool->mutex); + +#ifdef MONGO_POOL_DEBUG + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: put size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn); +#endif + + return status; +} diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index 8487d0be62..2cd772ece0 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -399,7 +399,7 @@ static switch_status_t do_billing(switch_core_session_t *session) const char *billrate; const char *billaccount; float nobal_amt = globals.nobal_amt; - float lowbal_amt = globals.lowbal_amt; + //float lowbal_amt = globals.lowbal_amt; float balance; if (!session) { @@ -421,10 +421,11 @@ static switch_status_t do_billing(switch_core_session_t *session) if (!zstr(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 = (float)atof(switch_channel_get_variable(channel, "lowbal_amt")); } - + */ /* Return if there's no billing information on this session */ if (!billrate || !billaccount) { return SWITCH_STATUS_SUCCESS; @@ -802,9 +803,6 @@ SWITCH_STANDARD_API(nibblebill_api_function) if ((argc == 2 || argc == 3) && !zstr(argv[0])) { char *uuid = argv[0]; if ((psession = switch_core_session_locate(uuid))) { - switch_channel_t *channel; - channel = switch_core_session_get_channel(psession); - if (!strcasecmp(argv[1], "adjust") && argc == 3) { nibblebill_adjust(psession, (float) atof(argv[2])); } else if (!strcasecmp(argv[1], "flush")) { @@ -904,7 +902,7 @@ switch_state_handler_table_t nibble_state_handler = { /* on_hibernate */ NULL, /* on_reset */ NULL, /* on_park */ NULL, - /* on_reporting */ process_hangup, /* force billing event on b-leg if we can */ + /* on_reporting */ NULL, /* on_destroy */ NULL }; diff --git a/src/mod/applications/mod_protovm/Makefile b/src/mod/applications/mod_protovm/Makefile new file mode 100644 index 0000000000..92f8441104 --- /dev/null +++ b/src/mod/applications/mod_protovm/Makefile @@ -0,0 +1,3 @@ +BASE=../../../.. +LOCAL_OBJS=ivr.o util.o config.o menu.o +include $(BASE)/build/modmake.rules diff --git a/src/mod/applications/mod_protovm/config.c b/src/mod/applications/mod_protovm/config.c new file mode 100644 index 0000000000..feec69b79e --- /dev/null +++ b/src/mod/applications/mod_protovm/config.c @@ -0,0 +1,130 @@ +/* Copy paste from FS mod_voicemail */ +#include + +#include "config.h" + +const char *global_cf = "protovm.conf"; + +void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu) { + switch_xml_t cfg, xml, x_profiles, x_profile, x_keys, x_phrases, x_menus, x_menu; + + free_profile_menu_event(menu); + + if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); + goto end; + } + if (!(x_profiles = switch_xml_child(cfg, "profiles"))) { + goto end; + } + + if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile->name))) { + if ((x_menus = switch_xml_child(x_profile, "menus"))) { + if ((x_menu = switch_xml_find_child(x_menus, "menu", "name", menu->name))) { + if ((x_keys = switch_xml_child(x_menu, "keys"))) { + switch_event_import_xml(switch_xml_child(x_keys, "key"), "dtmf", "action", &menu->event_keys_dtmf); + switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "dtmf", &menu->event_keys_action); + switch_event_import_xml(switch_xml_child(x_keys, "key"), "action", "variable", &menu->event_keys_varname); + } + if ((x_phrases = switch_xml_child(x_menu, "phrases"))) { + switch_event_import_xml(switch_xml_child(x_phrases, "phrase"), "name", "value", &menu->event_phrases); + } + } + } + } +end: + if (xml) + switch_xml_free(xml); + return; + +} + +void free_profile_menu_event(vmivr_menu_profile_t *menu) { + if (menu->event_keys_dtmf) { + switch_event_destroy(&menu->event_keys_dtmf); + } + if (menu->event_keys_action) { + switch_event_destroy(&menu->event_keys_action); + } + if (menu->event_keys_varname) { + switch_event_destroy(&menu->event_keys_varname); + } + + if (menu->event_phrases) { + switch_event_destroy(&menu->event_phrases); + } +} + +vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name) +{ + vmivr_profile_t *profile = NULL; + switch_xml_t cfg, xml, x_profiles, x_profile, x_apis, param; + + if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); + return profile; + } + if (!(x_profiles = switch_xml_child(cfg, "profiles"))) { + goto end; + } + + if ((x_profile = switch_xml_find_child(x_profiles, "profile", "name", profile_name))) { + if (!(profile = switch_core_session_alloc(session, sizeof(vmivr_profile_t)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n"); + goto end; + } + + profile->name = profile_name; + + /* TODO Make the following configurable */ + profile->api_profile = profile->name; + profile->menu_check_auth = "std_authenticate"; + profile->menu_check_main = "std_navigator"; + profile->menu_check_terminate = "std_purge"; + + if ((x_apis = switch_xml_child(x_profile, "apis"))) { + int total_options = 0; + int total_invalid_options = 0; + for (param = switch_xml_child(x_apis, "api"); param; param = param->next) { + char *var, *val; + if ((var = (char *) switch_xml_attr_soft(param, "name")) && (val = (char *) switch_xml_attr_soft(param, "value"))) { + if (!strcasecmp(var, "msg_undelete") && !profile->api_msg_undelete) + profile->api_msg_undelete = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "msg_delete") && !profile->api_msg_delete) + profile->api_msg_delete = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "msg_list") && !profile->api_msg_list) + profile->api_msg_list = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "msg_count") && !profile->api_msg_count) + profile->api_msg_count = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "msg_save") && !profile->api_msg_save) + profile->api_msg_save = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "msg_purge") && !profile->api_msg_purge) + profile->api_msg_purge = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "msg_get") && !profile->api_msg_get) + profile->api_msg_get = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "pref_greeting_set") && !profile->api_pref_greeting_set) + profile->api_pref_greeting_set = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "pref_recname_set") && !profile->api_pref_recname_set) + profile->api_pref_recname_set = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "pref_password_set") && !profile->api_pref_password_set) + profile->api_pref_password_set = switch_core_session_strdup(session, val); + else if (!strcasecmp(var, "auth_login") && !profile->api_auth_login) + profile->api_auth_login = switch_core_session_strdup(session, val); + else + total_invalid_options++; + total_options++; + } + } + if (total_options - total_invalid_options != 11) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing api definition for profile '%s'\n", profile_name); + profile = NULL; + } + } + + } + +end: + switch_xml_free(xml); + return profile; +} + diff --git a/src/mod/applications/mod_protovm/config.h b/src/mod/applications/mod_protovm/config.h new file mode 100644 index 0000000000..04713fb7ae --- /dev/null +++ b/src/mod/applications/mod_protovm/config.h @@ -0,0 +1,49 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +extern const char *global_cf; + +struct vmivr_profile { + const char *name; + + const char *domain; + const char *id; + + const char *menu_check_auth; + const char *menu_check_main; + const char *menu_check_terminate; + + switch_bool_t authorized; + + const char *api_profile; + const char *api_auth_login; + const char *api_msg_delete; + const char *api_msg_undelete; + const char *api_msg_list; + const char *api_msg_count; + const char *api_msg_save; + const char *api_msg_purge; + const char *api_msg_get; + const char *api_pref_greeting_set; + const char *api_pref_recname_set; + const char *api_pref_password_set; + +}; +typedef struct vmivr_profile vmivr_profile_t; + +struct vmivr_menu_profile { + const char *name; + + switch_event_t *event_keys_action; + switch_event_t *event_keys_dtmf; + switch_event_t *event_keys_varname; + switch_event_t *event_phrases; +}; +typedef struct vmivr_menu_profile vmivr_menu_profile_t; + +vmivr_profile_t *get_profile(switch_core_session_t *session, const char *profile_name); + +void free_profile_menu_event(vmivr_menu_profile_t *menu); +void populate_profile_menu_event(vmivr_profile_t *profile, vmivr_menu_profile_t *menu); + +#endif /* _CONFIG_H_ */ diff --git a/src/mod/applications/mod_protovm/ivr.c b/src/mod/applications/mod_protovm/ivr.c new file mode 100644 index 0000000000..4b1f6ef0cc --- /dev/null +++ b/src/mod/applications/mod_protovm/ivr.c @@ -0,0 +1,249 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, 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 / Soft-Switch Application + * + * 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): + * + * Marc Olivier Chouinard + * + * + * ivr.c -- MT IVR System Interface + * + */ + +#include + +#include "ivr.h" + +int match_dtmf(switch_core_session_t *session, dtmf_ss_t *loc) { + switch_bool_t is_invalid[128] = { SWITCH_FALSE }; + int i; + loc->potentialMatch = NULL; + loc->completeMatch = NULL; + loc->potentialMatchCount = 0; + + for (i = 0; i < loc->dtmf_received; i++) { + int j; + loc->potentialMatchCount = 0; + for (j = 0; !zstr(loc->dtmf_accepted[j]) && j < 128; j++) { + switch_bool_t cMatch = SWITCH_FALSE; + char test[2] = { 0 }; + + if (is_invalid[j]) + continue; + + test[0] = loc->dtmf_stored[i]; + if (loc->dtmf_accepted[j][i] == 'N' && atoi(test) >= 2 && atoi(test) <= 9) + cMatch = SWITCH_TRUE; + if (loc->dtmf_accepted[j][i] == 'X' && atoi(test) >= 0 && atoi(test) <= 9) { + cMatch = SWITCH_TRUE; + } + if (i >= strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.') + cMatch = SWITCH_TRUE; + if (loc->dtmf_accepted[j][i] == loc->dtmf_stored[i]) + cMatch = SWITCH_TRUE; + + if (cMatch == SWITCH_FALSE) { + is_invalid[j] = SWITCH_TRUE; + continue; + } + + if (i == strlen(loc->dtmf_accepted[j]) - 1 && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] == '.') { + loc->completeMatch = loc->dtmf_accepted[j]; + } + if (i == loc->dtmf_received - 1 && loc->dtmf_received == strlen(loc->dtmf_accepted[j]) && loc->dtmf_accepted[j][strlen(loc->dtmf_accepted[j])-1] != '.') { + loc->completeMatch = loc->dtmf_accepted[j]; + continue; + } + loc->potentialMatchCount++; + } + } + + return 1; +} + +static switch_status_t cb_on_dtmf_ignore(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) +{ + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + switch_channel_queue_dtmf(channel, dtmf); + return SWITCH_STATUS_BREAK; + } + default: + break; + } + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t cb_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) +{ + dtmf_ss_t *loc = (dtmf_ss_t*) buf; + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + switch_bool_t audio_was_stopped = loc->audio_stopped; + loc->audio_stopped = SWITCH_TRUE; + + if (loc->dtmf_received >= sizeof(loc->dtmf_stored)) { + loc->result = RES_BUFFER_OVERFLOW; + break; + } + if (!loc->terminate_key || dtmf->digit != loc->terminate_key) + loc->dtmf_stored[loc->dtmf_received++] = dtmf->digit; + + match_dtmf(session, loc); + + if (loc->terminate_key && dtmf->digit == loc->terminate_key && loc->result == RES_WAITFORMORE) { + if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) { + loc->result = RES_FOUND; + } else { + loc->result = RES_INVALID; + } + return SWITCH_STATUS_BREAK; + } else { + if (loc->potentialMatchCount == 0 && loc->completeMatch != NULL) { + loc->result = RES_FOUND; + return SWITCH_STATUS_BREAK; + } else if (loc->potentialMatchCount > 0) { + loc->result = RES_WAITFORMORE; + if (!audio_was_stopped) + return SWITCH_STATUS_BREAK; + } else { + loc->result = RES_INVALID; + return SWITCH_STATUS_BREAK; + } + } + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted) { + int i; + + memset(loc, 0, sizeof(*loc)); + + for (i = 0; dtmf_accepted[i] && i < 16; i++) { + strncpy(loc->dtmf_accepted[i], dtmf_accepted[i], 128); + } + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_channel_t *channel = switch_core_session_get_channel(session); + + if (switch_channel_ready(channel)) { + switch_input_args_t args = { 0 }; + + args.input_callback = cb_on_dtmf_ignore; + + if (macro_name) { + status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args); + } + } else { + status = SWITCH_STATUS_BREAK; + } + + return status; +} + + +switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_channel_t *channel = switch_core_session_get_channel(session); + + if (switch_channel_ready(channel)) { + switch_input_args_t args = { 0 }; + + args.input_callback = cb_on_dtmf; + args.buf = loc; + + if (macro_name && loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) { + status = switch_ivr_phrase_macro_event(session, macro_name, data, event, lang, &args); + } + + if (switch_channel_ready(channel) && (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) && timeout && loc->result == RES_WAITFORMORE) { + loc->audio_stopped = SWITCH_TRUE; + switch_ivr_collect_digits_callback(session, &args, timeout, 0); + if (loc->result == RES_WAITFORMORE) { + if (loc->potentialMatchCount == 1 && loc->completeMatch != NULL) { + loc->result = RES_FOUND; + } else { + loc->result = RES_TIMEOUT; + } + } + } + } else { + status = SWITCH_STATUS_BREAK; + } + + return status; +} + +switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_channel_t *channel = switch_core_session_get_channel(session); + + if (switch_channel_ready(channel)) { + switch_input_args_t args = { 0 }; + + args.input_callback = cb_on_dtmf; + args.buf = loc; + + if (loc->audio_stopped == SWITCH_FALSE && loc->result == RES_WAITFORMORE) { + loc->recorded_audio = SWITCH_TRUE; + status = switch_ivr_record_file(session, fh, file_path, &args, max_record_len); + + } + if (loc->result == RES_WAITFORMORE) { + loc->result = RES_TIMEOUT; + } + + } else { + status = SWITCH_STATUS_BREAK; + } + + return status; +} + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 + */ diff --git a/src/mod/applications/mod_protovm/ivr.h b/src/mod/applications/mod_protovm/ivr.h new file mode 100644 index 0000000000..99136475fd --- /dev/null +++ b/src/mod/applications/mod_protovm/ivr.h @@ -0,0 +1,30 @@ +struct dtmf_ss { + char dtmf_stored[128]; + int dtmf_received; + char dtmf_accepted[16][128]; + int result; + switch_bool_t audio_stopped; + switch_bool_t recorded_audio; + const char *potentialMatch; + int potentialMatchCount; + const char *completeMatch; + char terminate_key; +}; +typedef struct dtmf_ss dtmf_ss_t; + +#define RES_WAITFORMORE 0 +#define RES_FOUND 1 +#define RES_INVALID 3 +#define RES_TIMEOUT 4 +#define RES_BREAK 5 +#define RES_RECORD 6 +#define RES_BUFFER_OVERFLOW 99 + +#define MAX_DTMF_SIZE_OPTION 32 + +switch_status_t captureMenu(switch_core_session_t *session, dtmf_ss_t *loc, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout); +switch_status_t captureMenuRecord(switch_core_session_t *session, dtmf_ss_t *loc, switch_event_t *event, const char *file_path, switch_file_handle_t *fh, int max_record_len); +switch_status_t captureMenuInitialize(dtmf_ss_t *loc, char **dtmf_accepted); + +switch_status_t playbackBufferDTMF(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, int timeout); + diff --git a/src/mod/applications/mod_protovm/menu.c b/src/mod/applications/mod_protovm/menu.c new file mode 100644 index 0000000000..4dc3e19e78 --- /dev/null +++ b/src/mod/applications/mod_protovm/menu.c @@ -0,0 +1,599 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, 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 / Soft-Switch Application + * + * 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): + * + * Marc Olivier Chouinard + * + * + * menu.c -- VoiceMail Menu + * + */ +#include + +#include "ivr.h" +#include "menu.h" +#include "util.h" +#include "config.h" + +/* List of available menu */ +vmivr_menu_function_t menu_list[] = { + {"std_authenticate", mtvm_menu_authenticate}, + {"std_navigator", mtvm_menu_main}, + {"std_record_name", mtvm_menu_record_name}, + {"std_set_password", mtvm_menu_set_password}, + {"std_select_greeting_slot", mtvm_menu_select_greeting_slot}, + {"std_record_greeting_with_slot", mtvm_menu_record_greeting_with_slot}, + {"std_preference", mtvm_menu_preference}, + {"std_purge", mtvm_menu_purge}, + { NULL, NULL } +}; + +#define MAX_ATTEMPT 3 /* TODO Make these fields configurable */ +#define DEFAULT_IVR_TIMEOUT 3000 + +void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile) { + if (profile->id && profile->authorized) { + if (1==1 /* TODO make Purge email on exit optional ??? */) { + const char *cmd = switch_core_session_sprintf(session, "%s %s %s", profile->api_profile, profile->domain, profile->id); + mt_api_execute(session, profile->api_msg_purge, cmd); + } + } +} +void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile) { + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_event_t *msg_list_params = NULL; + size_t msg_count = 0; + size_t current_msg = 1; + size_t next_msg = current_msg; + size_t previous_msg = current_msg; + char *cmd = NULL; + int retry; + + /* Different switch to control playback of phrases */ + switch_bool_t initial_count_played = SWITCH_FALSE; + switch_bool_t skip_header = SWITCH_FALSE; + switch_bool_t msg_deleted = SWITCH_FALSE; + switch_bool_t msg_undeleted = SWITCH_FALSE; + switch_bool_t msg_saved = SWITCH_FALSE; + + vmivr_menu_profile_t menu = { "std_navigator" }; + + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &menu); + + if (!menu.event_keys_dtmf || !menu.event_phrases) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); + return; + } + + /* Get VoiceMail List And update msg count */ + cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id); + msg_list_params = jsonapi2event(session, NULL, profile->api_msg_list, cmd); + msg_count = atol(switch_event_get_header(msg_list_params,"VM-List-Count")); + + /* TODO Add Detection of new message and notify the user */ + + for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { + dtmf_ss_t loc; + char *dtmfa[16] = { 0 }; + switch_event_t *phrase_params = NULL; + + switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); + + append_event_profile(phrase_params, profile, menu); + + populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); + + previous_msg = current_msg; + + /* Simple Protection to not go out of msg list scope */ + /* TODO: Add Prompt to notify they reached the begining or the end */ + if (next_msg == 0) { + next_msg = 1; + } else if (next_msg > msg_count) { + next_msg = msg_count; + } + + current_msg = next_msg; + + captureMenuInitialize(&loc, dtmfa); + + /* Prompt related to previous Message here */ + append_event_message(session, profile, phrase_params, msg_list_params, previous_msg); + if (msg_deleted) { + msg_deleted = SWITCH_FALSE; + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "deleted", phrase_params, NULL, 0); + } + if (msg_undeleted) { + msg_undeleted = SWITCH_FALSE; + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "undeleted", phrase_params, NULL, 0); + } + if (msg_saved) { + msg_saved = SWITCH_FALSE; + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "ack"), "saved", phrase_params, NULL, 0); + } + + /* Prompt related the current message */ + append_event_message(session, profile, phrase_params, msg_list_params, current_msg); + + /* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */ + if (!skip_header) { + if (!initial_count_played) { + cmd = switch_core_session_sprintf(session, "json %s %s %s", profile->api_profile, profile->domain, profile->id); + jsonapi2event(session, phrase_params, profile->api_msg_count, cmd); + initial_count_played = SWITCH_TRUE; + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "msg_count"), NULL, phrase_params, NULL, 0); + } + if (msg_count > 0) { + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_msg_number"), NULL, phrase_params, NULL, 0); + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "say_date"), NULL, phrase_params, NULL, 0); + } + } + if (msg_count > 0) { + /* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */ + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_message"), NULL, phrase_params, NULL, 0); + } + skip_header = SWITCH_FALSE; + + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); + + if (loc.result == RES_TIMEOUT) { + /* TODO Ask for the prompt Again IF retry != 0 */ + } else if (loc.result == RES_INVALID) { + /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ + const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); + + /* Reset the try count */ + retry = MAX_ATTEMPT; + + if (action) { + if (!strcasecmp(action, "skip_intro")) { /* Skip Header / Play the recording again */ + skip_header = SWITCH_TRUE; + } else if (!strcasecmp(action, "next_msg")) { /* Next Message */ + next_msg++; + } else if (!strcasecmp(action, "prev_msg")) { /* Previous Message */ + next_msg--; + } else if (!strcasecmp(action, "delete_msg")) { /* Delete / Undelete Message */ + if (strncasecmp(switch_event_get_header(phrase_params, "VM-Message-Flags"), "delete", 6)) { + cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); + mt_api_execute(session, profile->api_msg_delete, cmd); + + msg_deleted = SWITCH_TRUE; + /* TODO Option for auto going to next message or just return to the menu (So user used to do 76 to delete and next message wont be confused) */ + next_msg++; + } else { + cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); + mt_api_execute(session, profile->api_msg_undelete, cmd); + + msg_undeleted = SWITCH_TRUE; + } + } else if (!strcasecmp(action, "save_msg")) { /* Save Message */ + cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(phrase_params, "VM-Message-UUID")); + mt_api_execute(session, profile->api_msg_save, cmd); + + msg_saved = SWITCH_TRUE; + } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ + void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5); + if (fPtr) { + fPtr(session, profile); + } + } else if (!strcasecmp(action, "return")) { /* Return */ + retry = -1; + } + } + } + + /* IF the API to get the message returned us a COPY of the file locally (temp file create from a DB or from a web server), delete it */ + if (switch_true(switch_event_get_header(phrase_params, "VM-Message-Private-Local-Copy"))) { + const char *file_path = switch_event_get_header(phrase_params, "VM-Message-File-Path"); + if (file_path && unlink(file_path) != 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete temp file [%s]\n", file_path); + } + } + switch_event_destroy(&phrase_params); + } + + switch_event_destroy(&msg_list_params); + + free_profile_menu_event(&menu); + + return; +} + +void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile) { + switch_status_t status; + vmivr_menu_profile_t menu = { "std_record_name" }; + + char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */); + + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &menu); + + status = mtvm_menu_record(session, profile, menu, tmp_filepath); + + if (status == SWITCH_STATUS_SUCCESS) { + char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, tmp_filepath); + mt_api_execute(session, profile->api_pref_recname_set, cmd); + } +} + +void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile) { + char *password; + vmivr_menu_profile_t menu = { "std_set_password" }; + + password = mtvm_menu_get_input_set(session, profile, menu, "XXX." /* TODO Conf Min 3 Digit */, "#" /* TODO Conf terminate input key */); + + /* TODO Add Prompts to tell if password was set and if it was not */ + if (password) { + char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, profile->id, password); + mt_api_execute(session, profile->api_pref_password_set, cmd); + } + + free_profile_menu_event(&menu); +} + +void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile) { + switch_channel_t *channel = switch_core_session_get_channel(session); + vmivr_menu_profile_t menu = { "std_authenticate" }; + int retry; + const char *auth_var = NULL; + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &menu); + + if (profile->id && (auth_var = switch_channel_get_variable(channel, "voicemail_authorized")) && switch_true(auth_var)) { + profile->authorized = SWITCH_TRUE; + } + + for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0 && profile->authorized == SWITCH_FALSE; retry--) { + const char *id = profile->id, *password = NULL; + char *cmd = NULL; + + if (!id) { + vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_user" }; + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &sub_menu); + + id = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */, "#" /* TODO Conf terminate input key */); + free_profile_menu_event(&sub_menu); + } + if (!password) { + vmivr_menu_profile_t sub_menu = { "std_authenticate_ask_password" }; + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &sub_menu); + + password = mtvm_menu_get_input_set(session, profile, sub_menu, "X." /* TODO Conf Min 3 Digit */, "#" /* TODO Conf terminate input key */); + free_profile_menu_event(&sub_menu); + } + cmd = switch_core_session_sprintf(session, "%s %s %s %s", profile->api_profile, profile->domain, id, password); + + if (mt_api_execute(session, profile->api_auth_login, cmd) == SWITCH_STATUS_SUCCESS) { + profile->id = id; + profile->authorized = SWITCH_TRUE; + } else { + playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "fail_auth"), NULL, NULL, NULL, 0); + } + } + free_profile_menu_event(&menu); +} + + +void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile) { + vmivr_menu_profile_t menu = { "std_select_greeting_slot" }; + + const char *result; + int gnum = -1; + + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &menu); + + result = mtvm_menu_get_input_set(session, profile, menu, "X", NULL); + + if (result) + gnum = atoi(result); + if (gnum != -1) { + char * cmd = switch_core_session_sprintf(session, "%s %s %s %d", profile->api_profile, profile->domain, profile->id, gnum); + if (mt_api_execute(session, profile->api_pref_greeting_set, cmd) == SWITCH_STATUS_SUCCESS) { + char *str_num = switch_core_session_sprintf(session, "%d", gnum); + playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); + } else { + playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "invalid_slot"), NULL, NULL, NULL, 0); + } + } + free_profile_menu_event(&menu); +} + +void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile) { + + vmivr_menu_profile_t menu = { "std_record_greeting_with_slot" }; + + const char *result; + int gnum = -1; + + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &menu); + + result = mtvm_menu_get_input_set(session, profile, menu, "X", NULL); + + if (result) + gnum = atoi(result); + + /* If user entered 0, we don't accept it */ + if (gnum > 0) { + vmivr_menu_profile_t sub_menu = { "std_record_greeting" }; + char *tmp_filepath = generate_random_file_name(session, "protovm", "wav" /* TODO make it configurable */); + switch_status_t status; + + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &sub_menu); + + status = mtvm_menu_record(session, profile, sub_menu, tmp_filepath); + + if (status == SWITCH_STATUS_SUCCESS) { + char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath); + char *str_num = switch_core_session_sprintf(session, "%d", gnum); + mt_api_execute(session, profile->api_pref_greeting_set, cmd); + playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0); + } + free_profile_menu_event(&sub_menu); + + } + + free_profile_menu_event(&menu); + +} + +void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile) { + switch_channel_t *channel = switch_core_session_get_channel(session); + + int retry; + + vmivr_menu_profile_t menu = { "std_preference" }; + + /* Initialize Menu Configs */ + populate_profile_menu_event(profile, &menu); + + if (!menu.event_keys_dtmf || !menu.event_phrases) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); + return; + } + + for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { + dtmf_ss_t loc; + char *dtmfa[16] = { 0 }; + switch_event_t *phrase_params = NULL; + + switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); + append_event_profile(phrase_params, profile, menu); + + populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); + + captureMenuInitialize(&loc, dtmfa); + + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); + + if (loc.result == RES_TIMEOUT) { + /* TODO Ask for the prompt Again IF retry != 0 */ + } else if (loc.result == RES_INVALID) { + /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ + const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); + + /* Reset the try count */ + retry = MAX_ATTEMPT; + + if (action) { + if (!strcasecmp(action, "return")) { /* Return to the previous menu */ + retry = -1; + } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ + void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5); + if (fPtr) { + fPtr(session, profile); + } + } + } + } + switch_event_destroy(&phrase_params); + } + + free_profile_menu_event(&menu); +} + +char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask, const char *terminate_key) { + char *result = NULL; + int retry; + + switch_channel_t *channel = switch_core_session_get_channel(session); + + if (!menu.event_keys_dtmf || !menu.event_phrases) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys : %s\n", menu.name); + return result; + } + + for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { + dtmf_ss_t loc; + char *dtmfa[16] = { 0 }; + int i; + switch_event_t *phrase_params = NULL; + + switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); + append_event_profile(phrase_params, profile, menu); + + populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); + + /* Find the last entry and append this one to it */ + for (i=0; dtmfa[i] && i < 16; i++){ + } + dtmfa[i] = (char *) input_mask; + + captureMenuInitialize(&loc, dtmfa); + if (terminate_key) + loc.terminate_key = terminate_key[0]; /* TODO Make this load from the configuration */ + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); + + if (loc.result == RES_TIMEOUT) { + /* TODO Ask for the prompt Again IF retry != 0 */ + } else if (loc.result == RES_INVALID) { + /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ + + /* Reset the try count */ + retry = MAX_ATTEMPT; + + if (!strncasecmp(loc.completeMatch, input_mask, 1)) { + result = switch_core_session_strdup(session, loc.dtmf_stored); + retry = -1; + + } + } + switch_event_destroy(&phrase_params); + } + + return result; +} + +switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name) { + switch_status_t status = SWITCH_STATUS_FALSE; + switch_channel_t *channel = switch_core_session_get_channel(session); + int retry; + + switch_bool_t record_prompt = SWITCH_TRUE; + switch_bool_t listen_recording = SWITCH_FALSE; + switch_bool_t play_instruction = SWITCH_TRUE; + + if (!menu.event_keys_dtmf || !menu.event_phrases) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Menu Phrases and Keys\n"); + return status; + } + + for (retry = MAX_ATTEMPT; switch_channel_ready(channel) && retry > 0; retry--) { + dtmf_ss_t loc; + + char *dtmfa[16] = { 0 }; + switch_event_t *phrase_params = NULL; + switch_file_handle_t fh = { 0 }; + + /* TODO Make the following configurable */ + fh.thresh = 200; + fh.silence_hits = 4; + //fh.samplerate = 8000; + + + switch_event_create(&phrase_params, SWITCH_EVENT_REQUEST_PARAMS); + append_event_profile(phrase_params, profile, menu); + + populate_dtmfa_from_event(phrase_params, profile, menu, dtmfa); + + captureMenuInitialize(&loc, dtmfa); + if (record_prompt) { + if (play_instruction) { + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "instructions"), NULL, phrase_params, NULL, 0); + } + play_instruction = SWITCH_TRUE; + + captureMenuRecord(session, &loc, phrase_params, file_name, &fh, 30 /* TODO Make max recording configurable */); + } else { + if (listen_recording) { + switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Record-File-Path", "%s", file_name); + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "play_recording"), NULL, phrase_params, NULL, 0); + listen_recording = SWITCH_FALSE; + + } + captureMenu(session, &loc, switch_event_get_header(menu.event_phrases, "menu_options"), NULL, phrase_params, NULL, DEFAULT_IVR_TIMEOUT); + } + + if (loc.recorded_audio) { + /* Reset the try count */ + retry = MAX_ATTEMPT; + + /* TODO Check if message is too short */ + + record_prompt = SWITCH_FALSE; + + } else if (loc.result == RES_TIMEOUT) { + /* TODO Ask for the prompt Again IF retry != 0 */ + } else if (loc.result == RES_INVALID) { + /* TODO Say invalid option, and ask for the prompt again IF retry != 0 */ + } else if (loc.result == RES_FOUND) { /* Matching DTMF Key Pressed */ + const char *action = switch_event_get_header(menu.event_keys_dtmf, loc.dtmf_stored); + + /* Reset the try count */ + retry = MAX_ATTEMPT; + + if (action) { + if (!strcasecmp(action, "listen")) { /* Listen */ + listen_recording = SWITCH_TRUE; + + } else if (!strcasecmp(action, "save")) { + retry = -1; + /* TODO ALLOW SAVE ONLY IF FILE IS RECORDED AND HIGHER THAN MIN SIZE */ + status = SWITCH_STATUS_SUCCESS; + + } else if (!strcasecmp(action, "rerecord")) { + record_prompt = SWITCH_TRUE; + + } else if (!strcasecmp(action, "skip_instruction")) { /* Skip Recording Greeting */ + play_instruction = SWITCH_FALSE; + + } else if (!strncasecmp(action, "menu:", 5)) { /* Sub Menu */ + void (*fPtr)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(action+5); + if (fPtr) { + fPtr(session, profile); + } + } else if (!strcasecmp(action, "return")) { /* Return */ + retry = -1; + } + } + } + switch_event_destroy(&phrase_params); + } + return status; +} + + +void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile) { + int i = 0; + + if (menu_name) { + for (i=0; menu_list[i].name ; i++) { + if (!strcasecmp(menu_list[i].name, menu_name)) { + return menu_list[i].pt2Func; + } + } + } + return NULL; +} + + + +/* 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/applications/mod_protovm/menu.h b/src/mod/applications/mod_protovm/menu.h new file mode 100644 index 0000000000..a2d8cb09f5 --- /dev/null +++ b/src/mod/applications/mod_protovm/menu.h @@ -0,0 +1,31 @@ +#ifndef _MENU_H_ +#define _MENU_H_ + +#include "config.h" + +void mtvm_menu_purge(switch_core_session_t *session, vmivr_profile_t *profile); +void mtvm_menu_authenticate(switch_core_session_t *session, vmivr_profile_t *profile); +void mtvm_menu_main(switch_core_session_t *session, vmivr_profile_t *profile); +void mtvm_menu_record_name(switch_core_session_t *session, vmivr_profile_t *profile); +void mtvm_menu_set_password(switch_core_session_t *session, vmivr_profile_t *profile); +void mtvm_menu_select_greeting_slot(switch_core_session_t *session, vmivr_profile_t *profile); +void mtvm_menu_record_greeting_with_slot(switch_core_session_t *session, vmivr_profile_t *profile); +void mtvm_menu_preference(switch_core_session_t *session, vmivr_profile_t *profile); + +switch_status_t mtvm_menu_record(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *file_name); +char *mtvm_menu_get_input_set(switch_core_session_t *session, vmivr_profile_t *profile, vmivr_menu_profile_t menu, const char *input_mask, const char *terminate_key); + + +struct vmivr_menu_function { + const char *name; + void (*pt2Func)(switch_core_session_t *session, vmivr_profile_t *profile); + +}; +typedef struct vmivr_menu_function vmivr_menu_function_t; + +extern vmivr_menu_function_t menu_list[]; + +void (*mtvm_get_menu_function(const char *menu_name))(switch_core_session_t *session, vmivr_profile_t *profile); + +#endif /* _MENU_H_ */ + diff --git a/src/mod/applications/mod_protovm/mod_protovm.c b/src/mod/applications/mod_protovm/mod_protovm.c new file mode 100644 index 0000000000..7d826e03c2 --- /dev/null +++ b/src/mod/applications/mod_protovm/mod_protovm.c @@ -0,0 +1,139 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, 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 / Soft-Switch Application + * + * 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): + * + * Marc Olivier Chouinard + * + * + * mod_protovm.c -- MT VoiceMail System + * + */ +#include + +#include "config.h" +#include "menu.h" + +/* Prototypes */ +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown); +SWITCH_MODULE_RUNTIME_FUNCTION(mod_protovm_runtime); +SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load); + +/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) + * Defines a switch_loadable_module_function_table_t and a static const char[] modname + */ +SWITCH_MODULE_DEFINITION(mod_protovm, mod_protovm_load, mod_protovm_shutdown, NULL); + + +#define MTVM_DESC "protovm" +#define MTVM_USAGE " profile domain [id]" + +SWITCH_STANDARD_APP(protovm_function) +{ + const char *id = NULL; + const char *domain = NULL; + const char *profile_name = NULL; + vmivr_profile_t *profile = NULL; + int argc = 0; + char *argv[6] = { 0 }; + char *mydata = NULL; + + if (!zstr(data)) { + mydata = switch_core_session_strdup(session, data); + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[1]) + profile_name = argv[1]; + + if (argv[2]) + domain = argv[2]; + + if (!strcasecmp(argv[0], "check")) { + if (argv[3]) + id = argv[3]; + + if (domain && profile_name) { + profile = get_profile(session, profile_name); + + if (profile) { + void (*fPtrAuth)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_auth); + void (*fPtrMain)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_main); + void (*fPtrTerminate)(switch_core_session_t *session, vmivr_profile_t *profile) = mtvm_get_menu_function(profile->menu_check_terminate); + + profile->domain = domain; + profile->id = id; + + if (fPtrAuth && !profile->authorized) { + fPtrAuth(session, profile); + } + + if (fPtrMain && profile->authorized) { + fPtrMain(session, profile); + } + if (fPtrTerminate) { + fPtrTerminate(session, profile); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile '%s' not found\n", profile_name); + } + } + } + return; +} + +/* Macro expands to: switch_status_t mod_protovm_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ +SWITCH_MODULE_LOAD_FUNCTION(mod_protovm_load) +{ + switch_application_interface_t *app_interface; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_APP(app_interface, "protovm", "protovm", MTVM_DESC, protovm_function, MTVM_USAGE, SAF_NONE); + + /* indicate that the module should continue to be loaded */ + return status; +} + +/* + Called when the system shuts down + Macro expands to: switch_status_t mod_protovm_shutdown() */ +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_protovm_shutdown) +{ + + 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/applications/mod_protovm/protovm.conf.xml b/src/mod/applications/mod_protovm/protovm.conf.xml new file mode 100644 index 0000000000..e25b8760c8 --- /dev/null +++ b/src/mod/applications/mod_protovm/protovm.conf.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/applications/mod_protovm/sounds.xml b/src/mod/applications/mod_protovm/sounds.xml new file mode 100644 index 0000000000..1760e7cc07 --- /dev/null +++ b/src/mod/applications/mod_protovm/sounds.xml @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/applications/mod_protovm/util.c b/src/mod/applications/mod_protovm/util.c new file mode 100644 index 0000000000..476e99bd26 --- /dev/null +++ b/src/mod/applications/mod_protovm/util.c @@ -0,0 +1,175 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, 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 / Soft-Switch Application + * + * 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): + * + * Marc Olivier Chouinard + * + * + * utils.c -- MT VoiceMail / Different utility that might need to go into the core (after cleanup) + * + */ +#include + +#include "util.h" + +switch_status_t mt_merge_media_files(const char** inputs, const char *output) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_file_handle_t fh_output = { 0 }; + int channels = 1; + int rate = 8000; /* TODO Make this configurable */ + int j = 0; + + if (switch_core_file_open(&fh_output, output, channels, rate, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", output); + goto end; + } + + for (j = 0; inputs[j] != NULL && j < 128 && status == SWITCH_STATUS_SUCCESS; j++) { + switch_file_handle_t fh_input = { 0 }; + char buf[2048]; + switch_size_t len = sizeof(buf) / 2; + + if (switch_core_file_open(&fh_input, inputs[j], channels, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open %s\n", inputs[j]); + status = SWITCH_STATUS_GENERR; + break; + } + + while (switch_core_file_read(&fh_input, buf, &len) == SWITCH_STATUS_SUCCESS) { + if (switch_core_file_write(&fh_output, buf, &len) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write error\n"); + status = SWITCH_STATUS_GENERR; + break; + } + } + + if (fh_input.file_interface) { + switch_core_file_close(&fh_input); + } + } + + if (fh_output.file_interface) { + switch_core_file_close(&fh_output); + } +end: + return status; +} + +switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data) { + switch_event_t *phrases_event = NULL; + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + switch_api_execute(api, data, session, &stream); + switch_event_create_json(&phrases_event, (char *) stream.data); + switch_safe_free(stream.data); + + if (apply_event) { + switch_event_header_t *hp; + for (hp = phrases_event->headers; hp; hp = hp->next) { + if (!strncasecmp(hp->name, "VM-", 3)) { + switch_event_add_header(apply_event, SWITCH_STACK_BOTTOM, hp->name, "%s", hp->value); + } + } + switch_event_destroy(&phrases_event); + phrases_event = apply_event; + + } + + return phrases_event; +} + +char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension) { + char rand_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = ""; + switch_uuid_t srand_uuid; + + switch_uuid_get(&srand_uuid); + switch_uuid_format(rand_uuid, &srand_uuid); + + return switch_core_session_sprintf(session, "%s%s%s_%s.%s", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, mod_name, rand_uuid, file_extension); + +} + +switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_stream_handle_t stream = { 0 }; + + SWITCH_STANDARD_STREAM(stream); + switch_api_execute(apiname, arguments, session, &stream); + if (!strncasecmp(stream.data, "-ERR", 4)) { + status = SWITCH_STATUS_GENERR; + } + switch_safe_free(stream.data); + return status; +} + +void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu) { + /* Used for some appending function */ + if (profile->name && profile->id && profile->domain) { + switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Profile", "%s", profile->name); + switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-ID", "%s", profile->id); + switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Account-Domain", "%s", profile->domain); + } +} + +void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa) { + int i = 0; + if (menu.event_keys_dtmf) { + switch_event_header_t *hp; + + for (hp = menu.event_keys_dtmf->headers; hp; hp = hp->next) { + if (strlen(hp->name) < 3 && hp->value) { /* TODO This is a hack to discard default FS Events ! */ + const char *varphrasename = switch_event_get_header(menu.event_keys_varname, hp->value); + dtmfa[i++] = hp->name; + + if (varphrasename && !zstr(varphrasename)) { + switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, varphrasename, "%s", hp->name); + } + } + } + } + +} + +void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg) { + + char *varname; + char *apicmd; + + varname = switch_mprintf("VM-List-Message-%" SWITCH_SIZE_T_FMT "-UUID", current_msg); + apicmd = switch_mprintf("json %s %s %s %s", profile->api_profile, profile->domain, profile->id, switch_event_get_header(msg_list_event, varname)); + + switch_safe_free(varname); + + jsonapi2event(session, phrase_params, profile->api_msg_get, apicmd); + + /* TODO Set these 2 header correctly */ + switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Type", "%s", "new"); + switch_event_add_header(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Number", "%"SWITCH_SIZE_T_FMT, current_msg); + + switch_event_add_header_string(phrase_params, SWITCH_STACK_BOTTOM, "VM-Message-Private-Local-Copy", "False"); + + switch_safe_free(apicmd); +} + diff --git a/src/mod/applications/mod_protovm/util.h b/src/mod/applications/mod_protovm/util.h new file mode 100644 index 0000000000..1c46329e18 --- /dev/null +++ b/src/mod/applications/mod_protovm/util.h @@ -0,0 +1,16 @@ +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#include "config.h" + +switch_status_t mt_merge_files(const char** inputs, const char *output); + +void append_event_message(switch_core_session_t *session, vmivr_profile_t *profile, switch_event_t *phrase_params, switch_event_t *msg_list_event, size_t current_msg); +void append_event_profile(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu); +char *generate_random_file_name(switch_core_session_t *session, const char *mod_name, char *file_extension); +switch_event_t *jsonapi2event(switch_core_session_t *session, switch_event_t *apply_event, const char *api, const char *data); +switch_status_t mt_merge_media_files(const char** inputs, const char *output); +switch_status_t mt_api_execute(switch_core_session_t *session, const char *apiname, const char *arguments); +void populate_dtmfa_from_event(switch_event_t *phrase_params, vmivr_profile_t *profile, vmivr_menu_profile_t menu, char **dtmfa); +#endif /* _UTIL_H_ */ + diff --git a/src/mod/applications/mod_redis/mod_redis.c b/src/mod/applications/mod_redis/mod_redis.c index ebf2a9e324..36376dd069 100755 --- a/src/mod/applications/mod_redis/mod_redis.c +++ b/src/mod/applications/mod_redis/mod_redis.c @@ -89,7 +89,7 @@ SWITCH_LIMIT_INCR(limit_incr_redis) } /* Get the keys for redis server */ - uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_hostname(), realm, resource); + uuid_rediskey = switch_core_session_sprintf(session,"%s_%s_%s", switch_core_get_switchname(), realm, resource); rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource); if ((pvt = switch_channel_get_private(channel, "limit_redis"))) { @@ -179,7 +179,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", (char *)p_key); switch_goto_status(SWITCH_STATUS_FALSE, end); } - p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_hostname(), (char *)p_key); + p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_switchname(), (char *)p_key); if (credis_decr(redis,p_uuid_key,&uuid_val) != 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", p_uuid_key); switch_goto_status(SWITCH_STATUS_FALSE, end); @@ -193,7 +193,7 @@ SWITCH_LIMIT_RELEASE(limit_release_redis) } else { rediskey = switch_core_session_sprintf(session, "%s_%s", realm, resource); - uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_hostname(), realm, resource); + uuid_rediskey = switch_core_session_sprintf(session, "%s_%s_%s", switch_core_get_switchname(), realm, resource); switch_core_hash_delete(pvt->hash, (const char *) rediskey); if (credis_decr(redis, rediskey, &val) != 0) { @@ -249,13 +249,13 @@ SWITCH_LIMIT_RESET(limit_reset_redis) { REDIS redis; if (redis_factory(&redis) == SWITCH_STATUS_SUCCESS) { - char *rediskey = switch_mprintf("%s_*", switch_core_get_hostname()); + char *rediskey = switch_mprintf("%s_*", switch_core_get_switchname()); int dec = 0, val = 0, keyc; char *uuids[2000]; if ((keyc = credis_keys(redis, rediskey, uuids, switch_arraylen(uuids))) > 0) { int i = 0; - int hostnamelen = strlen(switch_core_get_hostname())+1; + int hostnamelen = strlen(switch_core_get_switchname())+1; for (i = 0; i < keyc && uuids[i]; i++){ const char *key = uuids[i] + hostnamelen; diff --git a/src/mod/applications/mod_rss/mod_rss.c b/src/mod/applications/mod_rss/mod_rss.c index b85d86bb99..073b471bb4 100644 --- a/src/mod/applications/mod_rss/mod_rss.c +++ b/src/mod/applications/mod_rss/mod_rss.c @@ -175,7 +175,7 @@ SWITCH_STANDARD_APP(rss_function) char *filename = NULL; char *argv[3], *feed_list[TTS_MAX_ENTRIES] = { 0 }, *feed_names[TTS_MAX_ENTRIES] = { 0}; - int argc, feed_index = 0; + int feed_index = 0; const char *cf = "rss.conf"; switch_xml_t cfg, cxml, feeds, feed; char buf[1024] = ""; @@ -236,7 +236,7 @@ SWITCH_STANDARD_APP(rss_function) if (!zstr(data)) { if ((mydata = switch_core_session_strdup(session, data))) { - argc = switch_separate_string(mydata, ' ', argv, sizeof(argv) / sizeof(argv[0])); + switch_separate_string(mydata, ' ', argv, sizeof(argv) / sizeof(argv[0])); if (argv[0]) { engine = argv[0]; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index d9b9ff084a..fd2ac7f947 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -70,33 +70,89 @@ SWITCH_STANDARD_APP(stop_dtmf_session_function) spandsp_stop_inband_dtmf_session(session); } + +SWITCH_STANDARD_APP(spandsp_fax_detect_session_function) +{ + int argc = 0; + char *argv[3] = { 0 }; + char *dupdata; + const char *app = NULL, *arg = NULL; + int timeout = 0; + + if (!zstr(data) && (dupdata = switch_core_session_strdup(session, data))) { + if ((argc = switch_split(dupdata, ' ', argv)) == 3) { + app = argv[0]; + arg = argv[1]; + timeout = atoi(argv[2]); + if (timeout < 0) { + timeout = 0; + } + } + } + + if (app) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Enabling fax detection '%s' '%s'\n", argv[0], argv[1]); + spandsp_fax_detect_session(session, "rw", timeout, 1, app, arg, NULL); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot Enable fax detection '%s' '%s'\n", argv[0], argv[1]); + } +} + +SWITCH_STANDARD_APP(spandsp_stop_fax_detect_session_function) +{ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Disabling fax detection\n"); + spandsp_fax_stop_detect_session(session); +} + static void event_handler(switch_event_t *event) { mod_spandsp_fax_event_handler(event); } + SWITCH_STANDARD_APP(t38_gateway_function) { switch_channel_t *channel = switch_core_session_get_channel(session); time_t timeout = switch_epoch_time_now(NULL) + 20; const char *var; - - if (zstr(data) || strcasecmp(data, "self")) { - data = "peer"; - } - - switch_channel_set_variable(channel, "t38_leg", data); - - if ((var = switch_channel_get_variable(channel, "t38_gateway_detect_timeout"))) { - long to = atol(var); - if (to > -1) { - timeout = (time_t) (switch_epoch_time_now(NULL) + to); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s invalid timeout value.\n", switch_channel_get_name(channel)); + int argc = 0; + char *argv[2] = { 0 }; + char *dupdata; + const char *direction = NULL, *flags = NULL; + + if (!zstr(data) && (dupdata = switch_core_session_strdup(session, data))) { + if ((argc = switch_split(dupdata, ' ', argv))) { + if (argc > 0) { + direction = argv[0]; + } + + if (argc > 1) { + flags = argv[1]; + } } } + + if (zstr(direction) || strcasecmp(direction, "self")) { + direction = "peer"; + } - switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, data, NULL, t38_gateway_start); + switch_channel_set_variable(channel, "t38_leg", direction); + + if (!zstr(flags) && !strcasecmp(flags, "nocng")) { + t38_gateway_start(session, direction, NULL); + } else { + if ((var = switch_channel_get_variable(channel, "t38_gateway_detect_timeout"))) { + long to = atol(var); + if (to > -1) { + timeout = (time_t) (switch_epoch_time_now(NULL) + to); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s invalid timeout value.\n", switch_channel_get_name(channel)); + } + } + + //switch_ivr_tone_detect_session(session, "t38", "1100.0", "rw", timeout, 1, direction, NULL, t38_gateway_start); + spandsp_fax_detect_session(session, "rw", timeout, 1, direction, NULL, t38_gateway_start); + } } /** @@ -198,6 +254,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spandsp_init) SWITCH_ADD_APP(app_interface, "spandsp_stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "spandsp_start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP); + SWITCH_ADD_APP(app_interface, "spandsp_start_fax_detect", "start fax detect", "start fax detect", spandsp_fax_detect_session_function, + "[ ][ ]", SAF_NONE); + + SWITCH_ADD_APP(app_interface, "spandsp_stop_fax_detect", "stop fax detect", "stop fax detect", spandsp_stop_fax_detect_session_function, "", SAF_NONE); + + mod_spandsp_fax_load(pool); mod_spandsp_codecs_load(module_interface, pool); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.h b/src/mod/applications/mod_spandsp/mod_spandsp.h index 09e816627a..21de3fa22b 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.h +++ b/src/mod/applications/mod_spandsp/mod_spandsp.h @@ -68,3 +68,9 @@ switch_status_t spandsp_inband_dtmf_session(switch_core_session_t *session); switch_status_t callprogress_detector_start(switch_core_session_t *session, const char *name); switch_status_t callprogress_detector_stop(switch_core_session_t *session); + +switch_status_t spandsp_fax_detect_session(switch_core_session_t *session, + const char *flags, time_t timeout, + int hits, const char *app, const char *data, switch_tone_detect_callback_t callback); + +switch_status_t spandsp_fax_stop_detect_session(switch_core_session_t *session); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 4dd936b8c6..119294f4bd 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -220,7 +220,7 @@ static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void * } for (pvt = t38_state_list.head; pvt; pvt = pvt->next) { - if (pvt->udptl_state) { + if (pvt->udptl_state && pvt->session && switch_channel_ready(switch_core_session_get_channel(pvt->session))) { t38_terminal_send_timeout(pvt->t38_state, samples); } } @@ -414,18 +414,19 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) /* Fire event */ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXRESULT : SPANDSP_EVENT_RXFAXRESULT) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-success", (result == T30_ERR_OK) ? "1" : "0"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-code", fax_result_code); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-text", t30_completion_code_to_str(result)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-transferred-pages", fax_document_transferred_pages); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-total-pages", fax_document_total_pages); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_image_resolution); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-size", fax_image_size); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-bad-rows", fax_bad_rows); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-transfer-rate", fax_transfer_rate); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-code", fax_result_code); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-text", t30_completion_code_to_str(result)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-ecm-used", (t.error_correcting_mode) ? "on" : "off"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-local-station-id", local_ident); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-remote-station-id", far_ident); - switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); + switch_event_fire(&event); } } @@ -433,7 +434,6 @@ static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uin { switch_frame_t out_frame = { 0 }; switch_core_session_t *session; - switch_channel_t *channel; pvt_t *pvt; uint8_t pkt[LOCAL_FAX_MAX_DATAGRAM]; int x; @@ -441,23 +441,37 @@ static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uin pvt = (pvt_t *) user_data; session = pvt->session; - channel = switch_core_session_get_channel(session); /* we need to build a real packet here and make write_frame.packet and write_frame.packetlen point to it */ out_frame.flags = SFF_UDPTL_PACKET | SFF_PROXY_PACKET; out_frame.packet = pkt; - out_frame.packetlen = udptl_build_packet(pvt->udptl_state, pkt, buf, len); - - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "WRITE %d udptl bytes\n", out_frame.packetlen); + if ((r = udptl_build_packet(pvt->udptl_state, pkt, buf, len)) > 0) { + out_frame.packetlen = r; + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "WRITE %d udptl bytes\n", out_frame.packetlen); - for (x = 0; x < count; x++) { - if (switch_core_session_write_frame(session, &out_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { - r = -1; - break; + for (x = 0; x < count; x++) { + if (switch_core_session_write_frame(session, &out_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "INVALID WRITE: %d:%d\n", out_frame.packetlen, count); + r = -1; + break; + } } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "INVALID PACKETLEN: %d PASSED: %d:%d\n", r, len, count); + } + + if (r < 0) { + t30_state_t *t30; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TERMINATING T30 STATE\n"); + + if (pvt->t38_state && (t30 = t38_terminal_get_t30_state(pvt->t38_state))) { + t30_terminate(t30); + } + switch_yield(10000); } - return r; + return r < 0 ? r : 0; } static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode) @@ -1772,8 +1786,8 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, switch_channel_set_variable(channel, "t38_peer", switch_core_session_get_uuid(other_session)); switch_channel_set_variable(other_channel, "t38_peer", switch_core_session_get_uuid(session)); - switch_channel_set_variable(peer ? other_channel : channel, "t38_gateway_format", "audio"); - switch_channel_set_variable(peer ? channel : other_channel, "t38_gateway_format", "udptl"); + switch_channel_set_variable(peer ? other_channel : channel, "t38_gateway_format", "udptl"); + switch_channel_set_variable(peer ? channel : other_channel, "t38_gateway_format", "audio"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s starting gateway mode to %s\n", @@ -1803,6 +1817,250 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, return SWITCH_FALSE; } +typedef struct { + char *app; + char *data; + char *key; + int up; + int total_hits; + int hits; + int sleep; + int expires; + int default_sleep; + int default_expires; + switch_tone_detect_callback_t callback; + modem_connect_tones_rx_state_t rx_tones; + + switch_media_bug_t *bug; + switch_core_session_t *session; + int bug_running; + +} spandsp_fax_tone_container_t; + +static switch_status_t tone_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_"); + + + if (!cont || dtmf->digit != 'f') { + return SWITCH_STATUS_SUCCESS; + } + + if (cont->callback) { + cont->callback(cont->session, cont->app, cont->data); + } else { + switch_channel_execute_on(switch_core_session_get_channel(cont->session), "execute_on_fax_detect"); + if (cont->app) { + switch_core_session_execute_application_async(cont->session, cont->app, cont->data); + } + } + + return SWITCH_STATUS_SUCCESS; + +} + + +static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +{ + spandsp_fax_tone_container_t *cont = (spandsp_fax_tone_container_t *) user_data; + switch_frame_t *frame = NULL; + switch_bool_t rval = SWITCH_TRUE; + + switch (type) { + case SWITCH_ABC_TYPE_INIT: + if (cont) { + cont->bug_running = 1; + modem_connect_tones_rx_init(&cont->rx_tones, MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE, NULL, NULL); + } + break; + case SWITCH_ABC_TYPE_CLOSE: + break; + case SWITCH_ABC_TYPE_READ_REPLACE: + case SWITCH_ABC_TYPE_WRITE_REPLACE: + { + int skip = 0; + + if (type == SWITCH_ABC_TYPE_READ_REPLACE) { + frame = switch_core_media_bug_get_read_replace_frame(bug); + } else { + frame = switch_core_media_bug_get_write_replace_frame(bug); + } + + if (cont->sleep) { + cont->sleep--; + if (cont->sleep) { + skip = 1; + } + } + + if (cont->expires) { + cont->expires--; + if (!cont->expires) { + cont->hits = 0; + cont->sleep = 0; + cont->expires = 0; + } + } + + if (!cont->up) { + skip = 1; + } + + if (skip) { + return SWITCH_TRUE; + } + + cont->hits = 0; + modem_connect_tones_rx(&cont->rx_tones, frame->data, frame->samples); + cont->hits = modem_connect_tones_rx_get(&cont->rx_tones); + + if (cont->hits) { + switch_event_t *event; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, + "Fax Tone Detected. [%s][%s]\n", cont->app, switch_str_nil(cont->data)); + + if (cont->callback) { + cont->callback(cont->session, cont->app, cont->data); + } else { + switch_channel_execute_on(switch_core_session_get_channel(cont->session), "execute_on_fax_detect"); + if (cont->app) { + switch_core_session_execute_application_async(cont->session, cont->app, cont->data); + } + } + + + if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) { + switch_event_t *dup; + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Fax-Tone", "true"); + + if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) { + switch_event_fire(&dup); + } + + if (switch_core_session_queue_event(cont->session, &event) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR, + "Event queue failed!\n"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true"); + switch_event_fire(&event); + } + } + + rval = SWITCH_FALSE; + } + + } + break; + case SWITCH_ABC_TYPE_WRITE: + default: + break; + } + + if (rval == SWITCH_FALSE) { + cont->bug_running = 0; + } + + return rval; +} + +switch_status_t spandsp_fax_stop_detect_session(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_"); + + if (cont) { + switch_channel_set_private(channel, "_fax_tone_detect_", NULL); + cont->up = 0; + switch_core_media_bug_remove(session, &cont->bug); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + +switch_status_t spandsp_fax_detect_session(switch_core_session_t *session, + const char *flags, time_t timeout, + int hits, const char *app, const char *data, switch_tone_detect_callback_t callback) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_status_t status; + spandsp_fax_tone_container_t *cont = switch_channel_get_private(channel, "_fax_tone_detect_"); + switch_media_bug_flag_t bflags = 0; + const char *var; + switch_codec_implementation_t read_impl = { 0 }; + switch_core_session_get_read_impl(session, &read_impl); + + if (cont) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Max Tones Reached!\n"); + return SWITCH_STATUS_FALSE; + } + + if (!cont && !(cont = switch_core_session_alloc(session, sizeof(*cont)))) { + return SWITCH_STATUS_MEMERR; + } + + if (app) { + cont->app = switch_core_session_strdup(session, app); + } + + if (data) { + cont->data = switch_core_session_strdup(session, data); + } + + cont->callback = callback; + cont->up = 1; + cont->session = session; + + if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + + cont->default_sleep = 25; + cont->default_expires = 250; + + if ((var = switch_channel_get_variable(channel, "fax_tone_detect_sleep"))) { + int tmp = atoi(var); + if (tmp > 0) { + cont->default_sleep = tmp; + } + } + + if ((var = switch_channel_get_variable(channel, "fax_tone_detect_expires"))) { + int tmp = atoi(var); + if (tmp > 0) { + cont->default_expires = tmp; + } + } + + if (zstr(flags)) { + bflags = SMBF_READ_REPLACE; + } else { + if (strchr(flags, 'r')) { + bflags |= SMBF_READ_REPLACE; + } else if (strchr(flags, 'w')) { + bflags |= SMBF_WRITE_REPLACE; + } + } + + bflags |= SMBF_NO_PAUSE; + + + switch_core_event_hook_add_send_dtmf(session, tone_on_dtmf); + switch_core_event_hook_add_recv_dtmf(session, tone_on_dtmf); + + + if ((status = switch_core_media_bug_add(session, "fax_tone_detect", "", + tone_detect_callback, cont, timeout, bflags, &cont->bug)) != SWITCH_STATUS_SUCCESS) { + cont->bug_running = 0; + return status; + } + + switch_channel_set_private(channel, "_fax_tone_detect_", cont); + + return SWITCH_STATUS_SUCCESS; +} + + /* For Emacs: diff --git a/src/mod/applications/mod_spandsp/udptl.c b/src/mod/applications/mod_spandsp/udptl.c index f5b3be2445..cde248c3d9 100644 --- a/src/mod/applications/mod_spandsp/udptl.c +++ b/src/mod/applications/mod_spandsp/udptl.c @@ -61,7 +61,6 @@ static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8 int octet_cnt; int octet_idx; int stat; - int i; const uint8_t **pbuf; for (octet_idx = 0, *p_num_octets = 0;; octet_idx += octet_cnt) { @@ -71,7 +70,6 @@ static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8 *p_num_octets += octet_cnt; pbuf = &p_object[octet_idx]; - i = 0; /* Make sure the buffer contains at least the number of bits requested */ if ((*len + octet_cnt) > limit) return -1; diff --git a/src/mod/applications/mod_vmd/mod_vmd.c b/src/mod/applications/mod_vmd/mod_vmd.c index 4a20df8183..3bb1e6b16e 100644 --- a/src/mod/applications/mod_vmd/mod_vmd.c +++ b/src/mod/applications/mod_vmd/mod_vmd.c @@ -237,9 +237,8 @@ static switch_bool_t process_data(vmd_session_info_t *vmd_info, switch_frame_t * double pts[P]; int16_t *data; int16_t max; - switch_ssize_t len; - len = frame->samples * sizeof(int16_t); + //len = frame->samples * sizeof(int16_t); data = (int16_t *) frame->data; for (max = (int16_t) abs(data[0]), i = 1; i < frame->samples; i++) { diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index a046021034..4d31279882 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -204,6 +204,36 @@ static switch_status_t vm_execute_sql(vm_profile_t *profile, char *sql, switch_m return status; } +char *vm_execute_sql2str(vm_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len) +{ + switch_cache_db_handle_t *dbh = NULL; + + char *ret = NULL; + + if (mutex) { + switch_mutex_lock(mutex); + } + + if (!(dbh = vm_get_db_handle(profile))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n"); + goto end; + } + + ret = switch_cache_db_execute_sql2str(dbh, sql, resbuf, len, NULL); + +end: + + switch_cache_db_release_db_handle(&dbh); + + if (mutex) { + switch_mutex_unlock(mutex); + } + + return ret; + +} + + static switch_bool_t vm_execute_sql_callback(vm_profile_t *profile, switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata) { @@ -2384,7 +2414,6 @@ static switch_status_t deliver_vm(vm_profile_t *profile, char *vm_email = NULL; char *vm_email_from = NULL; char *vm_notify_email = NULL; - char *email_addr = NULL; char *vm_timezone = NULL; int send_mail = 0; int send_main = 0; @@ -2449,8 +2478,6 @@ static switch_status_t deliver_vm(vm_profile_t *profile, vm_notify_email = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "vm-mailfrom")) { vm_email_from = switch_core_strdup(pool, val); - } else if (!strcasecmp(var, "email-addr")) { - email_addr = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "vm-email-all-messages") && (send_main = switch_true(val))) { send_mail++; } else if (!strcasecmp(var, "vm-notify-email-all-messages") && (send_notify = switch_true(val))) { @@ -2487,12 +2514,26 @@ static switch_status_t deliver_vm(vm_profile_t *profile, goto failed; } - file_path = switch_mprintf("%s%smsg_%s_broadcast_%s", dir_path, SWITCH_PATH_SEPARATOR, use_uuid, filename); - if (copy) { + file_path = switch_mprintf("%s%smsg_%s_broadcast_%s", dir_path, SWITCH_PATH_SEPARATOR, use_uuid, filename); + + if (strlen(file_path) >= 250 /* Max size of the SQL field */) { + char *ext; + switch_safe_free(file_path); + + if (!(ext = strrchr(filename, '.'))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Filename doesn't include a file format %s\n", filename); + ret = SWITCH_STATUS_FALSE; + goto failed; + } + + ext++; + + file_path = switch_mprintf("%s%smsg_%s_broadcast_%" SWITCH_TIME_T_FMT ".%s", dir_path, SWITCH_PATH_SEPARATOR, use_uuid, switch_micro_time_now(), ext); + } + switch_file_copy(path, file_path, SWITCH_FPROT_FILE_SOURCE_PERMS, pool); } else { - switch_safe_free(file_path); file_path = (char *) path; } @@ -2957,8 +2998,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p int send_mail = 0; cc_t cc = { 0 }; char *read_flags = NORMAL_FLAG_STRING; - int priority = 3; - int email_attach = 1; char *operator_ext = NULL; char buf[2]; char key_buf[80]; @@ -2973,7 +3012,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p char *record_macro = VM_RECORD_MESSAGE_MACRO; int send_main = 0; int send_notify = 0; - int insert_db = 1; const char *read_id = NULL; const char *caller_id_name = NULL; const char *caller_id_number = NULL; @@ -3030,10 +3068,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p vm_storage_dir = switch_core_session_strdup(session, val); } else if (!strcasecmp(var, "vm-notify-email-all-messages") && (send_notify = switch_true(val))) { send_mail++; - } else if (!strcasecmp(var, "vm-keep-local-after-email")) { - insert_db = switch_true(val); - } else if (!strcasecmp(var, "vm-attach-file")) { - email_attach = switch_true(val); } else if (!strcasecmp(var, "vm-disk-quota")) { disk_quota = atoi(val); } else if (!strcasecmp(var, "vm-alternate-greet-id")) { @@ -3073,11 +3107,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Falling back to leaving message locally due to too many misconfiguration.\n"); send_mail = 0; - insert_db = 1; - } - - if (send_notify && !send_main) { - insert_db = 1; } } else { @@ -3259,7 +3288,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p (void) vm_macro_get(session, VM_RECORD_URGENT_CHECK_MACRO, key_buf, input, sizeof(input), 1, "", &term, profile->digit_timeout); if (*profile->urgent_key == *input) { read_flags = URGENT_FLAG_STRING; - priority = 1; (void) switch_ivr_phrase_macro(session, VM_ACK_MACRO, "marked-urgent", NULL, NULL); } else { (void) switch_ivr_phrase_macro(session, VM_ACK_MACRO, "saved", NULL, NULL); @@ -3301,7 +3329,6 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p SWITCH_STANDARD_APP(voicemail_function) { - int argc = 0; char *argv[6] = { 0 }; char *mydata = NULL; vm_profile_t *profile = NULL; @@ -3315,7 +3342,7 @@ SWITCH_STANDARD_APP(voicemail_function) if (!zstr(data)) { mydata = switch_core_session_strdup(session, data); - argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } for (;;) { @@ -4329,7 +4356,6 @@ SWITCH_STANDARD_API(voicemail_list_api_function) #define VOICEMAIL_SYNTAX "rss [ ] | [load|unload|reload] [reloadxml]" SWITCH_STANDARD_API(voicemail_api_function) { - int argc = 0; char *mydata = NULL, *argv[6]; char *host = NULL, *port = NULL, *uri = NULL; char *user = NULL, *domain = NULL; @@ -4341,7 +4367,7 @@ SWITCH_STANDARD_API(voicemail_api_function) void *val = NULL; switch_xml_t xml_root; const char *err; - + int argc = 0; if (session) { return SWITCH_STATUS_FALSE; @@ -4480,6 +4506,795 @@ SWITCH_STANDARD_API(voicemail_api_function) return SWITCH_STATUS_SUCCESS; } +struct msg_get_callback { + switch_event_t *my_params; +}; +typedef struct msg_get_callback msg_get_callback_t; + +static int message_get_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + msg_get_callback_t *cbt = (msg_get_callback_t *) pArg; + + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Received-Epoch", "%s", argv[0]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Read-Epoch", "%s", argv[1]); + /* switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, user, argv[2], 255); */ + /* switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, domain, argv[3], 255); */ + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-UUID", "%s", argv[4]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Caller-Name", "%s", argv[5]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Caller-Number", "%s", argv[6]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Folder", "%s", argv[7]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-File-Path", "%s", argv[8]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Duration", "%s", argv[9]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Flags", "%s", argv[10]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Read-Flags", "%s", argv[11]); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, "VM-Message-Forwarded-By", "%s", argv[12]); + + return 0; +} + +struct msg_lst_callback { + char *buf; + size_t len; + switch_event_t *my_params; +}; +typedef struct msg_lst_callback msg_lst_callback_t; + +static int message_list_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + msg_lst_callback_t *cbt = (msg_lst_callback_t *) pArg; + char *varname = NULL; + /* Message # never start with 0 */ + varname = switch_mprintf("VM-List-Message-%ld-UUID", ++cbt->len); + switch_event_add_header(cbt->my_params, SWITCH_STACK_BOTTOM, varname, "%s", argv[0]); + switch_safe_free(varname); + return 0; +} + +static int message_purge_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + const char *profile_name = argv[0]; + const char *uuid = argv[1]; + const char *id = argv[2]; + const char *domain = argv[3]; + const char *file_path = argv[4]; + char *sql; + vm_profile_t *profile = get_profile(profile_name); + + if (unlink(file_path) != 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete file [%s]\n", file_path); + } else { + sql = switch_mprintf("DELETE FROM voicemail_msgs WHERE username='%q' AND domain='%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + } + profile_rwunlock(profile); + + return 0; +} + +/* Preference API */ +#define VM_FSDB_PREF_GREETING_SET_USAGE " [file-path]" +SWITCH_STANDARD_API(vm_fsdb_pref_greeting_set_function) +{ + int slot = -1; + const char *file_path = NULL; + char *sql = NULL; + char res[254] = ""; + + char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + slot = atoi(argv[3]); + if (argv[4]) + file_path = argv[4]; + + if (!profile_name || !domain || !id || !slot) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } else { + char *dir_path = switch_core_sprintf(pool, "%s%svoicemail%s%s%s%s%s%s", SWITCH_GLOBAL_dirs.storage_dir, + SWITCH_PATH_SEPARATOR, + SWITCH_PATH_SEPARATOR, + profile->name, SWITCH_PATH_SEPARATOR, domain, SWITCH_PATH_SEPARATOR, id); + char *final_file_path = switch_core_sprintf(pool, "%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, slot, profile->file_ext); + + if (file_path) { + if (switch_file_exists(file_path, pool) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "-ERR Filename doesn't exist\n"); + profile_rwunlock(profile); + goto done; + } + + switch_file_rename(file_path, final_file_path, pool); + } + + if (switch_file_exists(final_file_path, pool) == SWITCH_STATUS_SUCCESS) { + + sql = switch_mprintf("SELECT count(*) FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, res, sizeof(res)); + switch_safe_free(sql); + + if (atoi(res) == 0) { + sql = switch_mprintf("INSERT INTO voicemail_prefs (username, domain, greeting_path) VALUES('%q', '%q', '%q')", id, domain, final_file_path); + } else { + sql = switch_mprintf("UPDATE voicemail_prefs SET greeting_path = '%q' WHERE username = '%q' AND domain = '%q'", final_file_path, id, domain); + } + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + } else { + stream->write_function(stream, "-ERR Recording doesn't exist [%s]\n", final_file_path); + } + profile_rwunlock(profile); + } + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_PREF_RECNAME_SET_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_pref_recname_set_function) +{ + const char *file_path = NULL; + + char *sql = NULL; + char res[254] = ""; + + char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + file_path = argv[3]; + + if (!profile_name || !domain || !id || !file_path) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + if (switch_file_exists(file_path, pool) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "-ERR Filename doesn't exist\n"); + profile_rwunlock(profile); + goto done; + } + + sql = switch_mprintf("SELECT count(*) FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, res, sizeof(res)); + switch_safe_free(sql); + + if (atoi(res) == 0) { + sql = switch_mprintf("INSERT INTO voicemail_prefs (username, domain, name_path) VALUES('%q', '%q', '%q')", id, domain, file_path); + } else { + sql = switch_mprintf("UPDATE voicemail_prefs SET name_path = '%q' WHERE username = '%q' AND domain = '%q'", file_path, id, domain); + } + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + { + char *dir_path = switch_core_sprintf(pool, "%s%svoicemail%s%s%s%s%s%s", SWITCH_GLOBAL_dirs.storage_dir, + SWITCH_PATH_SEPARATOR, + SWITCH_PATH_SEPARATOR, + profile->name, SWITCH_PATH_SEPARATOR, domain, SWITCH_PATH_SEPARATOR, id); + char *final_file_path = switch_core_sprintf(pool, "%s%srecorded_name.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext); + + if (switch_file_exists(file_path, pool) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "-ERR Filename doesn't exist\n"); + profile_rwunlock(profile); + goto done; + } + + switch_file_rename(file_path, final_file_path, pool); + + } + profile_rwunlock(profile); + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_PREF_PASSWORD_SET_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_pref_password_set_function) +{ + const char *password = NULL; + + char *sql = NULL; + char res[254] = ""; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + password = argv[3]; + + if (!profile_name || !domain || !id || !password) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("SELECT count(*) FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, res, sizeof(res)); + switch_safe_free(sql); + + if (atoi(res) == 0) { + sql = switch_mprintf("INSERT INTO voicemail_prefs (username, domain, password) VALUES('%q', '%q', '%q')", id, domain, password); + } else { + sql = switch_mprintf("UPDATE voicemail_prefs SET password = '%q' WHERE username = '%q' AND domain = '%q'", password, id, domain); + } + vm_execute_sql(profile, sql, profile->mutex); + switch_safe_free(sql); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + + + +/* Message API */ + +#define VM_FSDB_MSG_LIST_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_list_function) +{ + char *sql; + msg_lst_callback_t cbt = { 0 }; + char *ebuf = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[1]) + profile_name = argv[1]; + if (argv[2]) + domain = argv[2]; + if (argv[3]) + id = argv[3]; + + if (!profile_name || !domain || !id) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + sql = switch_mprintf("SELECT uuid FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND read_epoch = 0 ORDER BY read_flags, created_epoch", id, domain); + + memset(&cbt, 0, sizeof(cbt)); + + switch_event_create(&cbt.my_params, SWITCH_EVENT_REQUEST_PARAMS); + + vm_execute_sql_callback(profile, profile->mutex, sql, message_list_callback, &cbt); + + profile_rwunlock(profile); + + switch_event_add_header(cbt.my_params, SWITCH_STACK_BOTTOM, "VM-List-Count", "%"SWITCH_SIZE_T_FMT, cbt.len); + switch_event_serialize_json(cbt.my_params, &ebuf); + switch_event_destroy(&cbt.my_params); + + switch_safe_free(sql); + stream->write_function(stream, "%s", ebuf); + switch_safe_free(ebuf); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_PURGE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_purge_function) +{ + char *sql; + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + + if (!profile_name || !domain || !id) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("SELECT '%q', uuid, username, domain, file_path FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND flags = 'delete'", profile_name, id, domain); + vm_execute_sql_callback(profile, profile->mutex, sql, message_purge_callback, NULL); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); + +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_DELETE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_delete_function) +{ + char *sql; + const char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + uuid = argv[3]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("UPDATE voicemail_msgs SET flags = 'delete' WHERE username = '%q' AND domain = '%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); + +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_SAVE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_save_function) +{ + char *sql; + const char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + uuid = argv[3]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("UPDATE voicemail_msgs SET flags='save' WHERE username='%q' AND domain='%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_UNDELETE_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_undelete_function) +{ + char *sql; + const char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + uuid = argv[3]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("UPDATE voicemail_msgs SET flags='' WHERE username='%q' AND domain='%q' AND uuid = '%q'", id, domain, uuid); + vm_execute_sql(profile, sql, profile->mutex); + profile_rwunlock(profile); + + stream->write_function(stream, "-OK\n"); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_AUTH_LOGIN_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_auth_login_function) +{ + char *sql; + char *password = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + char user_db_password[64] = { 0 }; + const char *user_xml_password = NULL; + + switch_event_t *params = NULL; + switch_xml_t x_user = NULL; + switch_bool_t vm_enabled = SWITCH_TRUE; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[0]) + profile_name = argv[0]; + if (argv[1]) + domain = argv[1]; + if (argv[2]) + id = argv[2]; + if (argv[3]) + password = argv[3]; + + if (!profile_name || !domain || !id || !password) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + switch_event_create(¶ms, SWITCH_EVENT_GENERAL); + if (switch_xml_locate_user_merged("id", id, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", id, domain); + stream->write_function(stream, "-ERR User not found\n"); + } else { + switch_xml_t x_param, x_params; + + x_params = switch_xml_child(x_user, "params"); + + for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { + const char *var = switch_xml_attr_soft(x_param, "name"); + const char *val = switch_xml_attr_soft(x_param, "value"); + if (zstr(var) || zstr(val)) { + continue; /* Ignore empty entires */ + } + + if (!strcasecmp(var, "vm-enabled")) { + vm_enabled = !switch_false(val); + } + if (!strcasecmp(var, "vm-password")) { + user_xml_password = val; + } + } + + sql = switch_mprintf("SELECT password FROM voicemail_prefs WHERE username = '%q' AND domain = '%q'", id, domain); + vm_execute_sql2str(profile, profile->mutex, sql, user_db_password, sizeof(user_db_password)); + switch_safe_free(sql); + } + + if (vm_enabled == SWITCH_FALSE) { + stream->write_function(stream, "%s", "-ERR Login Denied"); + } else if (!zstr(user_db_password)) { + if (!strcasecmp(user_db_password, password)) { + stream->write_function(stream, "%s", "-OK"); + } else { + stream->write_function(stream, "%s", "-ERR"); + } + } else if (!zstr(user_xml_password)) { + if (!strcasecmp(user_xml_password, password)) { + stream->write_function(stream, "%s", "-OK"); + } else { + stream->write_function(stream, "%s", "-ERR"); + } + } else { + stream->write_function(stream, "%s", "-ERR"); + + } + + switch_xml_free(x_user); + profile_rwunlock(profile); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_GET_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_get_function) +{ + char *sql; + msg_get_callback_t cbt = { 0 }; + char *ebuf = NULL; + char *uuid = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[1]) + profile_name = argv[1]; + if (argv[2]) + domain = argv[2]; + if (argv[3]) + id = argv[3]; + if (argv[4]) + uuid = argv[4]; + + if (!profile_name || !domain || !id || !uuid) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf("SELECT * FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND uuid = '%q' ORDER BY read_flags, created_epoch", id, domain, uuid); + + memset(&cbt, 0, sizeof(cbt)); + + switch_event_create(&cbt.my_params, SWITCH_EVENT_REQUEST_PARAMS); + + vm_execute_sql_callback(profile, profile->mutex, sql, message_get_callback, &cbt); + + profile_rwunlock(profile); + + switch_event_serialize_json(cbt.my_params, &ebuf); + switch_event_destroy(&cbt.my_params); + + switch_safe_free(sql); + stream->write_function(stream, "%s", ebuf); + switch_safe_free(ebuf); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + +#define VM_FSDB_MSG_COUNT_USAGE " " +SWITCH_STANDARD_API(vm_fsdb_msg_count_function) +{ + char *sql; + msg_cnt_callback_t cbt = { 0 }; + switch_event_t *my_params = NULL; + char *ebuf = NULL; + + const char *id = NULL, *domain = NULL, *profile_name = NULL; + vm_profile_t *profile = NULL; + + char *argv[6] = { 0 }; + char *mycmd = NULL; + + switch_memory_pool_t *pool; + + switch_core_new_memory_pool(&pool); + + if (!zstr(cmd)) { + mycmd = switch_core_strdup(pool, cmd); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argv[1]) + profile_name = argv[1]; + if (argv[2]) + domain = argv[2]; + if (argv[3]) + id = argv[3]; + + if (!profile_name || !domain || !id) { + stream->write_function(stream, "-ERR Missing Arguments\n"); + goto done; + } + + if (!(profile = get_profile(profile_name))) { + stream->write_function(stream, "-ERR Profile not found\n"); + goto done; + } + + sql = switch_mprintf( + "SELECT 1, read_flags, count(read_epoch) FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND in_folder = '%q' AND read_epoch = 0 GROUP BY read_flags " + "UNION " + "SELECT 0, read_flags, count(read_epoch) FROM voicemail_msgs WHERE username = '%q' AND domain = '%q' AND in_folder = '%q' AND read_epoch <> 0 GROUP BY read_flags;", + id, domain, "inbox", + id, domain, "inbox"); + + + vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt); + + profile_rwunlock(profile); + + switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-New-Messages", "%d", cbt.total_new_messages + cbt.total_new_urgent_messages); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-New-Urgent-Messages", "%d", cbt.total_new_urgent_messages); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-Saved-Messages", "%d", cbt.total_saved_messages + cbt.total_saved_urgent_messages); + switch_event_add_header(my_params, SWITCH_STACK_BOTTOM, "VM-Total-Saved-Urgent-Messages", "%d", cbt.total_saved_urgent_messages); + switch_event_serialize_json(my_params, &ebuf); + switch_event_destroy(&my_params); + + switch_safe_free(sql); + stream->write_function(stream, "%s", ebuf); + switch_safe_free(ebuf); +done: + switch_core_destroy_memory_pool(&pool); + return SWITCH_STATUS_SUCCESS; +} + SWITCH_MODULE_LOAD_FUNCTION(mod_voicemail_load) { switch_application_interface_t *app_interface; @@ -4521,6 +5336,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voicemail_load) SWITCH_ADD_API(commands_api_interface, "vm_read", "vm_read", voicemail_read_api_function, VM_READ_USAGE); SWITCH_ADD_API(commands_api_interface, "vm_list", "vm_list", voicemail_list_api_function, VM_LIST_USAGE); + /* Auth API */ + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_auth_login", "vm_fsdb_auth_login", vm_fsdb_auth_login_function, VM_FSDB_AUTH_LOGIN_USAGE); + + /* Message Targeted API */ + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_count", "vm_fsdb_msg_count", vm_fsdb_msg_count_function, VM_FSDB_MSG_COUNT_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_list", "vm_fsdb_msg_list", vm_fsdb_msg_list_function, VM_FSDB_MSG_LIST_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_get", "vm_fsdb_msg_get", vm_fsdb_msg_get_function, VM_FSDB_MSG_GET_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_delete", "vm_fsdb_msg_delete", vm_fsdb_msg_delete_function, VM_FSDB_MSG_DELETE_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_undelete", "vm_fsdb_msg_undelete", vm_fsdb_msg_undelete_function, VM_FSDB_MSG_UNDELETE_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_purge", "vm_fsdb_msg_purge", vm_fsdb_msg_purge_function, VM_FSDB_MSG_PURGE_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_msg_save", "vm_fsdb_msg_save", vm_fsdb_msg_save_function, VM_FSDB_MSG_SAVE_USAGE); + + /* Preferences */ + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_pref_greeting_set", "vm_fsdb_pref_greeting_set", vm_fsdb_pref_greeting_set_function, VM_FSDB_PREF_GREETING_SET_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_pref_recname_set", "vm_fsdb_pref_recname_set", vm_fsdb_pref_recname_set_function, VM_FSDB_PREF_RECNAME_SET_USAGE); + SWITCH_ADD_API(commands_api_interface, "vm_fsdb_pref_password_set", "vm_fsdb_pref_password_set", vm_fsdb_pref_password_set_function, VM_FSDB_PREF_PASSWORD_SET_USAGE); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c index 432a0b7c99..63ed2a23d9 100644 --- a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c +++ b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c @@ -65,6 +65,14 @@ typedef struct { } cepstral_t; +static struct { + char *encoding; +} globals; + +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_encoding, globals.encoding); + + + /* This callback caches the audio in the buffer */ static swift_result_t write_audio(swift_event * event, swift_event_t type, void *udata) { @@ -223,7 +231,7 @@ static switch_status_t cepstral_speech_feed_tts(switch_speech_handle_t *sh, char if (zstr(text)) { return SWITCH_STATUS_FALSE; } - swift_port_speak_file(cepstral->port, text, NULL, &cepstral->tts_stream, NULL); + swift_port_speak_file(cepstral->port, text, globals.encoding, &cepstral->tts_stream, NULL); } else { char *to_say; if (zstr(text)) { @@ -231,7 +239,7 @@ static switch_status_t cepstral_speech_feed_tts(switch_speech_handle_t *sh, char } if ((to_say = switch_mprintf(" %s ", text))) { - swift_port_speak_text(cepstral->port, to_say, 0, NULL, &cepstral->tts_stream, NULL); + swift_port_speak_text(cepstral->port, to_say, 0, globals.encoding, &cepstral->tts_stream, NULL); switch_safe_free(to_say); } } @@ -401,10 +409,54 @@ static void cepstral_float_param_tts(switch_speech_handle_t *sh, char *param, do } +static switch_status_t load_config(void) +{ + char *cf = "cepstral.conf"; + switch_xml_t cfg, xml = NULL, param, settings; + + /* Init to SWIFT default encoding */ + set_global_encoding(SWIFT_DEFAULT_ENCODING); + + if (xml = switch_xml_open_cfg(cf, &cfg, NULL)) { + if ((settings = switch_xml_child(cfg, "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, "encoding")) { + if (!strcasecmp(val, "utf-8")) { + set_global_encoding(SWIFT_UTF8); + } else if (!strcasecmp(val, "us-ascii")) { + set_global_encoding(SWIFT_ASCII); + } else if (!strcasecmp(val, "iso8859-1")) { + set_global_encoding(SWIFT_ISO_8859_1); + } else if (!strcasecmp(val, "iso8859-15")) { + set_global_encoding(SWIFT_ISO_8859_15); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown value \"%s\" for param \"%s\". Setting to default.\n", val, var); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Param \"%s\" unknown\n", var); + } + } + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Open of \"%s\" failed. Using default settings.\n", cf); + } + + if (xml) { + switch_xml_free(xml); + } + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_MODULE_LOAD_FUNCTION(mod_cepstral_load) { switch_speech_interface_t *speech_interface; + memset(&globals, 0, sizeof(globals)); + load_config(); + /* Open the Swift TTS Engine */ if (!(engine = swift_engine_open(NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open Swift Engine."); diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index 9d7c21574a..53281bc389 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -3369,7 +3369,7 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp speech_channel_set_state(schannel, SPEECH_CHANNEL_PROCESSING); } else if (message->start_line.request_state == MRCP_REQUEST_STATE_COMPLETE) { /* RECOGNIZE failed to start */ - if (recog_hdr->completion_cause == RECOGNIZER_COMPLETION_CAUSE_UNKNOWN) { + if (!recog_hdr || recog_hdr->completion_cause == RECOGNIZER_COMPLETION_CAUSE_UNKNOWN) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) RECOGNIZE failed: status = %d\n", schannel->name, message->start_line.status_code); } else { diff --git a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c b/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c index 0553607bfe..a5bf1ecad7 100644 --- a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c +++ b/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c @@ -250,7 +250,6 @@ static switch_status_t switch_dahdi_encode(switch_codec_t *codec, { int32_t res; short *dbuf_linear; - unsigned char *ebuf_g729; unsigned char ebuf_ulaw[decoded_data_len / 2]; uint32_t i; struct dahdi_context *context = NULL; @@ -268,7 +267,6 @@ static switch_status_t switch_dahdi_encode(switch_codec_t *codec, } dbuf_linear = decoded_data; - ebuf_g729 = encoded_data; for (i = 0; i < decoded_data_len / sizeof(short); i++) { ebuf_ulaw[i] = linear_to_ulaw(dbuf_linear[i]); } 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 dd97453c7a..c2d6ae40b5 100644 --- a/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c +++ b/src/mod/codecs/mod_sangoma_codec/mod_sangoma_codec.c @@ -89,14 +89,14 @@ vocallo_codec_t g_codec_map[] = { SNGTC_CODEC_PCMA, IANA_PCMA_A_8000_1, "PCMA", "Sangoma PCMA", 40, 64000, 10000, 80, 160, 80, 8000, 8000, 1 }, { SNGTC_CODEC_L16_1, IANA_L16_A_8000_1, "L16", "Sangoma L16", 40, 120000, 10000, 80, 160, 160, 8000, 8000, 0 }, { SNGTC_CODEC_L16_2, IANA_L16_A_16000_1, "L16", "Sangoma L16 2", 40, 320000, 10000, 160, 320, 320, 16000, 16000, 0 }, - { SNGTC_CODEC_G729AB, IANA_G729_AB_8000_1, "G729", "Sangoma G729", 40, 8000, 10000, 80, 160, 10, 8000, 8000, 1 }, + { SNGTC_CODEC_G729AB, IANA_G729_AB_8000_1, "G729", "Sangoma G729", 200, 8000, 10000, 80, 160, 10, 8000, 8000, 1 }, { SNGTC_CODEC_G726_32, IANA_G726_32_8000_1, "G726-32", "Sangoma G.726 32k", 40, 32000, 10000, 80, 160, 40, 8000, 8000, 1 }, { SNGTC_CODEC_G722, IANA_G722_A_8000_1, "G722", "Sangoma G722", 20, 64000, 10000, 80, 160, 80, 8000, 8000, 1 }, /* manually initialized */ { SNGTC_CODEC_GSM_FR, IANA_GSM_A_8000_1, "GSM", "Sangoma GSM", 20, 13200, 20000, 160, 320, 33, 8000, 8000, 0 }, { SNGTC_CODEC_G723_1_63, IANA_G723_A_8000_1, "G723", "Sangoma G723", 90, 6300, 30000, 240, 480, 24, 8000, 8000, 0 }, - { SNGTC_CODEC_AMR_1220, IANA_AMR_WB_16000_1, "AMR", "Sangoma AMR", 20, 12200, 20000, 160, 320, 0, 8000, 8000, 0 }, + { SNGTC_CODEC_AMR_1220, IANA_AMR_A_8000_1, "AMR", "Sangoma AMR", 20, 12200, 20000, 160, 320, 0, 8000, 8000, 0 }, { SNGTC_CODEC_SIREN7_24, IANA_SIREN7, "G7221", "Sangoma G722.1", 20, 24000, 20000, 320, 640, 60, 16000, 16000, 0 }, { SNGTC_CODEC_SIREN7_32, IANA_SIREN7, "G7221", "Sangoma G722.1", 20, 32000, 20000, 320, 640, 80, 16000, 16000, 0 }, { SNGTC_CODEC_ILBC_133, IANA_ILBC_133_8000_1, "iLBC", "Sangoma iLBC", 30, 13300, 30000, 240, 480, 50, 8000, 8000, 0 }, @@ -131,6 +131,7 @@ struct codec_data { /* packet counters */ unsigned long tx; unsigned long rx; + unsigned long ticks; /* Lost packets */ long lastrxseqno; @@ -467,6 +468,8 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec func_start_time = switch_micro_time_now(); } + sess->encoder.ticks++; + /* start assuming we will not encode anything */ *encoded_data_len = 0; @@ -547,7 +550,7 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec continue; } - if (encoded_frame.datalen != codec->implementation->encoded_bytes_per_packet) { + if (codec->implementation->encoded_bytes_per_packet && encoded_frame.datalen != codec->implementation->encoded_bytes_per_packet) { /* seen when silence suppression is enabled */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring encoded frame of %d bytes intead of %d bytes\n", encoded_frame.datalen, codec->implementation->encoded_bytes_per_packet); continue; @@ -619,7 +622,7 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec sess->encoder.rtp_queue[sess->encoder.queue_rindex].datalen = 0; SAFE_INDEX_INC(sess->encoder.rtp_queue, sess->encoder.queue_rindex); sess->encoder.queue_size--; - if (*encoded_data_len != codec->implementation->encoded_bytes_per_packet) { + if (codec->implementation->encoded_bytes_per_packet && *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); } } else { @@ -667,6 +670,7 @@ static switch_status_t switch_sangoma_decode(switch_codec_t *codec, /* codec ses } dbuf_linear = decoded_data; + sess->decoder.ticks++; /* start assuming we will not decode anything */ *decoded_data_len = 0; @@ -989,6 +993,7 @@ SWITCH_STANDARD_API(sangoma_function) stream->write_function(stream, "Rx %s at %d.%d.%d.%d:%d from %d.%d.%d.%d:%d\n\n", sess->impl->iananame, SNGTC_NIPV4(sess->encoder.reply.b.host_ip), sess->encoder.reply.b.host_udp_port, SNGTC_NIPV4(sess->encoder.reply.b.codec_ip), sess->encoder.reply.b.codec_udp_port); + stream->write_function(stream, "Ticks: %lu\n", sess->encoder.ticks); stream->write_function(stream, "-- Inbound Stats --\n"); stream->write_function(stream, "Rx Discarded: %lu\n", sess->encoder.rxdiscarded); @@ -1008,6 +1013,7 @@ SWITCH_STANDARD_API(sangoma_function) SNGTC_NIPV4(sess->decoder.reply.a.codec_ip), sess->decoder.reply.a.codec_udp_port); stream->write_function(stream, "Rx L16 at %d.%d.%d.%d:%d from %d.%d.%d.%d:%d\n\n", SNGTC_NIPV4(sess->decoder.reply.b.host_ip), sess->decoder.reply.b.host_udp_port, SNGTC_NIPV4(sess->decoder.reply.b.codec_ip), sess->decoder.reply.b.codec_udp_port); + stream->write_function(stream, "Ticks: %lu\n", sess->decoder.ticks); stream->write_function(stream, "-- Inbound Stats --\n"); stream->write_function(stream, "Rx Discarded: %lu\n", sess->decoder.rxdiscarded); diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index 3bc5cb4a3d..4e62a00da8 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -164,7 +164,6 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt) int argc; char *argv[3] = { 0 }; char *pattern = NULL; - char *pri = NULL; char *app = NULL; char *argument = NULL; char *expression = NULL, expression_buf[1024] = ""; @@ -242,7 +241,7 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt) switch_channel_set_variable(channel, "CHANNEL", switch_channel_get_name(channel)); switch_channel_set_variable(channel, "UNIQUEID", switch_core_session_get_uuid(session)); - pri = argv[1]; + //pri = argv[1]; app = argv[2]; if ((argument = strchr(app, '('))) { diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index b0bfeada97..2db3660ccd 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -30,6 +30,7 @@ * */ #include +#include #include #include @@ -1399,7 +1400,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch { struct private_object *tech_pvt = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); - int payload = 0; + //int payload = 0; tech_pvt = (struct private_object *) switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); @@ -1443,7 +1444,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch - payload = tech_pvt->read_frame.payload; + //payload = tech_pvt->read_frame.payload; #if 0 elapsed = (unsigned int) ((switch_micro_time_now() - started) / 1000); @@ -1911,6 +1912,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load) SWITCH_ADD_API(api_interface, "dingaling", "DingaLing Menu", dingaling, DINGALING_SYNTAX); SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send); + switch_ssl_init_ssl_locks(); + + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } @@ -2008,6 +2012,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dingaling_shutdown) switch_safe_free(globals.codec_string); switch_safe_free(globals.codec_rates_string); + switch_ssl_destroy_ssl_locks(); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_gsmopen/Makefile.am b/src/mod/endpoints/mod_gsmopen/Makefile.am index bde175df8f..8879a4616d 100644 --- a/src/mod/endpoints/mod_gsmopen/Makefile.am +++ b/src/mod/endpoints/mod_gsmopen/Makefile.am @@ -1,7 +1,24 @@ include $(top_srcdir)/build/modmake.rulesam MODNAME=mod_gsmopen + +TIFF_DIR=$(switch_srcdir)/libs/tiff-3.8.2 +TIFF_BUILDDIR=$(switch_builddir)/libs/tiff-3.8.2 +TIFF_LA=$(TIFF_BUILDDIR)/libtiff/libtiff.la + +SPANDSP_DIR=$(switch_srcdir)/libs/spandsp +SPANDSP_BUILDDIR=$(switch_builddir)/libs/spandsp +SPANDSP_LA=$(SPANDSP_BUILDDIR)/src/libspandsp.la + mod_LTLIBRARIES = mod_gsmopen.la mod_gsmopen_la_SOURCES = mod_gsmopen.cpp gsmopen_protocol.cpp -mod_gsmopen_la_CFLAGS = $(AM_CFLAGS) -DGSMOPEN_SVN_VERSION=\"`cat $(switch_builddir)/.version`\" -mod_gsmopen_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_gsmopen_la_LDFLAGS = -avoid-version -module -no-undefined -lasound -lgsmme -lspandsp +mod_gsmopen_la_CFLAGS = $(AM_CFLAGS) -I$(SPANDSP_DIR)/src -I$(TIFF_DIR)/libtiff -I$(SPANDSP_BUILDDIR)/src -I$(TIFF_BUILDDIR)/libtiff -I. -DGSMOPEN_SVN_VERSION=\"`cat $(switch_builddir)/.version`\" +mod_gsmopen_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LA) $(TIFF_LA) +mod_gsmopen_la_LDFLAGS = -avoid-version -module -no-undefined -lasound -lgsmme + +$(SPANDSP_LA): $(TIFF_LA) $(SPANDSP_DIR) $(SPANDSP_DIR)/.update + cd $(SPANDSP_BUILDDIR) && $(MAKE) -j1 + $(TOUCH_TARGET) + +$(TIFF_LA): $(TIFF_DIR) $(TIFF_DIR)/.update + cd $(TIFF_BUILDDIR) && $(MAKE) -j1 + $(TOUCH_TARGET) diff --git a/src/mod/endpoints/mod_h323/bugs b/src/mod/endpoints/mod_h323/bugs index 813c5c4c3a..ae2e0f1864 100644 --- a/src/mod/endpoints/mod_h323/bugs +++ b/src/mod/endpoints/mod_h323/bugs @@ -1,13 +1 @@ -faststart and codecs v CallProceeding due to h323plus, grep "Very Frustrating - S.H." in h323plus -source and uncomment commented lines. - - -exploration form developer of h323plus: - -Yes that should be mera. - -The problem is that Callproceeding does not always come from the remote it -may be generated by the gatekeeper. MERA where sending fast start elements -in the Call proceeding and connect. The call proceeding where not valid and -causing the media to fail. Normally (although valid) EP's do not set Fast -Start in Call proceeding so the code was disabled to resolve the MERA issue. +seems none for now \ No newline at end of file diff --git a/src/mod/endpoints/mod_h323/changes.txt b/src/mod/endpoints/mod_h323/changes.txt index 4f75aef8b4..ff99e50bd6 100644 --- a/src/mod/endpoints/mod_h323/changes.txt +++ b/src/mod/endpoints/mod_h323/changes.txt @@ -1,3 +1,6 @@ +make sure dtmfinband gets initialized +make gk-identifier and gk-interface settings optional (documentation sayed that about gk-identifier already) +fix race condition on destroying signaling thread in h323 library Adds an extra switch_rtp_destroy or switch_rtp_release_port when a session ends - to make sure the port is returned to FS. thx to Peter Olsson. fix issues with Progress message type if pre_answer enabled diff --git a/src/mod/endpoints/mod_h323/h323.conf.xml b/src/mod/endpoints/mod_h323/h323.conf.xml index bf5929008b..21bd80480c 100644 --- a/src/mod/endpoints/mod_h323/h323.conf.xml +++ b/src/mod/endpoints/mod_h323/h323.conf.xml @@ -9,7 +9,7 @@ - + diff --git a/src/mod/endpoints/mod_h323/mod_h323.cpp b/src/mod/endpoints/mod_h323/mod_h323.cpp index 44295f618f..985f6bb375 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.cpp +++ b/src/mod/endpoints/mod_h323/mod_h323.cpp @@ -1,9 +1,12 @@ /* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II + * H323 endpoint interface for Freeswitch Modular Media Switching Software Library / + * Soft-Switch Application * * Version: MPL 1.1 * + * Copyright (c) 2010 Ilnitskiy Mixim (max.h323@gmail.com) + * Copyright (c) 2010 Georgiewskiy Yuriy (bottleman@icf.org.ru) + * * 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 @@ -14,6 +17,12 @@ * for the specific language governing rights and limitations under the * License. * + * Contributor(s): + * Jan Willamowius. + * + * + * + * * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is @@ -24,7 +33,7 @@ * * mod_h323.cpp -- H323 endpoint * - * Version 0.0.56 + * Version 0.0.57 */ //#define DEBUG_RTP_PACKETS @@ -215,6 +224,7 @@ class FSTrace : public ostream { public: Buffer() { + // leave 2 chars room at end: 1 for overflow char and1 for \0 setg(buffer, buffer, &buffer[sizeof(buffer)-2]); setp(buffer, &buffer[sizeof(buffer)-2]); } @@ -432,8 +442,8 @@ bool FSH323EndPoint::Initialise(switch_loadable_module_interface_t *iface) } } - if (!m_gkAddress.IsEmpty() && !m_gkIdentifer.IsEmpty() && !m_gkInterface.IsEmpty()) { - m_thread = new FSGkRegThread(this,&m_gkAddress,&m_gkIdentifer,&m_gkInterface,m_gkretry); + if (!m_gkAddress.IsEmpty()) { + m_thread = new FSGkRegThread(this, &m_gkAddress, &m_gkIdentifer, &m_gkInterface, m_gkretry); m_thread->SetAutoDelete(); m_thread->Resume(); } @@ -584,6 +594,7 @@ FSH323EndPoint::FSH323EndPoint() :m_faststart(true) ,m_h245tunneling(true) ,m_h245insetup(true) + ,m_dtmfinband(false) ,m_thread(NULL) ,m_stop_gk(false) ,m_fax_old_asn(false) @@ -708,6 +719,7 @@ FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* tran h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_alloc(m_fsSession, sizeof(*tech_pvt)); tech_pvt->me = this; + tech_pvt->active_connection = true; switch_core_session_set_private(m_fsSession, tech_pvt); switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(m_fsSession)); @@ -748,8 +760,9 @@ FSH323Connection::~FSH323Connection() } else if (m_RTPlocalPort) { switch_rtp_release_port((const char *)m_RTPlocalIP.AsString(), m_RTPlocalPort); } - + tech_pvt->me = NULL; + tech_pvt->active_connection = false; // switch_mutex_unlock(tech_pvt->h323_mutex); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n"); } @@ -2387,6 +2400,9 @@ static switch_status_t on_hangup(switch_core_session_t *session) switch_mutex_lock(tech_pvt->h323_mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n"); switch_mutex_unlock(tech_pvt->h323_mutex); - + while (tech_pvt->active_connection){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Wait clear h323 connection\n"); + h_timer(1); + } return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_h323/mod_h323.h b/src/mod/endpoints/mod_h323/mod_h323.h index 5477f9aa59..3a0d7aa235 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.h +++ b/src/mod/endpoints/mod_h323/mod_h323.h @@ -1,9 +1,12 @@ /* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2011, Anthony Minessale II + * H323 endpoint interface for Freeswitch Modular Media Switching Software Library / + * Soft-Switch Application * * Version: MPL 1.1 * + * Copyright (c) 2010 Ilnitskiy Mixim (max.h323@gmail.com) + * Copyright (c) 2010 Georgiewskiy Yuriy (bottleman@icf.org.ru) + * * 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 @@ -14,6 +17,11 @@ * for the specific language governing rights and limitations under the * License. * + * Contributor(s): + * + * + * + * * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is @@ -24,7 +32,8 @@ * * mod_h323.h -- H323 endpoint * - */ + * Version 0.0.57 +*/ #if defined(__GNUC__) && defined(HAVE_VISIBILITY) #pragma GCC visibility push(default) @@ -184,6 +193,7 @@ typedef struct { switch_mutex_t *h323_io_mutex; FSH323Connection *me; + bool active_connection; char *token; } h323_private_t; diff --git a/src/mod/endpoints/mod_khomp/tools/getk3l.sh b/src/mod/endpoints/mod_khomp/tools/getk3l.sh index 57364cdd7e..59e3f4b5e3 100755 --- a/src/mod/endpoints/mod_khomp/tools/getk3l.sh +++ b/src/mod/endpoints/mod_khomp/tools/getk3l.sh @@ -41,28 +41,25 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ############################################################################### +K3L_FILE="k3l_2.1_client.sh" +PARAM="0" -clean() +if [ "$1" ] +then + PARAM=$1 +fi + +help() { - printf "$1" - exit 1 + echo "Usage: getk3l.sh [OPTION]" + echo + echo " -h, --help print this help" + echo " -d, --download only download the k3l package withou doing the installation" + echo } -if [ `whoami` != 'root' ] -then - clean "Need to be root\n" -fi - -#if [ "w$FREESWITCH_PATH" == "w" ] -#then -# clean "FreeSWITCH source PATH is needed: \n\tSet \"FREESWITCH_PATH=\"\n" -#fi - -if ! which 'kserver' &> /dev/null -then - echo "k3l will be installed" - K3L_FILE="k3l_2.1_client.sh" - +download() +{ if [ "w`uname -m | grep x86_64`" == "w" ] then echo "Downloading i686 package" @@ -71,23 +68,49 @@ then echo "Downloading x86_64 package" wget -t15 -c --progress=bar:force -O $K3L_FILE.gz http://www.khomp.com.br/binaries/softpbx/freeswitch/k3l_2.1_client_x86-64.sh.gz fi +} - gunzip $K3L_FILE.gz - chmod 0755 $K3L_FILE +clean() +{ + printf "$1" + exit 1 +} - (./$K3L_FILE) || clean "Error on k3l install\n" - - rm $K3L_FILE -fi +install() +{ + if [ `whoami` != 'root' ] + then + clean "Need to be root to install !\n" + exit 1 + fi -if [ "w`kserver --version | grep 2.1`" == "w" ] + if ! which 'kserver' &> /dev/null + then + download + gunzip $K3L_FILE.gz + chmod 0755 $K3L_FILE + (./$K3L_FILE) || clean "Error on k3l install\n" + rm $K3L_FILE + fi +} + +if [ $PARAM == '--help' -o $PARAM == '-h' ] then - clean "k3l version 2.1 must be installed: \n\tUninstall the old version of k3l and try again\n" + help + exit 0 +elif [ $PARAM == '--download' -o $PARAM == '-d' ] +then + download + exit 0 +else + echo "k3l will be installed" + install + + if [ "w`kserver --version | grep 2.1`" == "w" ] + then + clean "k3l version 2.1 must be installed: \n\tUninstall the old version of k3l and try again\n" + exit 1 + fi + + echo "Successfully installed!" fi - -#make || clean "Error on compilation\n" - -#make install || clean "Error on installation\n" - -echo "Successfully installed!" - diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index be9b4994d6..8fb8384e6b 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -48,7 +48,7 @@ typedef enum { TFLAG_LINKED = (1 << 0), TFLAG_OUTBOUND = (1 << 1), TFLAG_WRITE = (1 << 2), - TFLAG_CNG = (1 << 3), + TFLAG_USEME = (1 << 3), TFLAG_BRIDGE = (1 << 4), TFLAG_BOWOUT = (1 << 5), TFLAG_BLEG = (1 << 6), @@ -158,7 +158,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses tech_pvt->cng_frame.data = tech_pvt->cng_databuf; tech_pvt->cng_frame.buflen = sizeof(tech_pvt->cng_databuf); - //switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); + tech_pvt->cng_frame.datalen = 2; tech_pvt->bowout_frame_count = (tech_pvt->read_codec.implementation->actual_samples_per_second / @@ -297,12 +297,10 @@ static switch_status_t channel_on_init(switch_core_session_t *session) static void do_reset(private_t *tech_pvt) { switch_clear_flag_locked(tech_pvt, TFLAG_WRITE); - switch_set_flag_locked(tech_pvt, TFLAG_CNG); switch_mutex_lock(tech_pvt->mutex); if (tech_pvt->other_tech_pvt) { switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE); - switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_CNG); } switch_mutex_unlock(tech_pvt->mutex); } @@ -446,12 +444,6 @@ static switch_status_t channel_kill_channel(switch_core_session_t *session, int switch (sig) { case SWITCH_SIG_BREAK: - switch_set_flag_locked(tech_pvt, TFLAG_CNG); - switch_mutex_lock(tech_pvt->mutex); - if (tech_pvt->other_tech_pvt) { - switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_CNG); - } - switch_mutex_unlock(tech_pvt->mutex); break; case SWITCH_SIG_KILL: switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); @@ -583,18 +575,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch tech_pvt->write_frame->codec = &tech_pvt->read_codec; *frame = tech_pvt->write_frame; tech_pvt->packet_count++; - switch_clear_flag_locked(tech_pvt, TFLAG_CNG); switch_clear_flag(tech_pvt->write_frame, SFF_CNG); } else { - switch_set_flag(tech_pvt, TFLAG_CNG); - } - - if (switch_test_flag(tech_pvt, TFLAG_CNG)) { *frame = &tech_pvt->cng_frame; tech_pvt->cng_frame.codec = &tech_pvt->read_codec; tech_pvt->cng_frame.datalen = tech_pvt->read_codec.implementation->decoded_bytes_per_packet; switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); - switch_clear_flag_locked(tech_pvt, TFLAG_CNG); } @@ -613,6 +599,17 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch return status; } +static void clear_queue(private_t *tech_pvt) +{ + void *pop; + + while (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { + switch_frame_t *frame = (switch_frame_t *) pop; + switch_frame_free(&frame); + } +} + + static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) { switch_channel_t *channel = NULL; @@ -626,7 +623,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc 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) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { + (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { switch_core_timer_sync(&tech_pvt->timer); switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer); return SWITCH_STATUS_SUCCESS; @@ -672,23 +669,27 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc if (switch_test_flag(tech_pvt, TFLAG_LINKED) && tech_pvt->other_tech_pvt) { switch_frame_t *clone; - + if (frame->codec->implementation != tech_pvt->write_codec.implementation) { /* change codecs to match */ tech_init(tech_pvt, session, frame->codec); tech_init(tech_pvt->other_tech_pvt, tech_pvt->other_session, frame->codec); } - if (switch_queue_size(tech_pvt->other_tech_pvt->frame_queue) < FRAME_QUEUE_LEN) { - if (switch_frame_dup(frame, &clone) != SWITCH_STATUS_SUCCESS) { - abort(); - } - if (switch_queue_trypush(tech_pvt->other_tech_pvt->frame_queue, clone) != SWITCH_STATUS_SUCCESS) { - switch_frame_free(&clone); - } + if (switch_frame_dup(frame, &clone) != SWITCH_STATUS_SUCCESS) { + abort(); + } + + if ((status = switch_queue_trypush(tech_pvt->other_tech_pvt->frame_queue, clone)) != SWITCH_STATUS_SUCCESS) { + clear_queue(tech_pvt->other_tech_pvt); + status = switch_queue_trypush(tech_pvt->other_tech_pvt->frame_queue, clone); + } + if (status == SWITCH_STATUS_SUCCESS) { switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE); + } else { + switch_frame_free(&clone); } status = SWITCH_STATUS_SUCCESS; @@ -747,22 +748,13 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s case SWITCH_MESSAGE_INDICATE_UNBRIDGE: case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: { - void *pop; done = 1; - while (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { - switch_frame_t *frame = (switch_frame_t *) pop; - switch_frame_free(&frame); - } - - while (switch_queue_trypop(tech_pvt->other_tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { - switch_frame_t *frame = (switch_frame_t *) pop; - switch_frame_free(&frame); - } - + clear_queue(tech_pvt); + clear_queue(tech_pvt->other_tech_pvt); switch_core_timer_sync(&tech_pvt->timer); - + switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer); } break; default: diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index c710fc352a..8564a771e5 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -2415,7 +2415,7 @@ SWITCH_STANDARD_API(pa_cmd) } else if (!strcmp(action, "call")) { switch_snprintf(cmd_buf, sizeof(cmd_buf), "call %s", wcmd); cmd = cmd_buf; - } else if (!strcmp(action, "hangup") || !strcmp(action, "list") || !strcmp(action, "answer")) { + } else if (!strcmp(action, "hangup") || !strcmp(action, "list") || !strcmp(action, "devlist") || !strcmp(action, "answer")) { cmd = action; } } @@ -2543,6 +2543,7 @@ SWITCH_STANDARD_API(pa_cmd) " " " " " " + "
" " " " " " " diff --git a/src/mod/endpoints/mod_portaudio/pablio.c b/src/mod/endpoints/mod_portaudio/pablio.c index b994d21c2a..05fdf0f280 100644 --- a/src/mod/endpoints/mod_portaudio/pablio.c +++ b/src/mod/endpoints/mod_portaudio/pablio.c @@ -251,7 +251,7 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, PABLIO_Stream *aStream; long numFrames; //long numBytes; - int channels = 1; + //int channels = 1; if (!(inputParameters || outputParameters)) { return -1; @@ -262,11 +262,13 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, switch_assert(aStream); memset(aStream, 0, sizeof(PABLIO_Stream)); + /* if (inputParameters) { channels = inputParameters->channelCount; } else if (outputParameters) { channels = outputParameters->channelCount; } + */ numFrames = RoundUpToNextPowerOf2(samples_per_packet * 5); aStream->bytesPerFrame = bytesPerSample; diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index b05806b8d9..3879cca7d4 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -58,7 +58,10 @@ static char devices_sql[] = " type INTEGER,\n" " max_streams INTEGER,\n" " port INTEGER,\n" - " codec_string VARCHAR(255)\n" + " codec_string VARCHAR(255),\n" + " headset INTEGER,\n" + " handset INTEGER,\n" + " speaker INTEGER\n" ");\n"; static char lines_sql[] = @@ -459,7 +462,6 @@ uint32_t skinny_line_get_state(listener_t *listener, uint32_t line_instance, uin switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force) { - int ms; switch_status_t status = SWITCH_STATUS_SUCCESS; int resetting = 0; @@ -539,7 +541,7 @@ switch_status_t skinny_tech_set_codec(private_t *tech_pvt, int force) } tech_pvt->read_frame.rate = tech_pvt->rm_rate; - ms = tech_pvt->write_codec.implementation->microseconds_per_packet / 1000; + //ms = tech_pvt->write_codec.implementation->microseconds_per_packet / 1000; if (!switch_core_codec_ready(&tech_pvt->read_codec)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -877,7 +879,6 @@ switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_ { switch_channel_t *channel = switch_core_session_get_channel(session); private_t *tech_pvt = switch_core_session_get_private(session); - int payload = 0; while (!(tech_pvt->read_codec.implementation && switch_rtp_ready(tech_pvt->rtp_session))) { if (switch_channel_ready(channel)) { @@ -905,7 +906,7 @@ switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_ return SWITCH_STATUS_FALSE; } - payload = tech_pvt->read_frame.payload; + //payload = tech_pvt->read_frame.payload; if (switch_rtp_has_dtmf(tech_pvt->rtp_session)) { switch_dtmf_t dtmf = { 0 }; @@ -1317,6 +1318,9 @@ static int dump_device_callback(void *pArg, int argc, char **argv, char **column char *max_streams = argv[5]; char *port = argv[6]; char *codec_string = argv[7]; + char *headset = argv[8]; + char *handset = argv[9]; + char *speaker = argv[10]; const char *line = "================================================================================================="; stream->write_function(stream, "%s\n", line); @@ -1329,6 +1333,12 @@ static int dump_device_callback(void *pArg, int argc, char **argv, char **column stream->write_function(stream, "MaxStreams \t%s\n", max_streams); stream->write_function(stream, "Port \t%s\n", port); stream->write_function(stream, "Codecs \t%s\n", codec_string); + stream->write_function(stream, "HeadsetId \t%s\n", headset); + stream->write_function(stream, "Headset \t%s\n", skinny_accessory_state2str(atoi(headset))); + stream->write_function(stream, "HandsetId \t%s\n", handset); + stream->write_function(stream, "Handset \t%s\n", skinny_accessory_state2str(atoi(handset))); + stream->write_function(stream, "SpeakerId \t%s\n", speaker); + stream->write_function(stream, "Speaker \t%s\n", skinny_accessory_state2str(atoi(speaker))); stream->write_function(stream, "%s\n", line); return 0; @@ -1337,7 +1347,7 @@ static int dump_device_callback(void *pArg, int argc, char **argv, char **column switch_status_t dump_device(skinny_profile_t *profile, const char *device_name, switch_stream_handle_t *stream) { char *sql; - if ((sql = switch_mprintf("SELECT name, user_id, instance, ip, type, max_streams, port, codec_string " + if ((sql = switch_mprintf("SELECT name, user_id, instance, ip, type, max_streams, port, codec_string, headset, handset, speaker " "FROM skinny_devices WHERE name='%s'", device_name))) { skinny_execute_sql_callback(profile, profile->sql_mutex, sql, dump_device_callback, stream); @@ -1916,10 +1926,10 @@ static switch_status_t load_skinny_config(void) switch_odbc_handle_exec(profile->master_odbc, active_lines_sql, NULL, NULL); } else { if ((db = switch_core_db_open_file(profile->dbname))) { - switch_core_db_test_reactive(db, "SELECT * FROM skinny_devices", NULL, devices_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_lines", NULL, lines_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_buttons", NULL, buttons_sql); - switch_core_db_test_reactive(db, "SELECT * FROM skinny_active_lines", NULL, active_lines_sql); + switch_core_db_test_reactive(db, "SELECT headset FROM skinny_devices", "DROP TABLE skinny_devices", devices_sql); + switch_core_db_test_reactive(db, "SELECT * FROM skinny_lines", "DROP TABLE skinny_lines", lines_sql); + switch_core_db_test_reactive(db, "SELECT * FROM skinny_buttons", "DROP TABLE skinny_buttons", buttons_sql); + switch_core_db_test_reactive(db, "SELECT * FROM skinny_active_lines", "DROP TABLE skinny_active_lines", active_lines_sql); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n"); continue; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 8f8911f2a7..1eed692157 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -178,7 +178,7 @@ struct PACKED soft_key_event_message { /* HeadsetStatusMessage */ #define HEADSET_STATUS_MESSAGE 0x002B struct PACKED headset_status_message { - uint32_t mode; + uint32_t mode; /* 1=HeadsetOn; 2=HeadsetOff */ }; /* RegisterAvailableLinesMessage */ @@ -234,6 +234,23 @@ struct PACKED extended_data_message { #define DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE 0x0042 /* See struct PACKED extended_data_message */ +/* DialedPhoneBookMessage */ +#define DIALED_PHONE_BOOK_MESSAGE 0x0048 +struct PACKED dialed_phone_book_message { + uint32_t number_index; /* must be shifted 4 bits right */ + uint32_t line_instance; + uint32_t unknown; + char phone_number[256]; +}; + +/* AccessoryStatusMessage */ +#define ACCESSORY_STATUS_MESSAGE 0x0049 +struct PACKED accessory_status_message { + uint32_t accessory_id; + uint32_t accessory_status; + uint32_t unknown; +}; + /* RegisterAckMessage */ #define REGISTER_ACK_MESSAGE 0x0081 struct PACKED register_ack_message { @@ -507,7 +524,7 @@ struct PACKED display_prompt_status_message { }; /* ClearPromptStatusMessage */ -#define CLEAR_PROMPT_STATUS_MESSAGE 0x0113 +#define CLEAR_PROMPT_STATUS_MESSAGE 0x0113 struct PACKED clear_prompt_status_message { uint32_t line_instance; uint32_t call_id; @@ -573,6 +590,15 @@ struct PACKED service_url_stat_res_message { #define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F /* See struct PACKED extended_data_message */ +/* DialedPhoneBookAckMessage */ +#define DIALED_PHONE_BOOK_ACK_MESSAGE 0x0152 +struct PACKED dialed_phone_book_ack_message { + uint32_t number_index; /* must be shifted 4 bits right */ + uint32_t line_instance; + uint32_t unknown; + uint32_t unknown2; +}; + /* XMLAlarmMessage */ #define XML_ALARM_MESSAGE 0x015A @@ -614,6 +640,8 @@ union skinny_data { 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 dialed_phone_book_message dialed_phone_book; + struct accessory_status_message accessory_status; struct register_ack_message reg_ack; struct start_tone_message start_tone; struct stop_tone_message stop_tone; @@ -651,6 +679,7 @@ union skinny_data { 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 dialed_phone_book_ack_message dialed_phone_book_ack; struct data_message data; struct extended_data_message extended_data; diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index dac75facd7..f6887060fc 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -588,14 +588,12 @@ switch_call_cause_t skinny_ring_lines(private_t *tech_pvt, switch_core_session_t switch_status_t skinny_session_ring_out(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); send_start_tone(listener, SKINNY_TONE_ALERT, 0, line_instance, tech_pvt->call_id); @@ -732,14 +730,12 @@ switch_status_t skinny_session_start_media(switch_core_session_t *session, liste switch_status_t skinny_session_hold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); skinny_session_stop_media(session, listener, line_instance); @@ -760,17 +756,15 @@ switch_status_t skinny_session_hold_line(switch_core_session_t *session, listene switch_status_t skinny_session_unhold_line(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); - skinny_hold_active_calls(listener); + skinny_hold_active_calls(listener); send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id); send_set_speaker_mode(listener, SKINNY_SPEAKER_ON); send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT, 0xffff); @@ -825,14 +819,12 @@ switch_status_t skinny_session_transfer(switch_core_session_t *session, listener switch_status_t skinny_session_stop_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { - switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_assert(session); switch_assert(listener); switch_assert(listener->profile); - channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); switch_clear_flag_locked(tech_pvt, TFLAG_IO); @@ -1773,7 +1765,6 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn uint32_t call_id = 0; switch_core_session_t *session = NULL; switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; skinny_check_data_length(request, sizeof(request->data.soft_key_event.event)); @@ -1790,7 +1781,6 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn break; case SOFTKEY_NEWCALL: status = skinny_create_incoming_session(listener, &line_instance, &session); - tech_pvt = switch_core_session_get_private(session); skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); break; @@ -1874,13 +1864,10 @@ switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request) { skinny_message_t *message; - skinny_profile_t *profile; switch_assert(listener->profile); switch_assert(listener->device_name); - profile = listener->profile; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template)); message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE; message->length = 4 + sizeof(message->data.soft_key_template); @@ -1900,9 +1887,20 @@ switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, sk switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request) { + char *sql; + skinny_check_data_length(request, sizeof(request->data.headset_status)); - /* Nothing to do */ + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET headset=%d WHERE name='%s' and instance=%d", + (request->data.headset_status.mode==1) ? SKINNY_ACCESSORY_STATE_OFFHOOK : SKINNY_ACCESSORY_STATE_ONHOOK, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + return SWITCH_STATUS_SUCCESS; } @@ -2012,6 +2010,66 @@ switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_dialed_phone_book_message(listener_t *listener, skinny_message_t *request) +{ + skinny_message_t *message; + + skinny_check_data_length(request, sizeof(request->data.dialed_phone_book)); + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.dialed_phone_book_ack)); + message->type = DIALED_PHONE_BOOK_ACK_MESSAGE; + message->length = 4 + sizeof(message->data.dialed_phone_book_ack); + message->data.dialed_phone_book_ack.number_index = request->data.dialed_phone_book.number_index; + message->data.dialed_phone_book_ack.line_instance = request->data.dialed_phone_book.line_instance; + message->data.dialed_phone_book_ack.unknown = request->data.dialed_phone_book.unknown; + message->data.dialed_phone_book_ack.unknown2 = 0; + + return SWITCH_STATUS_SUCCESS; +} +switch_status_t skinny_handle_accessory_status_message(listener_t *listener, skinny_message_t *request) +{ + char *sql; + + skinny_check_data_length(request, sizeof(request->data.accessory_status)); + + switch(request->data.accessory_status.accessory_id) { + case SKINNY_ACCESSORY_HEADSET: + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET headset=%d WHERE name='%s' and instance=%d", + request->data.accessory_status.accessory_status, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + break; + case SKINNY_ACCESSORY_HANDSET: + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET handset=%d WHERE name='%s' and instance=%d", + request->data.accessory_status.accessory_status, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + break; + case SKINNY_ACCESSORY_SPEAKER: + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET speaker=%d WHERE name='%s' and instance=%d", + request->data.accessory_status.accessory_status, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(listener->profile, sql, listener->profile->sql_mutex); + switch_safe_free(sql); + } + break; + } + + return SWITCH_STATUS_SUCCESS; +} switch_status_t skinny_handle_xml_alarm(listener_t *listener, skinny_message_t *request) { @@ -2041,8 +2099,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re listener->device_name, listener->device_instance); } if(zstr(listener->device_name) && request->type != REGISTER_MESSAGE && request->type != ALARM_MESSAGE && request->type != XML_ALARM_MESSAGE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Device should send a register message first.\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Device should send a register message first. Received %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); return SWITCH_STATUS_FALSE; } switch(request->type) { @@ -2106,11 +2164,15 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_extended_data_message(listener, request); case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE: return skinny_handle_extended_data_message(listener, request); + case DIALED_PHONE_BOOK_MESSAGE: + return skinny_handle_dialed_phone_book_message(listener, request); + case ACCESSORY_STATUS_MESSAGE: + return skinny_handle_accessory_status_message(listener, request); case XML_ALARM_MESSAGE: return skinny_handle_xml_alarm(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); + "Unhandled %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); return SWITCH_STATUS_SUCCESS; } } diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index e8e56568b3..59bb4a1f2f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -35,223 +35,246 @@ /* Translation tables */ struct skinny_table SKINNY_MESSAGE_TYPES[] = { - {"KeepAliveMessage", KEEP_ALIVE_MESSAGE}, - {"RegisterMessage", REGISTER_MESSAGE}, - {"PortMessage", PORT_MESSAGE}, - {"KeypadButtonMessage", KEYPAD_BUTTON_MESSAGE}, - {"EnblocCallMessage", ENBLOC_CALL_MESSAGE}, - {"StimulusMessage", STIMULUS_MESSAGE}, - {"OffHookMessage", OFF_HOOK_MESSAGE}, - {"OnHookMessage", ON_HOOK_MESSAGE}, - {"ForwardStatReqMessage", FORWARD_STAT_REQ_MESSAGE}, - {"SpeedDialStatReqMessage", SPEED_DIAL_STAT_REQ_MESSAGE}, - {"LineStatReqMessage", LINE_STAT_REQ_MESSAGE}, - {"ConfigStatReqMessage", CONFIG_STAT_REQ_MESSAGE}, - {"TimeDateReqMessage", TIME_DATE_REQ_MESSAGE}, - {"ButtonTemplateReqMessage", BUTTON_TEMPLATE_REQ_MESSAGE}, - {"VersionReqMessage", VERSION_REQ_MESSAGE}, - {"CapabilitiesReqMessage", CAPABILITIES_RES_MESSAGE}, - {"AlarmMessage", ALARM_MESSAGE}, - {"OpenReceiveChannelAckMessage", OPEN_RECEIVE_CHANNEL_ACK_MESSAGE}, - {"SoftKeySetReqMessage", SOFT_KEY_SET_REQ_MESSAGE}, - {"SoftKeyEventMessage", SOFT_KEY_EVENT_MESSAGE}, - {"UnregisterMessage", UNREGISTER_MESSAGE}, - {"SoftKeyTemplateReqMessage", SOFT_KEY_TEMPLATE_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}, - {"SetRingerMessage", SET_RINGER_MESSAGE}, - {"SetLampMessage", SET_LAMP_MESSAGE}, - {"SetSpeakerModeMessage", SET_SPEAKER_MODE_MESSAGE}, - {"StartMediaTransmissionMessage", START_MEDIA_TRANSMISSION_MESSAGE}, - {"StopMediaTransmissionMessage", STOP_MEDIA_TRANSMISSION_MESSAGE}, - {"CallInfoMessage", CALL_INFO_MESSAGE}, - {"ForwardStatMessage", FORWARD_STAT_MESSAGE}, - {"SpeedDialStatResMessage", SPEED_DIAL_STAT_RES_MESSAGE}, - {"LineStatResMessage", LINE_STAT_RES_MESSAGE}, - {"ConfigStatResMessage", CONFIG_STAT_RES_MESSAGE}, - {"DefineTimeDateMessage", DEFINE_TIME_DATE_MESSAGE}, - {"ButtonTemplateResMessage", BUTTON_TEMPLATE_RES_MESSAGE}, - {"VersionMessage", VERSION_MESSAGE}, - {"CapabilitiesReqMessage", CAPABILITIES_REQ_MESSAGE}, - {"RegisterRejectMessage", REGISTER_REJECT_MESSAGE}, - {"ResetMessage", RESET_MESSAGE}, - {"KeepAliveAckMessage", KEEP_ALIVE_ACK_MESSAGE}, - {"OpenReceiveChannelMessage", OPEN_RECEIVE_CHANNEL_MESSAGE}, - {"CloseReceiveChannelMessage", CLOSE_RECEIVE_CHANNEL_MESSAGE}, - {"SoftKeyTemplateResMessage", SOFT_KEY_TEMPLATE_RES_MESSAGE}, - {"SoftKeySetResMessage", SOFT_KEY_SET_RES_MESSAGE}, - {"SelectSoftKeysMessage", SELECT_SOFT_KEYS_MESSAGE}, - {"CallStateMessage", CALL_STATE_MESSAGE}, - {"DisplayPromptStatusMessage", DISPLAY_PROMPT_STATUS_MESSAGE}, - {"ClearPromptStatusMessage", CLEAR_PROMPT_STATUS_MESSAGE}, - {"ActivateCallPlaneMessage", ACTIVATE_CALL_PLANE_MESSAGE}, - {"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}, - {"XMLAlarmMessage", XML_ALARM_MESSAGE}, - {NULL, 0} + {KEEP_ALIVE_MESSAGE, "KeepAliveMessage"}, + {REGISTER_MESSAGE, "RegisterMessage"}, + {PORT_MESSAGE, "PortMessage"}, + {KEYPAD_BUTTON_MESSAGE, "KeypadButtonMessage"}, + {ENBLOC_CALL_MESSAGE, "EnblocCallMessage"}, + {STIMULUS_MESSAGE, "StimulusMessage"}, + {OFF_HOOK_MESSAGE, "OffHookMessage"}, + {ON_HOOK_MESSAGE, "OnHookMessage"}, + { FORWARD_STAT_REQ_MESSAGE, "ForwardStatReqMessage"}, + {SPEED_DIAL_STAT_REQ_MESSAGE, "SpeedDialStatReqMessage"}, + {LINE_STAT_REQ_MESSAGE, "LineStatReqMessage"}, + {CONFIG_STAT_REQ_MESSAGE, "ConfigStatReqMessage"}, + {TIME_DATE_REQ_MESSAGE, "TimeDateReqMessage"}, + {BUTTON_TEMPLATE_REQ_MESSAGE, "ButtonTemplateReqMessage"}, + {VERSION_REQ_MESSAGE, "VersionReqMessage"}, + {CAPABILITIES_RES_MESSAGE, "CapabilitiesReqMessage"}, + {ALARM_MESSAGE, "AlarmMessage"}, + {OPEN_RECEIVE_CHANNEL_ACK_MESSAGE, "OpenReceiveChannelAckMessage"}, + {SOFT_KEY_SET_REQ_MESSAGE, "SoftKeySetReqMessage"}, + {SOFT_KEY_EVENT_MESSAGE, "SoftKeyEventMessage"}, + {UNREGISTER_MESSAGE, "UnregisterMessage"}, + {SOFT_KEY_TEMPLATE_REQ_MESSAGE, "SoftKeyTemplateReqMessage"}, + {HEADSET_STATUS_MESSAGE, "HeadsetStatusMessage"}, + {REGISTER_AVAILABLE_LINES_MESSAGE, "RegisterAvailableLinesMessage"}, + {DEVICE_TO_USER_DATA_MESSAGE, "DeviceToUserDataMessage"}, + {DEVICE_TO_USER_DATA_RESPONSE_MESSAGE, "DeviceToUserDataResponseMessage"}, + {SERVICE_URL_STAT_REQ_MESSAGE, "ServiceUrlStatReqMessage"}, + {FEATURE_STAT_REQ_MESSAGE, "FeatureStatReqMessage"}, + {DEVICE_TO_USER_DATA_VERSION1_MESSAGE, "DeviceToUserDataVersion1Message"}, + {DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE, "DeviceToUserDataResponseVersion1Message"}, + {DIALED_PHONE_BOOK_MESSAGE, "DialedPhoneBookMessage"}, + {ACCESSORY_STATUS_MESSAGE, "AccessoryStatusMessage"}, + {REGISTER_ACK_MESSAGE, "RegisterAckMessage"}, + {START_TONE_MESSAGE, "StartToneMessage"}, + {STOP_TONE_MESSAGE, "StopToneMessage"}, + {SET_RINGER_MESSAGE, "SetRingerMessage"}, + {SET_LAMP_MESSAGE, "SetLampMessage"}, + {SET_SPEAKER_MODE_MESSAGE, "SetSpeakerModeMessage"}, + {START_MEDIA_TRANSMISSION_MESSAGE, "StartMediaTransmissionMessage"}, + {STOP_MEDIA_TRANSMISSION_MESSAGE, "StopMediaTransmissionMessage"}, + {CALL_INFO_MESSAGE, "CallInfoMessage"}, + {FORWARD_STAT_MESSAGE, "ForwardStatMessage"}, + {SPEED_DIAL_STAT_RES_MESSAGE, "SpeedDialStatResMessage"}, + {LINE_STAT_RES_MESSAGE, "LineStatResMessage"}, + {CONFIG_STAT_RES_MESSAGE, "ConfigStatResMessage"}, + {DEFINE_TIME_DATE_MESSAGE, "DefineTimeDateMessage"}, + {BUTTON_TEMPLATE_RES_MESSAGE, "ButtonTemplateResMessage"}, + {VERSION_MESSAGE, "VersionMessage"}, + {CAPABILITIES_REQ_MESSAGE, "CapabilitiesReqMessage"}, + {REGISTER_REJECT_MESSAGE, "RegisterRejectMessage"}, + {RESET_MESSAGE, "ResetMessage"}, + {KEEP_ALIVE_ACK_MESSAGE, "KeepAliveAckMessage"}, + {OPEN_RECEIVE_CHANNEL_MESSAGE, "OpenReceiveChannelMessage"}, + {CLOSE_RECEIVE_CHANNEL_MESSAGE, "CloseReceiveChannelMessage"}, + {SOFT_KEY_TEMPLATE_RES_MESSAGE, "SoftKeyTemplateResMessage"}, + {SOFT_KEY_SET_RES_MESSAGE, "SoftKeySetResMessage"}, + {SELECT_SOFT_KEYS_MESSAGE, "SelectSoftKeysMessage"}, + {CALL_STATE_MESSAGE, "CallStateMessage"}, + {DISPLAY_PROMPT_STATUS_MESSAGE, "DisplayPromptStatusMessage"}, + {CLEAR_PROMPT_STATUS_MESSAGE, "ClearPromptStatusMessage"}, + {ACTIVATE_CALL_PLANE_MESSAGE, "ActivateCallPlaneMessage"}, + {UNREGISTER_ACK_MESSAGE, "UnregisterAckMessage"}, + {BACK_SPACE_REQ_MESSAGE, "BackSpaceReqMessage"}, + {DIALED_NUMBER_MESSAGE, "DialedNumberMessage"}, + {USER_TO_DEVICE_DATA_MESSAGE, "UserToDeviceDataMessage"}, + {FEATURE_STAT_RES_MESSAGE, "FeatureResMessage"}, + {DISPLAY_PRI_NOTIFY_MESSAGE, "DisplayPriNotifyMessage"}, + {SERVICE_URL_STAT_RES_MESSAGE, "ServiceUrlStatMessage"}, + {USER_TO_DEVICE_DATA_VERSION1_MESSAGE, "UserToDeviceDataVersion1Message"}, + {DIALED_PHONE_BOOK_ACK_MESSAGE, "DialedPhoneBookAckMessage"}, + {XML_ALARM_MESSAGE, "XMLAlarmMessage"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage") SKINNY_DECLARE_STR2ID(skinny_str2message_type, SKINNY_MESSAGE_TYPES, -1) struct skinny_table SKINNY_DEVICE_TYPES[] = { - {"Cisco 30 SP+", 1}, - {"Cisco 12 SP+", 2}, - {"Cisco 12 SP", 3}, - {"Cisco 12", 4}, - {"Cisco 30 VIP", 5}, - {"Cisco IP Phone 7910", 6}, - {"Cisco IP Phone 7960", 7}, - {"Cisco IP Phone 7940", 8}, - {"Cisco IP Phone 7935", 9}, - {"Cisco ATA 186", 12}, - {"Cisco IP Phone CP-7962G", 404}, - {"Cisco IP Phone CP-7965G", 436}, - {"Cisco IP Phone CP-7961G", 30018}, - {"Cisco IP Phone 7936", 30019}, - {NULL, 0} + {1, "Cisco 30 SP+"}, + {2, "Cisco 12 SP+"}, + {3, "Cisco 12 SP"}, + {4, "Cisco 12"}, + {5, "Cisco 30 VIP"}, + {6, "Cisco IP Phone 7910"}, + {7, "Cisco IP Phone 7960"}, + {8, "Cisco IP Phone 7940"}, + {9, "Cisco IP Phone 7935"}, + {12, "Cisco ATA 186"}, + {365, "Cisco IP Phone CP-7921G"}, + {404, "Cisco IP Phone CP-7962G"}, + {436, "Cisco IP Phone CP-7965G"}, + {30018, "Cisco IP Phone CP-7961G"}, + {30019, "Cisco IP Phone 7936"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_device_type2str, SKINNY_DEVICE_TYPES, "UnknownDeviceType") SKINNY_DECLARE_STR2ID(skinny_str2device_type, SKINNY_DEVICE_TYPES, -1) struct skinny_table SKINNY_RING_TYPES[] = { - {"RingOff", SKINNY_RING_OFF}, - {"RingInside", SKINNY_RING_INSIDE}, - {"RingOutside", SKINNY_RING_OUTSIDE}, - {"RingFeature", SKINNY_RING_FEATURE}, - {NULL, 0} + {SKINNY_RING_OFF, "RingOff"}, + {SKINNY_RING_INSIDE, "RingInside"}, + {SKINNY_RING_OUTSIDE, "RingOutside"}, + {SKINNY_RING_FEATURE, "RingFeature"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_ring_type2str, SKINNY_RING_TYPES, "RingTypeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2ring_type, SKINNY_RING_TYPES, -1) struct skinny_table SKINNY_RING_MODES[] = { - {"RingForever", SKINNY_RING_FOREVER}, - {"RingOnce", SKINNY_RING_ONCE}, - {NULL, 0} + {SKINNY_RING_FOREVER, "RingForever"}, + {SKINNY_RING_ONCE, "RingOnce"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_ring_mode2str, SKINNY_RING_MODES, "RingModeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2ring_mode, SKINNY_RING_MODES, -1) struct skinny_table SKINNY_BUTTONS[] = { - {"Unknown", SKINNY_BUTTON_UNKNOWN}, - {"LastNumberRedial", SKINNY_BUTTON_LAST_NUMBER_REDIAL}, - {"SpeedDial", SKINNY_BUTTON_SPEED_DIAL}, - {"Hold", SKINNY_BUTTON_HOLD}, - {"Transfer", SKINNY_BUTTON_TRANSFER}, - {"Line", SKINNY_BUTTON_LINE}, - {"Voicemail", SKINNY_BUTTON_VOICEMAIL}, - {"Privacy", SKINNY_BUTTON_PRIVACY}, - {"ServiceUrl", SKINNY_BUTTON_SERVICE_URL}, - {"Undefined", SKINNY_BUTTON_UNDEFINED}, - {NULL, 0} + {SKINNY_BUTTON_UNKNOWN, "Unknown"}, + {SKINNY_BUTTON_LAST_NUMBER_REDIAL, "LastNumberRedial"}, + {SKINNY_BUTTON_SPEED_DIAL, "SpeedDial"}, + {SKINNY_BUTTON_HOLD, "Hold"}, + {SKINNY_BUTTON_TRANSFER, "Transfer"}, + {SKINNY_BUTTON_LINE, "Line"}, + {SKINNY_BUTTON_VOICEMAIL, "Voicemail"}, + {SKINNY_BUTTON_PRIVACY, "Privacy"}, + {SKINNY_BUTTON_SERVICE_URL, "ServiceUrl"}, + {SKINNY_BUTTON_UNDEFINED, "Undefined"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_button2str, SKINNY_BUTTONS, "Unknown") SKINNY_DECLARE_STR2ID(skinny_str2button, SKINNY_BUTTONS, -1) struct skinny_table SKINNY_SOFT_KEY_EVENTS[] = { - {"SoftkeyRedial", SOFTKEY_REDIAL}, - {"SoftkeyNewcall", SOFTKEY_NEWCALL}, - {"SoftkeyHold", SOFTKEY_HOLD}, - {"SoftkeyTransfer", SOFTKEY_TRANSFER}, - {"SoftkeyCfwdall", SOFTKEY_CFWDALL}, - {"SoftkeyCfwdbusy", SOFTKEY_CFWDBUSY}, - {"SoftkeyCfwdnoanswer", SOFTKEY_CFWDNOANSWER}, - {"SoftkeyBackspace", SOFTKEY_BACKSPACE}, - {"SoftkeyEndcall", SOFTKEY_ENDCALL}, - {"SoftkeyResume", SOFTKEY_RESUME}, - {"SoftkeyAnswer", SOFTKEY_ANSWER }, - {"SoftkeyInfo", SOFTKEY_INFO}, - {"SoftkeyConfrm", SOFTKEY_CONFRM}, - {"SoftkeyPark", SOFTKEY_PARK}, - {"SoftkeyJoin", SOFTKEY_JOIN}, - {"SoftkeyMeetmeconfrm", SOFTKEY_MEETMECONFRM}, - {"SoftkeyCallpickup", SOFTKEY_CALLPICKUP}, - {"SoftkeyGrpcallpickup", SOFTKEY_GRPCALLPICKUP}, - {"SoftkeyDnd", SOFTKEY_DND}, - {"SoftkeyIdivert", SOFTKEY_IDIVERT}, - {NULL, 0} + {SOFTKEY_REDIAL, "SoftkeyRedial"}, + {SOFTKEY_NEWCALL, "SoftkeyNewcall"}, + {SOFTKEY_HOLD, "SoftkeyHold"}, + {SOFTKEY_TRANSFER, "SoftkeyTransfer"}, + {SOFTKEY_CFWDALL, "SoftkeyCfwdall"}, + {SOFTKEY_CFWDBUSY, "SoftkeyCfwdbusy"}, + {SOFTKEY_CFWDNOANSWER, "SoftkeyCfwdnoanswer"}, + {SOFTKEY_BACKSPACE, "SoftkeyBackspace"}, + {SOFTKEY_ENDCALL, "SoftkeyEndcall"}, + {SOFTKEY_RESUME, "SoftkeyResume"}, + {SOFTKEY_ANSWER , "SoftkeyAnswer"}, + {SOFTKEY_INFO, "SoftkeyInfo"}, + {SOFTKEY_CONFRM, "SoftkeyConfrm"}, + {SOFTKEY_PARK, "SoftkeyPark"}, + {SOFTKEY_JOIN, "SoftkeyJoin"}, + {SOFTKEY_MEETMECONFRM, "SoftkeyMeetmeconfrm"}, + {SOFTKEY_CALLPICKUP, "SoftkeyCallpickup"}, + {SOFTKEY_GRPCALLPICKUP, "SoftkeyGrpcallpickup"}, + {SOFTKEY_DND, "SoftkeyDnd"}, + {SOFTKEY_IDIVERT, "SoftkeyIdivert"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_soft_key_event2str, SKINNY_SOFT_KEY_EVENTS, "SoftkeyUnknown") SKINNY_DECLARE_STR2ID(skinny_str2soft_key_event, SKINNY_SOFT_KEY_EVENTS, 0) struct skinny_table SKINNY_LAMP_MODES[] = { - {"Off", SKINNY_LAMP_OFF}, - {"On", SKINNY_LAMP_ON}, - {"Wink", SKINNY_LAMP_WINK}, - {"Flash", SKINNY_LAMP_FLASH}, - {"Blink", SKINNY_LAMP_BLINK}, - {NULL, 0} + {SKINNY_LAMP_OFF, "Off"}, + {SKINNY_LAMP_ON, "On"}, + {SKINNY_LAMP_WINK, "Wink"}, + {SKINNY_LAMP_FLASH, "Flash"}, + {SKINNY_LAMP_BLINK, "Blink"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_lamp_mode2str, SKINNY_LAMP_MODES, "Unknown") SKINNY_DECLARE_STR2ID(skinny_str2lamp_mode, SKINNY_LAMP_MODES, -1) struct skinny_table SKINNY_SPEAKER_MODES[] = { - {"SpeakerOn", SKINNY_SPEAKER_ON}, - {"SpeakerOff", SKINNY_SPEAKER_OFF}, - {NULL, 0} + {SKINNY_SPEAKER_ON, "SpeakerOn"}, + {SKINNY_SPEAKER_OFF, "SpeakerOff"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_speaker_mode2str, SKINNY_SPEAKER_MODES, "Unknown") SKINNY_DECLARE_STR2ID(skinny_str2speaker_mode, SKINNY_SPEAKER_MODES, -1) struct skinny_table SKINNY_KEY_SETS[] = { - {"KeySetOnHook", SKINNY_KEY_SET_ON_HOOK}, - {"KeySetConnected", SKINNY_KEY_SET_CONNECTED}, - {"KeySetOnHold", SKINNY_KEY_SET_ON_HOLD}, - {"KeySetRingIn", SKINNY_KEY_SET_RING_IN}, - {"KeySetOffHook", SKINNY_KEY_SET_OFF_HOOK}, - {"KeySetConnectedWithTransfer", SKINNY_KEY_SET_CONNECTED_WITH_TRANSFER}, - {"KeySetDigitsAfterDialingFirstDigit", SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT}, - {"KeySetConnectedWithConference", SKINNY_KEY_SET_CONNECTED_WITH_CONFERENCE}, - {"KeySetRingOut", SKINNY_KEY_SET_RING_OUT}, - {"KeySetOffHookWithFeatures", SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES}, - {"KeySetInUseHint", SKINNY_KEY_SET_IN_USE_HINT}, - {NULL, 0} + {SKINNY_KEY_SET_ON_HOOK, "KeySetOnHook"}, + {SKINNY_KEY_SET_CONNECTED, "KeySetConnected"}, + {SKINNY_KEY_SET_ON_HOLD, "KeySetOnHold"}, + {SKINNY_KEY_SET_RING_IN, "KeySetRingIn"}, + {SKINNY_KEY_SET_OFF_HOOK, "KeySetOffHook"}, + {SKINNY_KEY_SET_CONNECTED_WITH_TRANSFER, "KeySetConnectedWithTransfer"}, + {SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT, "KeySetDigitsAfterDialingFirstDigit"}, + {SKINNY_KEY_SET_CONNECTED_WITH_CONFERENCE, "KeySetConnectedWithConference"}, + {SKINNY_KEY_SET_RING_OUT, "KeySetRingOut"}, + {SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES, "KeySetOffHookWithFeatures"}, + {SKINNY_KEY_SET_IN_USE_HINT, "KeySetInUseHint"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_soft_key_set2str, SKINNY_KEY_SETS, "UNKNOWN_SOFT_KEY_SET") SKINNY_DECLARE_STR2ID(skinny_str2soft_key_set, SKINNY_KEY_SETS, -1) struct skinny_table SKINNY_CALL_STATES[] = { - {"OffHook", SKINNY_OFF_HOOK}, - {"OnHook", SKINNY_ON_HOOK}, - {"RingOut", SKINNY_RING_OUT}, - {"RingIn", SKINNY_RING_IN}, - {"Connected", SKINNY_CONNECTED}, - {"Busy", SKINNY_BUSY}, - {"LineInUse", SKINNY_LINE_IN_USE}, - {"Hold", SKINNY_HOLD}, - {"CallWaiting", SKINNY_CALL_WAITING}, - {"CallTransfer", SKINNY_CALL_TRANSFER}, - {"CallPark", SKINNY_CALL_PARK}, - {"Proceed", SKINNY_PROCEED}, - {"InUseRemotely", SKINNY_IN_USE_REMOTELY}, - {"InvalidNumber", SKINNY_INVALID_NUMBER}, - {NULL, 0} + {SKINNY_OFF_HOOK, "OffHook"}, + {SKINNY_ON_HOOK, "OnHook"}, + {SKINNY_RING_OUT, "RingOut"}, + {SKINNY_RING_IN, "RingIn"}, + {SKINNY_CONNECTED, "Connected"}, + {SKINNY_BUSY, "Busy"}, + {SKINNY_LINE_IN_USE, "LineInUse"}, + {SKINNY_HOLD, "Hold"}, + {SKINNY_CALL_WAITING, "CallWaiting"}, + {SKINNY_CALL_TRANSFER, "CallTransfer"}, + {SKINNY_CALL_PARK, "CallPark"}, + {SKINNY_PROCEED, "Proceed"}, + {SKINNY_IN_USE_REMOTELY, "InUseRemotely"}, + {SKINNY_INVALID_NUMBER, "InvalidNumber"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_call_state2str, SKINNY_CALL_STATES, "CallStateUnknown") SKINNY_DECLARE_STR2ID(skinny_str2call_state, SKINNY_CALL_STATES, -1) struct skinny_table SKINNY_DEVICE_RESET_TYPES[] = { - {"DeviceReset", SKINNY_DEVICE_RESET}, - {"DeviceRestart", SKINNY_DEVICE_RESTART}, - {NULL, 0} + {SKINNY_DEVICE_RESET, "DeviceReset"}, + {SKINNY_DEVICE_RESTART, "DeviceRestart"}, + {0, NULL} }; SKINNY_DECLARE_ID2STR(skinny_device_reset_type2str, SKINNY_DEVICE_RESET_TYPES, "DeviceResetTypeUnknown") SKINNY_DECLARE_STR2ID(skinny_str2device_reset_type, SKINNY_DEVICE_RESET_TYPES, -1) +struct skinny_table SKINNY_ACCESSORY_TYPES[] = { + {SKINNY_ACCESSORY_NONE, "AccessoryNone"}, + {SKINNY_ACCESSORY_HEADSET, "Headset"}, + {SKINNY_ACCESSORY_HANDSET, "Handset"}, + {SKINNY_ACCESSORY_SPEAKER, "Speaker"}, + {0, NULL} +}; +SKINNY_DECLARE_ID2STR(skinny_accessory_type2str, SKINNY_ACCESSORY_TYPES, "AccessoryUnknown") +SKINNY_DECLARE_STR2ID(skinny_str2accessory_type, SKINNY_ACCESSORY_TYPES, -1) + +struct skinny_table SKINNY_ACCESSORY_STATES[] = { + {SKINNY_ACCESSORY_STATE_NONE, "AccessoryNoState"}, + {SKINNY_ACCESSORY_STATE_OFFHOOK, "OffHook"}, + {SKINNY_ACCESSORY_STATE_ONHOOK, "OnHook"}, + {0, NULL} +}; +SKINNY_DECLARE_ID2STR(skinny_accessory_state2str, SKINNY_ACCESSORY_STATES, "AccessoryStateUnknown") +SKINNY_DECLARE_STR2ID(skinny_str2accessory_state, SKINNY_ACCESSORY_STATES, -1) + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 00ddf0c74d..383e5bb2b1 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -36,8 +36,8 @@ /* SKINNY TABLES */ /*****************************************************************************/ struct skinny_table { - const char *name; uint32_t id; + const char *name; }; #define SKINNY_DECLARE_ID2STR(func, TABLE, DEFAULT_STR) \ @@ -87,12 +87,12 @@ uint32_t func(const char *str)\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[69]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[72]; 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) -extern struct skinny_table SKINNY_DEVICE_TYPES[15]; +extern struct skinny_table SKINNY_DEVICE_TYPES[16]; const char *skinny_device_type2str(uint32_t id); uint32_t skinny_str2device_type(const char *str); #define SKINNY_PUSH_DEVICE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_DEVICE_TYPES) @@ -248,6 +248,27 @@ const char *skinny_device_reset_type2str(uint32_t id); uint32_t skinny_str2device_reset_type(const char *str); #define SKINNY_PUSH_DEVICE_RESET_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_DEVICE_RESET_TYPES) +enum skinny_accessory_types { + SKINNY_ACCESSORY_NONE = 0x00, + SKINNY_ACCESSORY_HEADSET = 0x01, + SKINNY_ACCESSORY_HANDSET = 0x02, + SKINNY_ACCESSORY_SPEAKER = 0x03 +}; +extern struct skinny_table SKINNY_ACCESSORY_TYPES[5]; +const char *skinny_accessory_type2str(uint32_t id); +uint32_t skinny_str2accessory_type(const char *str); +#define SKINNY_PUSH_ACCESSORY_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_ACCESSORY_TYPES) + +enum skinny_accessory_states { + SKINNY_ACCESSORY_STATE_NONE = 0x00, + SKINNY_ACCESSORY_STATE_OFFHOOK = 0x01, + SKINNY_ACCESSORY_STATE_ONHOOK = 0x02 +}; +extern struct skinny_table SKINNY_ACCESSORY_STATES[4]; +const char *skinny_accessory_state2str(uint32_t id); +uint32_t skinny_str2accessory_state(const char *str); +#define SKINNY_PUSH_ACCESSORY_STATES SKINNY_DECLARE_PUSH_MATCH(SKINNY_ACCESSORY_STATES) + #endif /* _SKINNY_TABLES_H */ /* For Emacs: diff --git a/src/mod/endpoints/mod_skypopen/Makefile.am b/src/mod/endpoints/mod_skypopen/Makefile.am index b572b58e20..ab1909817b 100644 --- a/src/mod/endpoints/mod_skypopen/Makefile.am +++ b/src/mod/endpoints/mod_skypopen/Makefile.am @@ -1,7 +1,24 @@ include $(top_srcdir)/build/modmake.rulesam MODNAME=mod_skypopen + +TIFF_DIR=$(switch_srcdir)/libs/tiff-3.8.2 +TIFF_BUILDDIR=$(switch_builddir)/libs/tiff-3.8.2 +TIFF_LA=$(TIFF_BUILDDIR)/libtiff/libtiff.la + +SPANDSP_DIR=$(switch_srcdir)/libs/spandsp +SPANDSP_BUILDDIR=$(switch_builddir)/libs/spandsp +SPANDSP_LA=$(SPANDSP_BUILDDIR)/src/libspandsp.la + mod_LTLIBRARIES = mod_skypopen.la mod_skypopen_la_SOURCES = mod_skypopen.c skypopen_protocol.c -mod_skypopen_la_CFLAGS = $(AM_CFLAGS) -DSKYPOPEN_C_VER=\"`git log -1 --format="%h" skypopen_protocol.c`\" -DMODSKYPOPEN_C_VER=\"`git log -1 --format="%h" mod_skypopen.c`\" -I../../../../libs/spandsp/src -I../../../..//libs/tiff-3.8.2/libtiff -mod_skypopen_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_skypopen_la_LDFLAGS = -L../../../../libs/spandsp/src -avoid-version -module -no-undefined -shared -lX11 -lspandsp +mod_skypopen_la_CFLAGS = $(AM_CFLAGS) -I$(SPANDSP_DIR)/src -I$(TIFF_DIR)/libtiff -I$(SPANDSP_BUILDDIR)/src -I$(TIFF_BUILDDIR)/libtiff -I. -DSKYPOPEN_C_VER=\"`git log -1 --format="%h" skypopen_protocol.c`\" -DMODSKYPOPEN_C_VER=\"`git log -1 --format="%h" mod_skypopen.c`\" +mod_skypopen_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LA) $(TIFF_LA) +mod_skypopen_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lX11 + +$(SPANDSP_LA): $(TIFF_LA) $(SPANDSP_DIR) $(SPANDSP_DIR)/.update + cd $(SPANDSP_BUILDDIR) && $(MAKE) -j1 + $(TOUCH_TARGET) + +$(TIFF_LA): $(TIFF_DIR) $(TIFF_DIR)/.update + cd $(TIFF_BUILDDIR) && $(MAKE) -j1 + $(TOUCH_TARGET) diff --git a/src/mod/endpoints/mod_skypopen/alsa/alsa-driver-1.0.20-dummy.c b/src/mod/endpoints/mod_skypopen/alsa/alsa-driver-1.0.20-dummy.c deleted file mode 120000 index 1635114f26..0000000000 --- a/src/mod/endpoints/mod_skypopen/alsa/alsa-driver-1.0.20-dummy.c +++ /dev/null @@ -1 +0,0 @@ -./dummy.c \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/README.skypopen_auth b/src/mod/endpoints/mod_skypopen/configs/old-stuff/README.skypopen_auth similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/README.skypopen_auth rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/README.skypopen_auth diff --git a/src/mod/endpoints/mod_skypopen/configs/copy b/src/mod/endpoints/mod_skypopen/configs/old-stuff/copy similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/copy rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/copy diff --git a/src/mod/endpoints/mod_skypopen/configs/create b/src/mod/endpoints/mod_skypopen/configs/old-stuff/create similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/create rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/create diff --git a/src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/README b/src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/README similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/README rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/README diff --git a/src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/multi.sh b/src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/multi.sh similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/multi.sh rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/multi.sh diff --git a/src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/skypopen.conf.xml b/src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/skypopen.conf.xml similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/multiple-instance-same-skype-username/skypopen.conf.xml rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/multiple-instance-same-skype-username/skypopen.conf.xml diff --git a/src/mod/endpoints/mod_skypopen/configs/skypopen_auth.c b/src/mod/endpoints/mod_skypopen/configs/old-stuff/skypopen_auth.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/skypopen_auth.c rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/skypopen_auth.c diff --git a/src/mod/endpoints/mod_skypopen/configs/startskype.sh b/src/mod/endpoints/mod_skypopen/configs/old-stuff/startskype.sh similarity index 100% rename from src/mod/endpoints/mod_skypopen/configs/startskype.sh rename to src/mod/endpoints/mod_skypopen/configs/old-stuff/startskype.sh diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.xml new file mode 100644 index 0000000000..4b72e67eb5 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/shared.xml @@ -0,0 +1,99 @@ + + + + + <_2>00001000A563932E7DE5A581942041A820F8437512A079C7ACB1B73281F191D109521E265BCD38C4133596B834AD9AA1D6BB5E1AC3D59E8675785321F722D39FBFAFB9A24E6482FA3030FFA3692D2C4A53BBCE9DC63F25D10207A20FA969982FEDC1DCC2A7C599071F4735E52AB2E06E34CA232C08B3AA2FB88A0C4A5763E0CD23C3AA37D1D2A7D6EED691EE99BA08BE294F68C24F9AE777DAF294F0AEB8346325A978DC6CF7C210AD11EF3F38111F6D98F388CF41CCBA40ABE9F0D6CBBD3118BA0588344953DF3C5E88B2CCAEDE2E692F320D20EBF16D7DB36156E617C0CC9FB2855D7FDB4C7F8638CC9830E7448D5EAE301A2810277062989841EE679E00E4E277615FEC038DE3A0A20DD7C6A2A00DFBC6A2A00DA6E2B6F404FDC6A2A00DFEC6A2A00DF7FBBB990CF2C6A2A00D8EB4FE8A0C8FB4FE8A0C95C7A6E00CF5FBBB990CD6C7A6E00CD0F896950CCCE2B6F40485CCA2A00DA1D8EEA50DFDFBBB990CA7C7A6E00CA8C7A6E00CA9C7A6E00C97C7A6E00C90B4FE8A0CFE90D59308C290D59308D1E2B6F404C5E2B6F404C6AAF18705C7AAF18705C8AAF18705BBD8EEA50DBCD8EEA50DBDD8EEA50D93CCA2A00D94CCA2A00DEFE2B6F40491B4FE8A0CE2FBBB990CE3FBBB990CBED8EEA50DA0CCA2A00DA1CCA2A00DA6B4FE8A0CA7B4FE8A0CCED8EEA50DA3CCA2A00DA4CCA2A00D84E698AD0DB8C7A6E00CD9E2B6F404E0E2B6F40486E698AD0DFDF896950C0013A60400173D0018DE0200190300AB01F40300449875044518C15F9A278109D4BBAC4E8109D408A6238109D5A63304810904460CC15F9A26303ED408A624303E0047B054004801004980A305004A80E90F004BE0A801004C80A305004D01005CAC02045E5A50FC55465BA050FC55475BA050FC55485BA0C32EFDEE5BA0C32EFDEF5BA0C2A5BC4A5BA0C2A5BC4B5BA0D4BBAC055BA0D4BBAC145BA0D4BBAC215BA0D408A3575BA0D408A37D5BA0D408A37E5BA08275487E5BA0827548425BA00060B817046506CC09A3D6303E04AE018C0125F8D500021A25F9D500011A162102200301220125FFD50025FAD5000C03E4000D2580D6000F060125F8D5000302172105050103080D06010501011C210302060125FCD50025F9D5000A25FDD50025FED5000A0D06020502050119211305020380808080100C05010D0380808080100B25FDD5000C01080005000380808080100D060307010503220101220104AC01BF012597CE002597CE002590CE0019152590CE002597CE000B033C1815210220030122012593CE0014212E2594CE002103030B220125A5CE00030F172103030B22012596CE00142103030B22012597CE00142103030B22012599CE00142103030A220125A5CE00030A1A2590CE002592CE000B031E1B15142103030A220125A4CE000380201D14210303092201259BCE0014210A2594CE002103030B2201259DCE00142103030822012593CE002103012201259ECE001421030306220103022201006800006901006A01006C987504740CC2A5BC4C303ED408A34C303E007828047912CC09A3D3303E82754864303E4E8DB16F303E047DBF010203020800050003020D0B0601030308000500020501030508000500021A03060800050003041A16030508000500021D160C0A0C060203D00F251205020A03020D0A050103D00F0C0A0603010800050003FFFFFFFF0F18030208000500021D141506042512020800050003030D05040C10030205040B0C06050306050505020A0C060603040800050003050800050003E400180C0607050703E400250A0B250A011C0C0A0314100608050303C03E0F03B8171005060388270F03DC0B100508047E5E0380010304080005000B03040D250403E4000F03140D0A2503250203030D0A0B0110060101080005000380020D0302080005000380020D172103010601250A03E4001B210D0501030A03E400250A210303DF002002250A0B0D0F0601050100800180EA49008101E003036F3139352E34362E3235332E3235333A313233353000038201706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B7970653B706F6F6C333D6578747261732E646F776E6C6F6164732E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B7970653B706F6F6C353D2A2E7072656D69756D2E736B7970653B706F6F6C363D2A2E6D756C74696D656469612E736B7970653B706F6F6C373D2A2E6D756C74696D656469612E6D657461636166653B706F6F6C383D2A2E6D756C74696D656469612E6461696C796D6F74696F6E3B706F6F6C393D2A2E6D756C74696D656469612E6D6574616F6D6E69747572653B706F6F6C31303D77686174736E65772E736B7970653B706F6F6C31313D7061792E736B7970653B706F6F6C31323D7365637572652E7061792E736B7970653B706F6F6C31333D2A2E70696373746F72653B706F6F6C31343D2A2E6D796163636F756E742E736B7970653B706F6F6C31353D2A2E62696269743B706F6F6C31363D2A2E70726F6363796265723B706F6F6C31373D747261636B696E672E6F6D6E69747572653B706F6F6C31383D676F2E736B7970653B706F6F6C31393D747261636B2E736B7970657C706F6F6C313D3139342E3139322E3139392E3235313A31323335303B706F6F6C323D3139342E3139322E3139392E3235323A31323335303B706F6F6C333D3139342E3139322E3139392E3235323A31323335303B706F6F6C343D3139342E3136352E3138382E3130313A31323335303B706F6F6C353D3139332E39352E3135342E31353A31323335313B706F6F6C363D3139342E3136352E3138382E3130303A31323335303B706F6F6C373D3139342E3136352E3138382E3130303A31323335303B706F6F6C383D3139342E3136352E3138382E3130303A31323335303B706F6F6C393D3139342E3136352E3138382E3130303A31323335303B706F6F6C31303D3230342E392E3136332E3134313A31323335303B706F6F6C31313D3139352E34362E3235332E3234353A31323335303B706F6F6C31323D3139352E34362E3235332E3234353A31323335303B706F6F6C31333D3139332E39352E3135342E31343A31323335313B706F6F6C31343D3139332E39352E3135342E31343A31323335313B706F6F6C31353D3139332E39352E3135342E31343A31323335313B706F6F6C31363D3139332E39352E3135342E31343A31323335313B706F6F6C31373D3139342E3136352E3138382E3130303A31323335303B706F6F6C31383D3139342E3136352E3138382E3130303A31323335303B706F6F6C31393D3139332E39352E3135342E31343A31323335310003B101706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B797065206578747261732E646F776E6C6F6164732E736B7970653B706F6F6C333D2A2E687773746F72652E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B797065202A2E6469726563746F72792E736B7970653B706F6F6C353D2A2E70696373746F7265202A2E6D796163636F756E742E736B797065202A2E6269626974202A2E70726F63637962657220747261636B2E736B79706520617070732E736B7970656173736574733B706F6F6C363D2A2E6D756C74696D656469612E736B797065202A2E6D756C74696D656469612E6D65746163616665202A2E6D756C74696D656469612E6461696C796D6F74696F6E202A2E6D756C74696D656469612E6D6574616F6D6E6974757265207777772E736B7970652077686174736E65772E736B7970653B706F6F6C373D7061792E736B797065207365637572652E7061792E736B7970653B706F6F6C383D6170692E736B7970653B706F6F6C393D63616C6C70686F6E65732E736B7970652063616C6C72617465732E736B7970653B706F6F6C31303D2A2E7072656D69756D2E736B7970653B706F6F6C31323D6C6F67732E736B7970653B706F6F6C31333D617661746172736572766963652E736B79706520636F6E74616374696D706F72742E736B7970653B706F6F6C31343D676F2E736B7970653B706F6F6C31353D747261636B696E672E6F6D6E69747572657C706F6F6C313D3139342E3139322E3139392E3235312C31323335302C312C4E4C2C77652C35302C313B706F6F6C323D3139342E3139322E3139392E3235322C31323335302C312C444B2C77652C35302C313B706F6F6C333D3139332E39352E3135342E31372C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36322C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232372C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33332C31323335312C312C4C552C77652C35302C313B706F6F6C343D3139342E3136352E3138382E3130312C31323335302C312C49452C77652C35302C313B706F6F6C353D3139332E39352E3135342E31342C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3230352C31323335312C312C4C552C77652C35302C31203231322E3138372E3137322E35392C31323335312C312C49452C77652C35302C31203231322E382E3136362E31392C31323335312C312C4C552C77652C35302C313B706F6F6C363D3139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134302C31323335302C312C43412C6E612C35302C313B706F6F6C373D3139352E34362E3235332E3234352C31323335302C312C4C552C77652C35302C31203139332E39352E3135342E31362C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36312C31323335312C312C49452C77652C35302C31203231322E382E3136362E32302C31323335302C312C4C552C77652C35302C313B706F6F6C383D3230342E392E3136332E3138342C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38392C31323335302C312C4C552C77652C35302C313B706F6F6C393D3139342E3136352E3138382E3131352C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134312C31323335302C312C43412C6E612C35302C313B706F6F6C31303D3139332E39352E3135342E31352C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36302C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232362C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33322C31323335312C312C4C552C77652C35302C313B706F6F6C31323D37382E3134312E3137372E37362C31323335302C312C4C552C77652C35302C313B706F6F6C31333D3230342E392E3136332E3136372C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38312C31323335302C312C4C552C77652C35302C313B706F6F6C31343D3230342E392E3136332E3136382C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C313B706F6F6C31353D3230342E392E3136332E3136392C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C3100039701736B79706566696E642E736B7970653D31372C362C382C2D33392C3139206469726563746F72792E736B7970653D31372C362C382C2D33392C31390003A60138302E3235322E38352E37302C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37312C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37322C32333435362C312C6E6C2C77652C35302C31203139352E34362E3235332E3233382C32333435362C322C6C752C77652C35302C31203139352E34362E3235332E3233392C32333435362C322C6C752C77652C35302C31203139342E3136352E3138382E37342C32333435362C332C69652C77652C35302C31203139342E3136352E3138382E37352C32333435362C332C69652C77652C35302C31203231322E3138372E3137322E352C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E32302C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E33332C32333435362C342C69652C77652C35302C31203231322E382E3136332E38372C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132352C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132362C32333435362C362C6C752C77652C35302C31203133302E3131372E37322E3132362C32333435362C372C6E6C2C77652C35302C31203133302E3131372E37322E36362C32333435362C372C6E6C2C77652C35302C310004B2010B03A09C0125B3EA010B220104A5012A24A39C012102220025A19C010401F3C2011A142103030A220125B0EA0103051A2103030B2201030522010384012B39393030303131313A37382E3134312E3137372E39363A3233343536000086010C008701880E039101000493010CC2A5BC5C2774C32EFDD927740496010CD592BC1034504E8DB5F2345006C20105F801F901FA01FB01FC010395016272617465303D31206272617465313D31206272617465323D31206272617465333D31206272617465343D31206272617465353D31206272617465363D31206272617465373D31206272617465383D31207372617465303D31207372617465313D31207372617465323D31207372617465333D31207372617465343D31207372617465353D31207372617465363D31207372617465373D31207372617465383D310003B4013139342E3136352E3138382E37373A3132333530203231322E382E3136332E3130333A31323335300000C0010100C1010103CB012E6163636573732E736B7970652E6E65740000E1010F00F0010100F101A982CA950303D50137382E3134312E3137372E33383A3132333530203230342E392E3136332E3135313A31323335300003CF0137382E3134312E3137372E36393A3132333530203230342E392E3136332E3134393A31323335300000D6010103E4013139342E3136352E3138382E38303A3132333530203231322E382E3136362E353A31323335300003E5010000F8016403F7015B574845453A204F4646203130302C20563120302C20563220305D205B496E70757445513A204F46462035302C2056312035305D205B4945513A204F46462031362C2056312031322C2056322031322C2056332031322C2056342031322C2056352031322C2056362031322C2056372031325D205B53453A204453203130302C2057494F20305D205B5345323A2044532039302C2057494F2031305D205B414D504D3A204F4C442035302C20444147432035305D205B4B54523A204F46462035302C204F4E2035305D205B49414D323A204F46462039392C204D3120312C204D3220305D0003FA0152434F4E3D350003F901302F342E322E2A2E2A2C33322C3320302F352E302E2A2E2A2C31342C3320302F352E312E2A2E3130342C342C330003A80168747470733A2F2F7777775C2E70617970616C5C2E2E3F2E3F2E3F247C68747470733A2F2F696D616765735C2E70617970616C5C2E636F6D247C68747470733A2F2F7777775C2E70617970616C6F626A656374735C2E636F6D247C68747470733F3A2F2F2E2B5C2E666263646E5C2E6E6574247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D247C68747470733F3A2F2F6368616E6E656C5C2E736B7970655C2E636F6D247C68747470733A2F2F617070735C2E736B7970655C2E636F6D247C68747470733F3A2F2F7161617070735C2E736B7970655C2E6E6574247C68747470733F3A2F2F636F6E6E6563745C2E66616365626F6F6B5C2E6E6574247C68747470733A2F2F2E2A5C2E736B7970656173736574735C2E636F6D247C68747470733A2F2F61645C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D656D65615C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D617061635C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F737461746963323F5C2E736B7970655C2E636F6D247C68747470733A2F2F7161737461746963323F5C2E736B7970655C2E6E6574247C68747470733A2F2F7072657374617469635C2E736B7970655C2E6E6574240003FF013078313030303230343030393136333231372D642D723230342E392E3136332E3231373A38313932203078313030303230343030393136333231392D642D723230342E392E3136332E3231393A38313932203078313030303230343030393136333232312D642D723230342E392E3136332E3232313A38313932203078313030303230343030393136333232332D642D723230342E392E3136332E3232333A38313932203078313030303230343030393136333232352D642D723230342E392E3136332E3232353A38313932203078313030303230343030393136333232372D642D723230342E392E3136332E3232373A38313932203078313030303230383038383138363030352D642D723230382E38382E3138362E353A38313932203078313030303230383038383138363030372D642D723230382E38382E3138362E373A38313932203078313030303230383038383138363030392D642D723230382E38382E3138362E393A38313932203078313030303230383038383138363031312D642D723230382E38382E3138362E31313A38313932203078313030303230383038383138363031332D642D723230382E38382E3138362E31333A38313932203078313030303230383038383138363031352D642D723230382E38382E3138362E31353A38313932203078313030303230383038383138363031372D642D723230382E38382E3138362E31373A38313932203078313030303230383038383138363031392D642D723230382E38382E3138362E31393A38313932203078313030303230383038383138363032312D642D723230382E38382E3138362E32313A38313932203078313030303230383038383138363032332D642D723230382E38382E3138362E32333A38313932203078313030303230383038383138363032352D642D723230382E38382E3138362E32353A38313932203078313030303230383038383138363032372D642D723230382E38382E3138362E32373A38313932203078313030303230383038383138363032392D642D723230382E38382E3138362E32393A38313932203078313030303230383038383138363033312D642D723230382E38382E3138362E33313A38313932203078313030303230383038383138363033332D642D723230382E38382E3138362E33333A38313932203078313030303230383038383138363033352D642D723230382E38382E3138362E33353A38313932203078313030303230383038383138363033372D642D723230382E38382E3138362E33373A38313932203078313030303230383038383138363033392D642D723230382E38382E3138362E33393A38313932203078313030303230383038383138363034372D642D723230382E38382E3138362E34373A38313932203078313030303230383038383138363034392D642D723230382E38382E3138362E34393A38313932203078313030303230383038383138363035312D642D723230382E38382E3138362E35313A38313932203078313030303230383038383138363035332D642D723230382E38382E3138362E35333A38313932203078313030303230383038383138363035352D642D723230382E38382E3138362E35353A38313932203078313030303230383038383138363035372D642D723230382E38382E3138362E35373A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E35393A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36313A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36333A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E36353A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36373A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36393A38313932203078313030303230383038383138363037312D642D723230382E38382E3138362E37313A38313932203078313030303230383038383138363037332D642D723230382E38382E3138362E37333A38313932203078313030303230383038383138363037352D642D723230382E38382E3138362E37353A38313932203078313030303230383038383138363037372D642D723230382E38382E3138362E37373A38313932203078313030303230383038383138363037392D642D723230382E38382E3138362E37393A38313932203078313030303230383038383138363038312D642D723230382E38382E3138362E38313A38313932203078313030303230383038383138363038332D642D723230382E38382E3138362E38333A38313932203078313030303230383038383138363038352D642D723230382E38382E3138362E38353A38313932203078313030303230383038383138363038372D642D723230382E38382E3138362E38373A38313932203078313030303230383038383138363038392D642D723230382E38382E3138362E38393A38313932203078313030303230383038383138363039312D642D723230382E38382E3138362E39313A38313932203078313030303230383038383138363039332D642D723230382E38382E3138362E39333A38313932203078313030303230383038383138363039352D642D723230382E38382E3138362E39353A38313932203078313030303230383038383138363039372D642D723230382E38382E3138362E39373A38313932203078313030303230383038383138363039392D642D723230382E38382E3138362E39393A38313932203078313030303230383038383138363130312D642D723230382E38382E3138362E3130313A38313932203078313030303230383038383138363130332D642D723230382E38382E3138362E3130333A38313932203078313030303230383038383138363130352D642D723230382E38382E3138362E3130353A38313932203078313030303230383038383138363130372D642D723230382E38382E3138362E3130373A38313932203078313030303230383038383138363130392D642D723230382E38382E3138362E3130393A38313932203078313030303230383038383138363131312D642D723230382E38382E3138362E3131313A38313932203078313030303230383038383138363131332D642D723230382E38382E3138362E3131333A38313932203078313030303230383038383138363131352D642D723230382E38382E3138362E3131353A38313932203078313030303230383038383138363131372D642D723230382E38382E3138362E3131373A38313932203078323030303134393030353034353031312D642D723134392E352E34352E31313A38313932203078323030303134393030353034353031332D642D723134392E352E34352E31333A38313932203078323030303134393030353034353031352D642D723134392E352E34352E31353A38313932203078323030303134393030353034353031372D642D723134392E352E34352E31373A38313932203078323030303134393030353034353031392D642D723134392E352E34352E31393A38313932203078323030303134393030353034353032312D642D723134392E352E34352E32313A38313932203078323030303134393030353034353032332D642D723134392E352E34352E32333A38313932203078323030303134393030353034353032352D642D723134392E352E34352E32353A38313932203078323030303134393030353034353032372D642D723134392E352E34352E32373A38313932203078323030303134393030353034353032392D642D723134392E352E34352E32393A38313932203078323030303134393030353034353033312D642D723134392E352E34352E33313A38313932203078323030303134393030353034353033332D642D723134392E352E34352E33333A38313932203078323030303134393030353034353033352D642D723134392E352E34352E33353A38313932203078323030303134393030353034353033372D642D723134392E352E34352E33373A38313932203078323030303134393030353034353033392D642D723134392E352E34352E33393A38313932203078323030303134393030353034353034312D642D723134392E352E34352E34313A38313932203078323030303134393030353034353034332D642D723134392E352E34352E34333A38313932203078323030303134393030353034353034352D642D723134392E352E34352E34353A38313932203078323030303134393030353034353034372D642D723134392E352E34352E34373A38313932203078323030303134393030353034353034392D642D723134392E352E34352E34393A38313932203078323030303134393030353034353035312D642D723134392E352E34352E35313A38313932203078323030303134393030353034353035332D642D723134392E352E34352E35333A38313932203078323030303134393030353034353035352D642D723134392E352E34352E35353A38313932203078323030303134393030353034353035372D642D723134392E352E34352E35373A38313932203078323030303134393030353034353035392D642D723134392E352E34352E35393A38313932203078323030303134393030353034353036312D642D723134392E352E34352E36313A38313932203078323030303134393030353034353036332D642D723134392E352E34352E36333A38313932203078323030303134393030353034353036352D642D723134392E352E34352E36353A38313932203078323030303134393030353034353036372D642D723134392E352E34352E36373A38313932203078323030303134393030353034353036392D642D723134392E352E34352E36393A38313932203078323030303134393030353034353037312D642D723134392E352E34352E37313A38313932203078323030303134393030353034353037332D642D723134392E352E34352E37333A38313932203078323030303134393030353034353037352D642D723134392E352E34352E37353A38313932203078323030303134393030353034353037372D642D723134392E352E34352E37373A38313932203078323030303134393030353034353037392D642D723134392E352E34352E37393A38313932203078323030303134393030353034353038312D642D723134392E352E34352E38313A38313932203078323030303134393030353034353038332D642D723134392E352E34352E38333A38313932203078323030303134393030353034353038352D642D723134392E352E34352E38353A38313932203078323030303134393030353034353038372D642D723134392E352E34352E38373A38313932203078323030303134393030353034353038392D642D723134392E352E34352E38393A38313932203078323030303134393030353034353039312D642D723134392E352E34352E39313A38313932203078323030303134393030353034353039332D642D723134392E352E34352E39333A38313932203078323030303134393030353034353039352D642D723134392E352E34352E39353A38313932203078323030303134393030353034353039372D642D723134392E352E34352E39373A38313932203078323030303134393030353034353039392D642D723134392E352E34352E39393A38313932203078323030303134393030353034353130312D642D723134392E352E34352E3130313A38313932203078323030303134393030353034353130332D642D723134392E352E34352E3130333A38313932203078323030303134393030353034353130352D642D723134392E352E34352E3130353A38313932203078323030303134393030353034353130372D642D723134392E352E34352E3130373A38313932203078323030303134393030353034353130392D642D723134392E352E34352E3130393A38313932203078323030303134393030353034353131312D642D723134392E352E34352E3131313A38313932203078323030303134393030353034353131332D642D723134392E352E34352E3131333A38313932203078323030303134393030353034353131352D642D723134392E352E34352E3131353A38313932203078323030303134393030353034353131372D642D723134392E352E34352E3131373A38313932203078323030303134393030353034353131392D642D723134392E352E34352E3131393A38313932203078323030303134393030353034353132312D642D723134392E352E34352E3132313A38313932203078323030303134393030353034353132332D642D723134392E352E34352E3132333A38313932203078323030303134393030353034353132352D642D723134392E352E34352E3132353A38313932203078323030303134393030353034353132372D642D723134392E352E34352E3132373A38313932203078323030303134393030353034353132392D642D723134392E352E34352E3132393A38313932000089020A062E19AEBFD5A40B80D4B6B30280D2AFF205808CFD910B80DEB9F1048FA486F4049CA486F404D5A486F404ACC686F404C2C686F404878F87F404CEB887F404ADC487F404BCC687F404D4D087F404F9EA87F4049CF587F404C8F487F404C9F487F404CAF487F404EACCBB9C05F7CCBB9C05E694D7BB058E96D7BB05A896D7BB050094023C0095021400930201039902536B79706520546563686E6F6C6F6769657320534100008E0200008F0280BAB70300910280A30503F2013231332E3134362E3138392E3230313A3132333530203231332E3134362E3138392E3230323A3132333530203231332E3134362E3138392E3230333A3132333530203231332E3134362E3138392E3230343A3132333530203231332E3134362E3138392E3230353A3132333530203231332E3134362E3138392E3230363A3132333530203231322E3136312E382E31303A3132333530203231322E3136312E382E323A3132333530203231322E3136312E382E333A3132333530203231322E3136312E382E343A3132333530203231322E3136312E382E353A3132333530203231322E3136312E382E363A31323335300000FC010106FD0106011E64AC02A403E807009002C20103C301687474703A2F2F37392E3132352E36332E3732247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D240000DE0148 + <_256>000010011AC0AA3BA66DF7FB48228AE35F9BB4A032FE4A6A898DA7A1A5AE37DC59FB3D09607F1CACD46A5DBC008DABF8F09C797DF5A8903307D04C318825CEA7C481303C655A9EEE099E9A0AF1158373B458BB8FDACB336A6EC63C043E6782688E2350B417DDDDFF96B474DAEA7D1DF3742303B79111FC752BFB5D6887A5B822F945CC761FAF6E80DE5EC60868768CB8A9F9C876137806DCEA0DD1300181558ABFDBA26592078F5F84195C526D8C7F339EF82700FD93F8FB71ADA5ED3E977D27FA52D1F489EF5DA0A9E00B146BADCBDEBFB0DFEBCD61E5B8352A49893357E0DC3A736743929DA975782EA4D8184605FD064641986C47706D264281C876F926BF58003E9E + <_3>0000100498ECF8A7A4585F76C930739A1EAE590DE96D9EF3AA9B231E67965F3F08ECFC493E1DA23ECDE17A85C94CBE034E88F9414E9BBC82F32AAFCFFB2C09F6F57A478238BAEC9EEF2BB9C67F71257722E6786D88D6400F6B7D81450FB3B6CCCC3986E3782D2387E354EBA9099331AEF510D479C6601D2383D866E2B5B525DF0BA975D58C120EFAE88C89EE365FC696CC891B77F67CFA18FDE8E95DDAC25A7C7D70FA7A1414BAE593856A658888C622836006C1C131B4B2E805554DCFA52F3EFD34C1B759BF8A302E491835DCE701E84D37ED150C8ADD699AD3DCA9F515123C5B5AD94E253E173BA3465E64A0079D5EF4E6075E66D0F5FBC3D9BC25C4E80C4CB2FE9B87040003000004D00F0005D00F050041040400B80125C20003141B14230025D50003031B14230024E100142300250003191714230025EA0003141714230025EA00011724EA00140A14230025E400030F1C14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E10025E10003A006100A0309031725000325180C0A25C20003140B0C03040D0A03882725C3000C0A03E43225C4000C0A0602050228038407DC08FA1E0601050102050203FA1E1C0603250028061D1E1F202122060105010205010503050141060300636F756E74206279207175616C697479000001CC080002040003000004010005010501410603006261647175616C69747920636F756E742062792076657273696F6E000001D6080002070003000004010005010501410603006261647175616C6974792073756D2062792076657273696F6E000001E0080002070003000004010005010500410304005424E400142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E40025E40028043CB401D804901C060105010205014106030073756D206F66206C61737463616C6C206475726174696F6E73000001B009000201000300000480A3050005B054050141060300636F756E74206279206C61737463616C6C206475726174696F6E000001BA090002050003000004010005010500410204005025EB00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EB0028031E32D0000601050102050141060300636F756E742062792073797374656D20637075207573616765000001940A0002040003000004010005010500410204004F25EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050141060300636F756E742062792070726F63657373206370752075736167650000019E0A0002040003000004010005010500410304006824C20014230024E60014230025E600011A14230025EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050125C2000501410603006A6974746572636F756E742062792070726F6365737320637075207573616765000001F80A0002040003000004010005010501410603006A69747465722062792070726F6365737320637075207573616765000001820B0002040003000004D00F0005D00F0500410304004424E700142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A1423000225E700050141060300706F74656E7469616C207463702066616C6C6261636B73000001DC0B00020100030000040100050105014106030061637475616C207463702066616C6C6261636B73000001E60B00020100030000040100050105004103040056240C142300250C030A1814230025EA0003141714230025EA00011724EA00140A14230024E70014230025E700011A14230024E50014230025E500011C0602250C29050306070809280401020405060105010205010502050141060300636F756E74206279206E617474797065000001C00C0002050003000004010005010501410603007564706661696C75726573206279206E617474797065000001CA0C0002050003000004010005010500410204001B25D90014230025D90025DA000B0602050228030102040601050102050141060300636F756E74206279206E726F666D756C74696368617473000001A40D0002040003000004010005010500410304001425F700011C14230025000319171423000225F90005014106030075736572732077686F206861766520636F6D706C65746564204943000001880E0002010003000004010005010501410603006C617374204943207969656C6420676C6F62616C73756D000001920E0002010003000004E8070005500500410304001224F60014230025000319171423000225F60005014106030075736572732077686F206861766520494320737570706F7274000001EC0E0002010003000004010005010501410603004943207374617274757020636F756E7420676C6F62616C73756D000001F60E00020100030000046400051405004102040025240C142300250C030A18142300250C011C142300250C280802030405060708090601050102050141060300636F756E74206279206E617474797065000001D00F0002090003000004010005010500410404001A250003191714230025E20025E30025FC00280201020601050102050141060300766964656F2073656E642063617061626C650000019811000201000300000401000501050141060300766964656F20706172616C6C656C2063616C6C730000019911000201000300000414000502050141060300636F756E7420627920766964656F2063616C6C73206D616465000001A2110002030003000004010005010500410204003A250003191714230025EA0003141714230025EA00011724EA00140A14230024E50014230025E50003031914230025E50028030102030601050102050141060300636F756E742062792073747265616D7472616E73706F7274000001FC11000204000300000401000501050041090400E00125C20003141B25E400030F1C1514230024E100142300250003191714230025EA0003141725EA0001171514230025FF002580010A011A14230025E60003031A25E50003031A1514230024F5001423002412142300249F0114230025C30025E10025E10003A006100A03A0060B0309031725000325180C0A25C20003140B0C03040D0A2512030A0C251025F5001703CC080C0A1C160602020502250003231B241D150603050305020503150503251D03808080808080808080011D14150603050305020503150503251D038080808080808080C0011D1415060305030502050315050141060300706F74656E7469616C2052555F756E65787065637465645F62616471000001E01200020100030000040100050105014106030061637475616C2052555F756E65787065637465645F62616471000001EA1200020100030000040100050105014106030042435020706F74656E7469616C2052555F756E65787065637465645F62616471000001F4120002010003000004010005010501410603004243502061637475616C2052555F756E65787065637465645F62616471000001FE12000201000300000401000501050141060300424350203220706F74656E7469616C2052555F756E65787065637465645F62616471000001881300020100030000040100050105014106030042435020322061637475616C2052555F756E65787065637465645F626164710000019213000201000300000401000501050141060300424350203420706F74656E7469616C2052555F756E65787065637465645F626164710000019C130002010003000004010005010501410603004243502031362061637475616C2052555F756E65787065637465645F62616471000001A6130002010003000004010005010500410304000825B801011C25B701050141060300757365727320696E207075626C6963206368617473000001C4130002010003000004010005010501410603007075626C69632063686174206D6573736167657320696E206C617374206D696E757465000001CE1300020100030000046400050A0500410404005F248E0114230024D5001423002500032B1B1423002500032B1C250D03021C16250E03FFFFFFFF0F1D03B4E2C8F10217250E0380808080100D03B4E2C8F10217151614230025D500280219C80106010501020501258E010501258E0103880E1C050141060300636F756E742062792062756464696573000001A814000203000300000401000501050141060300617661696C6162696C697479206167652062792062756464696573000001B2140002030003000004C0FC150005A099020501410603006C6F6E6720617661696C6162696C697479206167652062792062756464696573000001BC140002030003000004010005010500410204003324C000142300250003191714230025F301290300E5C68583B7AEDE36F2CAB9A3A7AE983806020502280202030601050125C00005014106030073696D756C74616E656F75732063616C6C7320706572206E616D6573706163650000018C15000203000300000419000519050041020400C50125C00006020502142300250006030503031917142300050303231B06040504210302200225A1010605050421030502200225A2010606030606070505021A050503021A160506021A15210305072002010607050203021B050603021B152103050720020206070502021A050603021B15210305072002030206070502021A050503041A15210305072002030306070502021A050503031A15210305072002030406070502021A050503051A152103050720020305060705072806010203040506060105010205014106030063616C6C6572733A207332735F313120636F6E665F686F737420636F6E665F636C69656E7420736B7970656F757420736B797065696E20766F6963656D61696C20756E6B6E6F776E000001F015000207000300000401000501 + <_4>000010052A0B6759B71FBC1EF05BE97DFEA4EE6C1E15AF19ED70DEC1130B14C13CE41246D302B9662592907E3CA508A57702B5C00C2A05170857FA22012E0F235B425B4D919B23A541D3AD6E948FC634DE71A29493634884DFD5E9D89C5D951CBCD71B9B3ABFD3C4E2779BB1817D76E7C223CA36BD75A6A05B730AF138057E4048B2FFDD522BB588EC0B9D3E014BF9E354EB608150BC613C739D9E8C7465F05F047FAF7AFA3EE89B9B58BF0FC35F07B55CF3E4B59A7C4ED48B1C0C7F0305E6AC2E80AAEAD6064EB6ACDC1806FCE0B5CB66F0840DA7F0FE7B228E3898E3E42A9AFEFE13DDF019EF8D8F02A631AF2615BBC6E1EDB65C89A775F642C88109E6247EC4B463DC302E2A2E323000050541020006020307322E302E2A2E3100050541030006020307322E302E2A2E3200000AE4ED8009050541030006020307322E302E2A2E33000009B3E6CC990B050541040006020307322E302E2A2E3400000AE4ED8009000BA00B050541030006020308322E302E2A2E35000307322E302E2A2E3900050541040006020308322E302E2A2E39000307322E302E2A2E313100000AE4ED8009050541040006020308322E302E2A2E3131000307322E302E2A2E3135000009E6CC99B306050541050006020308322E302E2A2E3135000307322E302E2A2E323000000AE4ED8009000BA00B050041050303557067726164655465737433000301332E302E302E3130300003044E6963654272616E6400050541040006020307332E302E302E2A0003074E6963654272616E6400000AE4ED8009050541040006020307322E302E302E2A0003074E6963654272616E6400000AE4ED80090500410E0303557067726164655465737433000301332E302E302E31303000050541040006020307332E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307322E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307332E302E302E39380003074F746865724272616E64000009B3E6CC990B050541040006020307322E302E302E39380003074F746865724272616E64000009B3E6CC990B050541050006020307332E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541050006020307322E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541030006020307332E302E302E393900000AE4ED8009050541030006020307322E302E302E393900000AE4ED8009050541030006020307332E302E302E3938000009B3E6CC990B050541030006020307322E302E302E3938000009B3E6CC990B050541040006020307332E302E302E393700000AE4ED8009000BA00B050541040006020307322E302E302E393700000AE4ED8009000BA00B0500410303033130303031000301302E302E302E313000050541020006020307302E302E302E3900 + <_5>00001006739CA527EF827847E16F23CD52458C3EBA3460A42935EC6948BEFA626B49E3BDF279FC62486E2DDBCA19609ED23D31F4E5175920F282AD74A74A997C3909E67B622480C68A058E886C7D5F3C40954880D7798CD61CEA0FBAFB389BE5B2B8A887348F7AADB4DF642B194B814047CDA0E698EDDE61DFA731DCA5883A76F913D8C94066718054E85ADA7AE009F2B2A9AF762FDCB9B6CAF64C156911E3AB172CFD795F66FB6E8E15048A54E4AB17979D6C447DEBADE75CC6F606050D980061112AFF9AE7C7BF8065D711949E41FA4C8B6CBF0916BB395B3E186A7D617D353C6BFFC687FE79475DFA095D113D70B828FB597BC3665B7C9C3669CA9CBE5D308D3FC23803044E45544745415200050541020006040307302E392E302E2A000500410503033130303033000301312E302E302E3137000304534D4300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E312E302E313000030442454C4B494E00050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E3137000304454447452D434F524500050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E31330003044C4F474954454300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303035000301312E342E38382E31333636000304544F50434F4D00050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410503033130303035000301312E342E38382E313336360003045043484F4D4500050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410403033130303036000301302E302E302E313000050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303037000301312E302E312E330003045445434F00050541020006040307312E302E302E3800050541020006020307312E302E312E31000500410503033130303038000301302E392E332E3339370003044C494E4B53595300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003044E45544745415200050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003045048494C49505300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410403033130303130000301302E392E302E31310003044C494E4B53595300050541020006040307302E392E302E3130000500410403033130303130000301302E392E302E313100030442554646414C4F00050541020006040307302E392E302E3130000500410503033130303132000301312E302E302E310003044353544E00050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303133000301302E302E332E3234000304414B00050541020006040307302E302E312E323400050541020006020307302E302E322E3234000500410303033130303134000301312E372E34332E33382E3200050541020006040307312E372E32332E32372E34000500410503033130303135000301312E322E31372E30000304415A5445434800050541020006040307312E322E31312E3000050541020006020307312E322E31352E30000500410303033130303230000301312E302E302E343700050541030006020308312E302E302E3233000307312E302E302E3233000500410403033130303234000301332E322E302E323800050541030006040308332E302E302E35000307332E302E302E3500050541030006020308332E312E302E31000307332E322E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E494300050541020006040307302E302E302E3100050541020006020307302E302E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E4943434F4E53554D455200050541020006040307302E302E302E3100050541020006020307302E302E302E3800 + + 1 + + 400 + + + + 8118 + 39,64,8184 + 37,50,13164 + + 1 + + 1 + + + -1431699456 + -1431699456 + 1610612735 + + 41C801050041050200D9AF0D45D9E900010400028788BCED0400038788BCED04000400050041050200BB0AB3FDD1A40001040002B7DCBCED040003B7DCBCED040004000500410502005C3766C2DA6B00010400029FB2BCED0400039FB2BCED04000400050041050200D9F8DC20CA33000104000296DAAAED04000396DAAAED0400040005004105020063847B3765900001040002D794BDED040003D794BDED040004000500410502004E80142FD3C70001040002CF86BDED040003CF86BDED04000400050041050200C3B213EA24A50001040002BF89BBED040003BF89BBED040004000500410502006FFEF1BA804C0001040002CF86BDED040003CF86BDED0400040005004105020052ED923CB3A700010400028788BCED0400038788BCED040004000500410502005243330D305B000104000283FFB2ED04000383FFB2ED040004000500410502006FF9438E9E5D0001040002CF86BDED040003CF86BDED04000400050041050200585515F19D77000104000283FFB2ED04000383FFB2ED04000400050041050200729EE3A8DD460001040002CF86BDED040003CF86BDED040004000500410502004572795D3BB300010400029FB2BCED0400039FB2BCED040004000500410502009F94D72CABA40001040002CF86BDED040003CF86BDED0400040005004105020095052D9C81090001040002B7DCBCED040003B7DCBCED040004000500410502005859A15FD7FC0001040002DC8FB5ED040003DC8FB5ED0400040005004105020059D7AB3EBBFB0001020002F8FABCED040003CF86BDED04000400050041050200BB2481B9390E0001040002CF86BDED040003CF86BDED0400040005004105020059D7F395A7BA0001040002B7DCBCED040003B7DCBCED040004000500410502006DC4BEF5D52E0001040002B0DFBAED040003B0DFBAED040004000500410502004B6E709CF4290001040002B7DCBCED040003B7DCBCED040004000500410502007A7D5CEC2B8D0001040002CF86BDED040003CF86BDED040004000500410502006FFFA8AFB19D0001040002B7DCBCED040003B7DCBCED040004000500410502003E4475A07A6F0001040002B7DCBCED040003B7DCBCED040004000500410502003EDD8384A4F90001040002BF89BBED040003BF89BBED04000400050041050200560FBFA4E4900001040002B7DCBCED040003B7DCBCED04000400050041050200C24FAEEE43F10001040002B3CEB5ED040003B3CEB5ED040004000500410502004F378778C6F30001040002CF86BDED040003CF86BDED04000400050041050200C94418BB0EDF0001040002B7DCBCED040003B7DCBCED040004000500410502003B75A58BECB30001040002CF86BDED040003CF86BDED04000400050041050200772A7A0908890001040002CF86BDED040003CF86BDED0400040005004105020048BB63586DE100010400029088BCED0400039088BCED040004000500410502005544F881BEDA000104000283FFB2ED04000383FFB2ED040004000500410502005B4C1468EDF80001040002B7DCBCED040003B7DCBCED04000400050041050200538BAF3F934F0001040002B3CEB5ED040003B3CEB5ED0400040005004105020055D6F93A4FD70001040002D7B3BBED040003D7B3BBED04000400050041050200D5D64561E55F00010400028788BCED0400038788BCED0400040005004105020046ADF229B8570001040002CF86BDED040003CF86BDED04000400050041050200D5151C19FFD600010200029FB2BCED040003B7DCBCED04000400050041050200973CA35DB82400010400029FB2BCED0400039FB2BCED04000400050041050200C249E5B953700001040002CF86BDED040003CF86BDED04000400050041050200722C69D8C4F500010400029FB2BCED0400039FB2BCED0400040005004105020058CBB311F2400001040002DC8FB5ED040003DC8FB5ED040004000500410502004BB7A090766E0001040002CF86BDED040003CF86BDED040004000500410502007DEF80FBEBD90001040002EFDDBBED040003EFDDBBED0400040005004105020076A03698F87A0001040002CF86BDED040003CF86BDED0400040005004105020050E5DFDD0C700001040002CF86BDED040003CF86BDED040004000500410502004D4C85E0CEC80001040002CF86BDED040003CF86BDED040004000500410502006FEA6BCD92A10001020002F8FABCED040003CF86BDED0400040005004105020043BAA930F28600010400029FB2BCED0400039FB2BCED04000400050041050200722DB82DDB780001040002CF86BDED040003CF86BDED0400040005004105020052E995118B9F0001040002CF86BDED040003CF86BDED040004000500410502005403013B36D20001040002EFDDBBED040003EFDDBBED04000400050041050200B27C0C920B260001040002B7DCBCED040003B7DCBCED04000400050041050200D9AF0997A7450001040002BCD9AAED040003BCD9AAED04000400050041050200BC00130BB5F60001040002CF86BDED040003CF86BDED04000400050041050200591FF23B53830001040002CF86BDED040003CF86BDED04000400050041050200557EB01367590001040002CF86BDED040003CF86BDED04000400050041050200505F157093A2000102000297A4BCED04000397A4BCED040004000500410502003A036C495C670001040002CF86BDED040003CF86BDED0400040005004105020050D8CF0B7D480001040002B7DCBCED040003B7DCBCED040004000500410502004E34E4D0FF250001040002B7DCBCED040003B7DCBCED040004000500410502007A1E50A46E770001040002CF86BDED040003CF86BDED040004000500410502005F18C666CBB80001040002EFDDBBED040003EFDDBBED04000400050041050200C19335603A9E0001040002DC8FB5ED040003DC8FB5ED0400040005004105020097142BD7DF890001040002AFDFBAED040003AFDFBAED0400040005004105020052F3355FFED400010400029FB2BCED0400039FB2BCED04000400050041050200BCBA857EECDF0001040002D7B3BBED040003D7B3BBED04000400050041050200729259D605EF0001040002CF86BDED040003CF86BDED04000400050041050200BEC2F57655B300010400029FB2BCED0400039FB2BCED040004000500410502005BD905C8304B0001020002A8EEBBED0400038788BCED0400040005004105020055F2C0360F360001040002EFDDBBED040003EFDDBBED0400040005004105020082C01DB9605D00010400028788BCED0400038788BCED04000400050041050200BC73B8FB30360001040002CF86BDED040003CF86BDED0400040005004105020050390E32DF8B0001040002B0DFBAED040003B0DFBAED040004000500410502005BCE8A2D7B8000010400028788BCED0400038788BCED0400040005004105020042292BB45D2D0001040002CF86BDED040003CF86BDED040004000500410502004F1A354DCA9A00010400029FB2BCED0400039FB2BCED04000400050041050200591C1D7F0EC900010400028788BCED0400038788BCED04000400050041050200722E9D2CCB030001040002CF86BDED040003CF86BDED04000400050041050200443AB71D3F8A0001040002CF86BDED040003CF86BDED0400040005004105020018DEF34EB70600010400028788BCED0400038788BCED0400040005004105020097215860080F00010400029FB2BCED0400039FB2BCED040004000500410502007229C156A49E0001040002B7DCBCED040003B7DCBCED040004000500410502003A72EDECB0250001040002B3F7B4ED040003B3F7B4ED04000400050041050200D52F8CD18F640001040002E285B0ED040003E285B0ED040004000500410502006B0325208B4C0001040002EFDDBBED040003EFDDBBED040004000500410502005164424285660001040002938AB5ED040003938AB5ED04000400050041050200D4E9D6AB12F80001040002AFDFBAED040003AFDFBAED0400040005004105020059B3090F459C0001040002FCDDAAED040003FCDDAAED04000400050041050200BC10C41E7AAB0001040002CF86BDED040003CF86BDED040004000500410502009F9532B560C100010400028788BCED0400038788BCED0400040005004105020050EA7B4A63750001040002CF86BDED040003CF86BDED0400040005004105020045A658245E790001040002CF86BDED040003CF86BDED0400040005004105020047E3059299620001040002CF86BDED040003CF86BDED0400040005004105020081164AFC3B450001040002CF86BDED040003CF86BDED040004000500410502005703C3FC60FF00010400028788BCED0400038788BCED0400040005004105020063FAEB02F39300010400028788BCED0400038788BCED040004000500410502005714F2D9F6650001020002AFDFBAED040003ECE7BAED04000400050041050200505F1B22B00D0001040002CF86BDED040003CF86BDED0400040005004105020062C2F2A80C7900010400029FB2BCED0400039FB2BCED04000400050041050200425CA6CCD1FF0001040002CF86BDED040003CF86BDED0400040005004105020084C778D4AB110001040002CF86BDED040003CF86BDED040004000500410502005106437CD3B60001040002CF86BDED040003CF86BDED0400040005004105020058506B2B47D40001040002D7B3BBED040003D7B3BBED04000400050041050200DD70204563390001040002B7DCBCED040003B7DCBCED040004000500410502005CFFA5BE4A0000010200028888BCED040003F8FABCED0400040005004105020089BD8692E0400001040002B7DCBCED040003B7DCBCED040004000500410502004AC12BB2AB8D0001040002B7DCBCED040003B7DCBCED04000400050041050200DB555CBAEE6B0001040002CF86BDED040003CF86BDED0400040005004105020095052D8F81090001020002A7FDBCED040003CF86BDED04000400050041050200473AA0E1C9110001020002A7FDBCED040003CF86BDED040004000500410502004EFA971D2E4C0001040002B7DCBCED040003B7DCBCED04000400050041050200BCE6C5A829D900010400029E90B5ED0400039E90B5ED0400040005004105020051699F18DC540001040002D7B3BBED040003D7B3BBED040004000500410502005CFB85D7E6460001040002B3CEB5ED040003B3CEB5ED0400040005004105020052D17CE5A9840001040002BF89BBED040003BF89BBED0400040005004105020054DD54C818F20001040002CF86BDED040003CF86BDED040004000500410502005C3555EBDC670001040002B7DCBCED040003B7DCBCED0400040005004105020051D92EE554370001040002BF89BBED040003BF89BBED0400040005004105020095549556182D0001040002CF86BDED040003CF86BDED040004000500410502005419C1F7F52A0001040002B3CEB5ED040003B3CEB5ED040004000500410502008C7259638E1D0001040002B7DCBCED040003B7DCBCED04000400050041050200516745231C2200010400029FB2BCED0400039FB2BCED0400040005004105020055FB3DEAE2380001040002B7DCBCED040003B7DCBCED040004000500410502005D5470BCB83A00010400028788BCED0400038788BCED0400040005004105020054C6D511E6810001040002CF86BDED040003CF86BDED0400040005004105020062A7FAC0119000010200028788BCED0400038888BCED040004000500410502007225A1DCFB1A00010200028788BCED0400038888BCED04000400050041050200708B358CF15C00010400028788BCED0400038788BCED04000400050041050200D9A293C3FE550001040002AFDFBAED040003AFDFBAED04000400050041050200722119BAFCB600010400029FB2BCED0400039FB2BCED0400040005004105020054369C95EAC60001040002CF86BDED040003CF86BDED04000400050041050200AE74419813810001040002B7DCBCED040003B7DCBCED0400040005004105020048C613BC68510001040002EFDDBBED040003EFDDBBED04000400050041050200516E168D638B0001040002EFDDBBED040003EFDDBBED040004000500410502001819CFB484D20001040002CF86BDED040003CF86BDED04000400050041050200ADE013B3E9F10001040002CF86BDED040003CF86BDED040004000500410502005C708ABFAC890001040002B3CEB5ED040003B3CEB5ED04000400050041050200BC81882E891C0001040002B7DCBCED040003B7DCBCED0400040005004105020057785543EB480001040002CF86BDED040003CF86BDED040004000500410502006FF0CE6CB4500001040002CF86BDED040003CF86BDED040004000500410502005CE13B7199D4000102000283ADE7E304000383ADE7E30400040005004105020063F610137D170001040002B7DCBCED040003B7DCBCED04000400050041050200DC887BC89E210001040002CF86BDED040003CF86BDED040004000500410502005D9324151E7F0001020002A7FDBCED040003CF86BDED04000400050041050200BC02D363924D00010400029FB2BCED0400039FB2BCED040004000500410502004F28848E1AC50001040002CF86BDED040003CF86BDED0400040005004105020054C606DD0D260001040002D984B5ED040003D984B5ED04000400050041050200D5F586558C850001040002BF89BBED040003BF89BBED0400040005004105020082582B0468CF00010400028788BCED0400038788BCED040004000500410502005CE21BB9BD7C00010400029FB2BCED0400039FB2BCED0400040005004105020059A9ACE3BC02000104000296DAAAED04000396DAAAED040004000500410502005557DB28EDA300010400028788BCED0400038788BCED0400040005004105020076ABA00FF52C0001040002CF86BDED040003CF86BDED0400040005004105020052185C5CB8440001040002B7DCBCED040003B7DCBCED04000400050041050200441402A770A800010200028788BCED0400038888BCED04000400050041050200516623CC99760001040002CF86BDED040003CF86BDED040004000500410502005A3D6D867C2A0001040002BF89BBED040003BF89BBED04000400050041050200BC70864FCE530001040002B3F7B4ED040003B3F7B4ED040004000500410502005E9C9B4E7A740001040002CF86BDED040003CF86BDED0400040005004105020058ABF63F0EA70001040002FCDDAAED040003FCDDAAED040004000500410502005556BDBE86AC000104000286FFB2ED04000386FFB2ED0400040005004105020059D0D49C9B8000010400028788BCED0400038788BCED0400040005004105020059A934952E920001040002B3F7B4ED040003B3F7B4ED040004000500410502007220ABEC82C80001040002B7DCBCED040003B7DCBCED04000400050041050200807AB45544310001040002BF89BBED040003BF89BBED04000400050041050200187A8DFCCDCF0001040002BF89BBED040003BF89BBED04000400050041050200616B5C35801000010400028788BCED0400038788BCED040004000500410502005ABCE5EAE3790001040002938AB5ED040003938AB5ED0400040005004105020048DF5F3311D10001020002F8FABCED040003CF86BDED04000400050041050200D3146B24D6340001040002CF86BDED040003CF86BDED0400040005004105020059037023AC7D00010400029FB2BCED0400039FB2BCED040004000500410502003EDD92C929340001040002BF89BBED040003BF89BBED040004000500410502004C4EB0C1270D0001040002CF86BDED040003CF86BDED04000400050041050200BCA300CD17370001040002CF86BDED040003CF86BDED040004000500410502005BC42D9E789A0001040002D7B3BBED040003D7B3BBED04000400050041050200589755D3E75F0001020002D884B5ED040003B3CEB5ED040004000500410502007A7CC86B21530001040002CF86BDED040003CF86BDED040004000500410502005352A2DA24D300010400028788BCED0400038788BCED0400040005004105020058C9F9B6A86F0001040002B7DCBCED040003B7DCBCED040004000500410502005706A79DEAE60001020002AFDFBAED040003ECE7BAED0400040005004105020082D1B28F7A3A0001040002CF86BDED040003CF86BDED0400040005004105020052217343E79C0001040002CF86BDED040003CF86BDED0400040005004105020082CEA3A289FE000104000296DAAAED04000396DAAAED04000400050041050200D9E0FF79D1180001040002B7DCBCED040003B7DCBCED0400040005004105020052FD31513EE90001040002938AB5ED040003938AB5ED0400040005004105020052128CCDBA7C00010400029FB2BCED0400039FB2BCED040004000500410502006FB83DA167580001040002CF86BDED040003CF86BDED040004000500410502002E14B9387F540001020002B7DCBCED040003CF86BDED040004000500410502004F7E6F098A990001040002CF86BDED040003CF86BDED040004000500410502005D98B7099E1F0001040002B7DCBCED040003B7DCBCED04000400050041050200722A7476317600010400029FB2BCED0400039FB2BCED04000400050041050200BC18CE5EBDA10001020002AFDFBAED040003ECE7BAED040004000500410502005CF890CF3E270001040002B7DCBCED040003B7DCBCED040004000500410502008D72AE6DBEE30001040002CF86BDED040003CF86BDED0400040005004105020076A6D8E9EAAB0001040002CF86BDED040003CF86BDED04000400050041050200721B63925A140001040002CF86BDED040003CF86BDED040004000500410502007608B348A53A0001040002CF86BDED040003CF86BDED04000400 + + 0 + + -645574544 + 0 + 47500 + + 1 + + + 217.133.80.112:1076 217.133.80.112:47500 217.133.80.112:1083 217.133.80.112:1083 217.133.80.112:49734 + 7 + + <_1303289856>6C81442204F3D9855070B98CAE5879A505F3D9855070B98C4D4320134B66D9855070B98C5F4E60ED0D34D98550700434 + <_1303293952>4287274ED659D9855070B98C4287274ED74BD9855070B98C4287274EC15CD9855070B98C4287274ECE92D9855070B98C4287274EA75BD9855070B98C4287274E4B98D9855070B98C4287274EAA2DD9855070B98C4287274EA175D9855070B98C4287274ED735D9855070B98C4287274EAE25D9855070B98C4287274E1A2BD9855070B98C3D7D44372576D9855070B98CCF86DF304366D9855070B98C3D2E02A2259CD9855070B98C4287274EB98CD9855070B98C + <_1303298048>2E3363049108D9855070B98C2E3795FA3202D9855070B98C2E2F6F42E86DD9855070B98CB4B0620AA528D9855070B98C + <_1303306240>5F1894D8122BD9855070B98C2E40484969A3D9855070B98CD592A70A5566D9855070B98C2E26119F8DBED9855070B98C2E3754264E48D9855070B98C + <_1303314432>4D2BFFCAEC6CD9855070043B54BAD08D05E0D9855070B98C9D9D4DA11995D9855070B98C59584CCBB5CED9855070B98C972AC71733DDD9855070B98C + <_1303322624>5F3B0DCEB535D9855070043BD5150C1746D3D9855070B98C4D4B8646EF29D9855070B98CD5152F4D12BBD9855070B98C + <_1303326720>59D0D11D89DCD9855070C2462E755D8E1E97D9855070B98C2E492F875789D9855070B98C2E378784E9C6D9855070B98C2E2F6F6B48FCD9855070B98C + + + <_1303289856>9A4A56D31C619325C6601C71B23E13FDFAF5CA49F15C34A4E33F239B524D6BBC226021F010D2270A3B48DFA2E8CDB6FD37531B1118DB2D471CB980D0 + <_1303293952>D5A2186D0B45088ADDFA7B626C0904CED47E3DF13172672AED483E1EAD69DB781ABEC0D8812B1B5EFF91BC28C67FB5A3404D875A + <_1303298048>DB0EC5161D10171C7C6A4C7109DD + <_1303302144>5379BD98 + <_1303306240>88B19442A48D863ED54D712EEC36D53127BCE36653FE + <_1303310336>1908404B0F7BA3BE952CB1C533456D3CDA410BCB774AF93880FB8BD8C110 + <_1303314432>4B015AD444DD027FD3F61B2A51A53BA0 + <_1303322624>878BAF81A9F053B39E35081485E24B4EDA5F79D37E176C409B6E237A336451F42CFA7CEC013C98A18B51 + <_1303326720>CFB137906F6CCE77246BD5B6B434875570B1F9B9140C85D5114EE6953110B04F3557C0D1686D46A9F69106521979AE49E19F8622F93A + <_1303330816>BA4B81F735FDCDA4E4EF57ACF8A37051C66401E41CA4E562A5A49ACC2E246CCE + + + + 1 + + + 1 + + + 0 + + + 1 + + + + 9BF92EA4B417A7F6 + + + 4102030E322F322E302E302E37322F31373400000FF6EB9ADC04 + + + 0 + + + + 2 + en + + 357 + 258 + 0 + 0 + + 0 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + +

+ 35716ecf:2 + 98e6c103:0 +

+ +
+
+ + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + +
+ + + skypopen + + + 0 + 2 + 2 + 2 + +
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameA/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + +

+ 35716ecf:2 + 98e6c103:0 +

+ +
+
+ + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + +
+ + + skypopen + + + 0 + 2 + 2 + 2 + +
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient00/skypenameB/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml new file mode 100644 index 0000000000..4b72e67eb5 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/shared.xml @@ -0,0 +1,99 @@ + + + + + <_2>00001000A563932E7DE5A581942041A820F8437512A079C7ACB1B73281F191D109521E265BCD38C4133596B834AD9AA1D6BB5E1AC3D59E8675785321F722D39FBFAFB9A24E6482FA3030FFA3692D2C4A53BBCE9DC63F25D10207A20FA969982FEDC1DCC2A7C599071F4735E52AB2E06E34CA232C08B3AA2FB88A0C4A5763E0CD23C3AA37D1D2A7D6EED691EE99BA08BE294F68C24F9AE777DAF294F0AEB8346325A978DC6CF7C210AD11EF3F38111F6D98F388CF41CCBA40ABE9F0D6CBBD3118BA0588344953DF3C5E88B2CCAEDE2E692F320D20EBF16D7DB36156E617C0CC9FB2855D7FDB4C7F8638CC9830E7448D5EAE301A2810277062989841EE679E00E4E277615FEC038DE3A0A20DD7C6A2A00DFBC6A2A00DA6E2B6F404FDC6A2A00DFEC6A2A00DF7FBBB990CF2C6A2A00D8EB4FE8A0C8FB4FE8A0C95C7A6E00CF5FBBB990CD6C7A6E00CD0F896950CCCE2B6F40485CCA2A00DA1D8EEA50DFDFBBB990CA7C7A6E00CA8C7A6E00CA9C7A6E00C97C7A6E00C90B4FE8A0CFE90D59308C290D59308D1E2B6F404C5E2B6F404C6AAF18705C7AAF18705C8AAF18705BBD8EEA50DBCD8EEA50DBDD8EEA50D93CCA2A00D94CCA2A00DEFE2B6F40491B4FE8A0CE2FBBB990CE3FBBB990CBED8EEA50DA0CCA2A00DA1CCA2A00DA6B4FE8A0CA7B4FE8A0CCED8EEA50DA3CCA2A00DA4CCA2A00D84E698AD0DB8C7A6E00CD9E2B6F404E0E2B6F40486E698AD0DFDF896950C0013A60400173D0018DE0200190300AB01F40300449875044518C15F9A278109D4BBAC4E8109D408A6238109D5A63304810904460CC15F9A26303ED408A624303E0047B054004801004980A305004A80E90F004BE0A801004C80A305004D01005CAC02045E5A50FC55465BA050FC55475BA050FC55485BA0C32EFDEE5BA0C32EFDEF5BA0C2A5BC4A5BA0C2A5BC4B5BA0D4BBAC055BA0D4BBAC145BA0D4BBAC215BA0D408A3575BA0D408A37D5BA0D408A37E5BA08275487E5BA0827548425BA00060B817046506CC09A3D6303E04AE018C0125F8D500021A25F9D500011A162102200301220125FFD50025FAD5000C03E4000D2580D6000F060125F8D5000302172105050103080D06010501011C210302060125FCD50025F9D5000A25FDD50025FED5000A0D06020502050119211305020380808080100C05010D0380808080100B25FDD5000C01080005000380808080100D060307010503220101220104AC01BF012597CE002597CE002590CE0019152590CE002597CE000B033C1815210220030122012593CE0014212E2594CE002103030B220125A5CE00030F172103030B22012596CE00142103030B22012597CE00142103030B22012599CE00142103030A220125A5CE00030A1A2590CE002592CE000B031E1B15142103030A220125A4CE000380201D14210303092201259BCE0014210A2594CE002103030B2201259DCE00142103030822012593CE002103012201259ECE001421030306220103022201006800006901006A01006C987504740CC2A5BC4C303ED408A34C303E007828047912CC09A3D3303E82754864303E4E8DB16F303E047DBF010203020800050003020D0B0601030308000500020501030508000500021A03060800050003041A16030508000500021D160C0A0C060203D00F251205020A03020D0A050103D00F0C0A0603010800050003FFFFFFFF0F18030208000500021D141506042512020800050003030D05040C10030205040B0C06050306050505020A0C060603040800050003050800050003E400180C0607050703E400250A0B250A011C0C0A0314100608050303C03E0F03B8171005060388270F03DC0B100508047E5E0380010304080005000B03040D250403E4000F03140D0A2503250203030D0A0B0110060101080005000380020D0302080005000380020D172103010601250A03E4001B210D0501030A03E400250A210303DF002002250A0B0D0F0601050100800180EA49008101E003036F3139352E34362E3235332E3235333A313233353000038201706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B7970653B706F6F6C333D6578747261732E646F776E6C6F6164732E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B7970653B706F6F6C353D2A2E7072656D69756D2E736B7970653B706F6F6C363D2A2E6D756C74696D656469612E736B7970653B706F6F6C373D2A2E6D756C74696D656469612E6D657461636166653B706F6F6C383D2A2E6D756C74696D656469612E6461696C796D6F74696F6E3B706F6F6C393D2A2E6D756C74696D656469612E6D6574616F6D6E69747572653B706F6F6C31303D77686174736E65772E736B7970653B706F6F6C31313D7061792E736B7970653B706F6F6C31323D7365637572652E7061792E736B7970653B706F6F6C31333D2A2E70696373746F72653B706F6F6C31343D2A2E6D796163636F756E742E736B7970653B706F6F6C31353D2A2E62696269743B706F6F6C31363D2A2E70726F6363796265723B706F6F6C31373D747261636B696E672E6F6D6E69747572653B706F6F6C31383D676F2E736B7970653B706F6F6C31393D747261636B2E736B7970657C706F6F6C313D3139342E3139322E3139392E3235313A31323335303B706F6F6C323D3139342E3139322E3139392E3235323A31323335303B706F6F6C333D3139342E3139322E3139392E3235323A31323335303B706F6F6C343D3139342E3136352E3138382E3130313A31323335303B706F6F6C353D3139332E39352E3135342E31353A31323335313B706F6F6C363D3139342E3136352E3138382E3130303A31323335303B706F6F6C373D3139342E3136352E3138382E3130303A31323335303B706F6F6C383D3139342E3136352E3138382E3130303A31323335303B706F6F6C393D3139342E3136352E3138382E3130303A31323335303B706F6F6C31303D3230342E392E3136332E3134313A31323335303B706F6F6C31313D3139352E34362E3235332E3234353A31323335303B706F6F6C31323D3139352E34362E3235332E3234353A31323335303B706F6F6C31333D3139332E39352E3135342E31343A31323335313B706F6F6C31343D3139332E39352E3135342E31343A31323335313B706F6F6C31353D3139332E39352E3135342E31343A31323335313B706F6F6C31363D3139332E39352E3135342E31343A31323335313B706F6F6C31373D3139342E3136352E3138382E3130303A31323335303B706F6F6C31383D3139342E3136352E3138382E3130303A31323335303B706F6F6C31393D3139332E39352E3135342E31343A31323335310003B101706F6F6C313D2A2E6C6976657461622E736B7970653B706F6F6C323D7765622E6578747261732E736B797065206578747261732E646F776E6C6F6164732E736B7970653B706F6F6C333D2A2E687773746F72652E736B7970653B706F6F6C343D2A2E736B79706566696E642E736B797065202A2E6469726563746F72792E736B7970653B706F6F6C353D2A2E70696373746F7265202A2E6D796163636F756E742E736B797065202A2E6269626974202A2E70726F63637962657220747261636B2E736B79706520617070732E736B7970656173736574733B706F6F6C363D2A2E6D756C74696D656469612E736B797065202A2E6D756C74696D656469612E6D65746163616665202A2E6D756C74696D656469612E6461696C796D6F74696F6E202A2E6D756C74696D656469612E6D6574616F6D6E6974757265207777772E736B7970652077686174736E65772E736B7970653B706F6F6C373D7061792E736B797065207365637572652E7061792E736B7970653B706F6F6C383D6170692E736B7970653B706F6F6C393D63616C6C70686F6E65732E736B7970652063616C6C72617465732E736B7970653B706F6F6C31303D2A2E7072656D69756D2E736B7970653B706F6F6C31323D6C6F67732E736B7970653B706F6F6C31333D617661746172736572766963652E736B79706520636F6E74616374696D706F72742E736B7970653B706F6F6C31343D676F2E736B7970653B706F6F6C31353D747261636B696E672E6F6D6E69747572657C706F6F6C313D3139342E3139322E3139392E3235312C31323335302C312C4E4C2C77652C35302C313B706F6F6C323D3139342E3139322E3139392E3235322C31323335302C312C444B2C77652C35302C313B706F6F6C333D3139332E39352E3135342E31372C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36322C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232372C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33332C31323335312C312C4C552C77652C35302C313B706F6F6C343D3139342E3136352E3138382E3130312C31323335302C312C49452C77652C35302C313B706F6F6C353D3139332E39352E3135342E31342C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3230352C31323335312C312C4C552C77652C35302C31203231322E3138372E3137322E35392C31323335312C312C49452C77652C35302C31203231322E382E3136362E31392C31323335312C312C4C552C77652C35302C313B706F6F6C363D3139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134302C31323335302C312C43412C6E612C35302C313B706F6F6C373D3139352E34362E3235332E3234352C31323335302C312C4C552C77652C35302C31203139332E39352E3135342E31362C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36312C31323335312C312C49452C77652C35302C31203231322E382E3136362E32302C31323335302C312C4C552C77652C35302C313B706F6F6C383D3230342E392E3136332E3138342C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38392C31323335302C312C4C552C77652C35302C313B706F6F6C393D3139342E3136352E3138382E3131352C31323335302C312C49452C77652C35302C31203230342E392E3136332E3134312C31323335302C312C43412C6E612C35302C313B706F6F6C31303D3139332E39352E3135342E31352C31323335312C312C49452C77652C35302C31203231322E3138372E3137322E36302C31323335312C312C49452C77652C35302C31203139352E34362E3235332E3232362C31323335312C312C4C552C77652C35302C31203231322E382E3136362E33322C31323335312C312C4C552C77652C35302C313B706F6F6C31323D37382E3134312E3137372E37362C31323335302C312C4C552C77652C35302C313B706F6F6C31333D3230342E392E3136332E3136372C31323335302C312C43412C6E612C35302C312037382E3134312E3137372E38312C31323335302C312C4C552C77652C35302C313B706F6F6C31343D3230342E392E3136332E3136382C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C313B706F6F6C31353D3230342E392E3136332E3136392C31323335302C312C43412C6E612C35302C31203139342E3136352E3138382E3130302C31323335302C312C49452C77652C35302C3100039701736B79706566696E642E736B7970653D31372C362C382C2D33392C3139206469726563746F72792E736B7970653D31372C362C382C2D33392C31390003A60138302E3235322E38352E37302C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37312C32333435362C312C6E6C2C77652C35302C312038302E3235322E38352E37322C32333435362C312C6E6C2C77652C35302C31203139352E34362E3235332E3233382C32333435362C322C6C752C77652C35302C31203139352E34362E3235332E3233392C32333435362C322C6C752C77652C35302C31203139342E3136352E3138382E37342C32333435362C332C69652C77652C35302C31203139342E3136352E3138382E37352C32333435362C332C69652C77652C35302C31203231322E3138372E3137322E352C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E32302C32333435362C342C69652C77652C35302C31203231322E3138372E3137322E33332C32333435362C342C69652C77652C35302C31203231322E382E3136332E38372C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132352C32333435362C362C6C752C77652C35302C31203231322E382E3136332E3132362C32333435362C362C6C752C77652C35302C31203133302E3131372E37322E3132362C32333435362C372C6E6C2C77652C35302C31203133302E3131372E37322E36362C32333435362C372C6E6C2C77652C35302C310004B2010B03A09C0125B3EA010B220104A5012A24A39C012102220025A19C010401F3C2011A142103030A220125B0EA0103051A2103030B2201030522010384012B39393030303131313A37382E3134312E3137372E39363A3233343536000086010C008701880E039101000493010CC2A5BC5C2774C32EFDD927740496010CD592BC1034504E8DB5F2345006C20105F801F901FA01FB01FC010395016272617465303D31206272617465313D31206272617465323D31206272617465333D31206272617465343D31206272617465353D31206272617465363D31206272617465373D31206272617465383D31207372617465303D31207372617465313D31207372617465323D31207372617465333D31207372617465343D31207372617465353D31207372617465363D31207372617465373D31207372617465383D310003B4013139342E3136352E3138382E37373A3132333530203231322E382E3136332E3130333A31323335300000C0010100C1010103CB012E6163636573732E736B7970652E6E65740000E1010F00F0010100F101A982CA950303D50137382E3134312E3137372E33383A3132333530203230342E392E3136332E3135313A31323335300003CF0137382E3134312E3137372E36393A3132333530203230342E392E3136332E3134393A31323335300000D6010103E4013139342E3136352E3138382E38303A3132333530203231322E382E3136362E353A31323335300003E5010000F8016403F7015B574845453A204F4646203130302C20563120302C20563220305D205B496E70757445513A204F46462035302C2056312035305D205B4945513A204F46462031362C2056312031322C2056322031322C2056332031322C2056342031322C2056352031322C2056362031322C2056372031325D205B53453A204453203130302C2057494F20305D205B5345323A2044532039302C2057494F2031305D205B414D504D3A204F4C442035302C20444147432035305D205B4B54523A204F46462035302C204F4E2035305D205B49414D323A204F46462039392C204D3120312C204D3220305D0003FA0152434F4E3D350003F901302F342E322E2A2E2A2C33322C3320302F352E302E2A2E2A2C31342C3320302F352E312E2A2E3130342C342C330003A80168747470733A2F2F7777775C2E70617970616C5C2E2E3F2E3F2E3F247C68747470733A2F2F696D616765735C2E70617970616C5C2E636F6D247C68747470733A2F2F7777775C2E70617970616C6F626A656374735C2E636F6D247C68747470733F3A2F2F2E2B5C2E666263646E5C2E6E6574247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D247C68747470733F3A2F2F6368616E6E656C5C2E736B7970655C2E636F6D247C68747470733A2F2F617070735C2E736B7970655C2E636F6D247C68747470733F3A2F2F7161617070735C2E736B7970655C2E6E6574247C68747470733F3A2F2F636F6E6E6563745C2E66616365626F6F6B5C2E6E6574247C68747470733A2F2F2E2A5C2E736B7970656173736574735C2E636F6D247C68747470733A2F2F61645C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D656D65615C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F61642D617061635C2E646F75626C65636C69636B5C2E6E6574247C68747470733A2F2F737461746963323F5C2E736B7970655C2E636F6D247C68747470733A2F2F7161737461746963323F5C2E736B7970655C2E6E6574247C68747470733A2F2F7072657374617469635C2E736B7970655C2E6E6574240003FF013078313030303230343030393136333231372D642D723230342E392E3136332E3231373A38313932203078313030303230343030393136333231392D642D723230342E392E3136332E3231393A38313932203078313030303230343030393136333232312D642D723230342E392E3136332E3232313A38313932203078313030303230343030393136333232332D642D723230342E392E3136332E3232333A38313932203078313030303230343030393136333232352D642D723230342E392E3136332E3232353A38313932203078313030303230343030393136333232372D642D723230342E392E3136332E3232373A38313932203078313030303230383038383138363030352D642D723230382E38382E3138362E353A38313932203078313030303230383038383138363030372D642D723230382E38382E3138362E373A38313932203078313030303230383038383138363030392D642D723230382E38382E3138362E393A38313932203078313030303230383038383138363031312D642D723230382E38382E3138362E31313A38313932203078313030303230383038383138363031332D642D723230382E38382E3138362E31333A38313932203078313030303230383038383138363031352D642D723230382E38382E3138362E31353A38313932203078313030303230383038383138363031372D642D723230382E38382E3138362E31373A38313932203078313030303230383038383138363031392D642D723230382E38382E3138362E31393A38313932203078313030303230383038383138363032312D642D723230382E38382E3138362E32313A38313932203078313030303230383038383138363032332D642D723230382E38382E3138362E32333A38313932203078313030303230383038383138363032352D642D723230382E38382E3138362E32353A38313932203078313030303230383038383138363032372D642D723230382E38382E3138362E32373A38313932203078313030303230383038383138363032392D642D723230382E38382E3138362E32393A38313932203078313030303230383038383138363033312D642D723230382E38382E3138362E33313A38313932203078313030303230383038383138363033332D642D723230382E38382E3138362E33333A38313932203078313030303230383038383138363033352D642D723230382E38382E3138362E33353A38313932203078313030303230383038383138363033372D642D723230382E38382E3138362E33373A38313932203078313030303230383038383138363033392D642D723230382E38382E3138362E33393A38313932203078313030303230383038383138363034372D642D723230382E38382E3138362E34373A38313932203078313030303230383038383138363034392D642D723230382E38382E3138362E34393A38313932203078313030303230383038383138363035312D642D723230382E38382E3138362E35313A38313932203078313030303230383038383138363035332D642D723230382E38382E3138362E35333A38313932203078313030303230383038383138363035352D642D723230382E38382E3138362E35353A38313932203078313030303230383038383138363035372D642D723230382E38382E3138362E35373A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E35393A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36313A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36333A38313932203078313030303230383038383138363035392D642D723230382E38382E3138362E36353A38313932203078313030303230383038383138363036312D642D723230382E38382E3138362E36373A38313932203078313030303230383038383138363036332D642D723230382E38382E3138362E36393A38313932203078313030303230383038383138363037312D642D723230382E38382E3138362E37313A38313932203078313030303230383038383138363037332D642D723230382E38382E3138362E37333A38313932203078313030303230383038383138363037352D642D723230382E38382E3138362E37353A38313932203078313030303230383038383138363037372D642D723230382E38382E3138362E37373A38313932203078313030303230383038383138363037392D642D723230382E38382E3138362E37393A38313932203078313030303230383038383138363038312D642D723230382E38382E3138362E38313A38313932203078313030303230383038383138363038332D642D723230382E38382E3138362E38333A38313932203078313030303230383038383138363038352D642D723230382E38382E3138362E38353A38313932203078313030303230383038383138363038372D642D723230382E38382E3138362E38373A38313932203078313030303230383038383138363038392D642D723230382E38382E3138362E38393A38313932203078313030303230383038383138363039312D642D723230382E38382E3138362E39313A38313932203078313030303230383038383138363039332D642D723230382E38382E3138362E39333A38313932203078313030303230383038383138363039352D642D723230382E38382E3138362E39353A38313932203078313030303230383038383138363039372D642D723230382E38382E3138362E39373A38313932203078313030303230383038383138363039392D642D723230382E38382E3138362E39393A38313932203078313030303230383038383138363130312D642D723230382E38382E3138362E3130313A38313932203078313030303230383038383138363130332D642D723230382E38382E3138362E3130333A38313932203078313030303230383038383138363130352D642D723230382E38382E3138362E3130353A38313932203078313030303230383038383138363130372D642D723230382E38382E3138362E3130373A38313932203078313030303230383038383138363130392D642D723230382E38382E3138362E3130393A38313932203078313030303230383038383138363131312D642D723230382E38382E3138362E3131313A38313932203078313030303230383038383138363131332D642D723230382E38382E3138362E3131333A38313932203078313030303230383038383138363131352D642D723230382E38382E3138362E3131353A38313932203078313030303230383038383138363131372D642D723230382E38382E3138362E3131373A38313932203078323030303134393030353034353031312D642D723134392E352E34352E31313A38313932203078323030303134393030353034353031332D642D723134392E352E34352E31333A38313932203078323030303134393030353034353031352D642D723134392E352E34352E31353A38313932203078323030303134393030353034353031372D642D723134392E352E34352E31373A38313932203078323030303134393030353034353031392D642D723134392E352E34352E31393A38313932203078323030303134393030353034353032312D642D723134392E352E34352E32313A38313932203078323030303134393030353034353032332D642D723134392E352E34352E32333A38313932203078323030303134393030353034353032352D642D723134392E352E34352E32353A38313932203078323030303134393030353034353032372D642D723134392E352E34352E32373A38313932203078323030303134393030353034353032392D642D723134392E352E34352E32393A38313932203078323030303134393030353034353033312D642D723134392E352E34352E33313A38313932203078323030303134393030353034353033332D642D723134392E352E34352E33333A38313932203078323030303134393030353034353033352D642D723134392E352E34352E33353A38313932203078323030303134393030353034353033372D642D723134392E352E34352E33373A38313932203078323030303134393030353034353033392D642D723134392E352E34352E33393A38313932203078323030303134393030353034353034312D642D723134392E352E34352E34313A38313932203078323030303134393030353034353034332D642D723134392E352E34352E34333A38313932203078323030303134393030353034353034352D642D723134392E352E34352E34353A38313932203078323030303134393030353034353034372D642D723134392E352E34352E34373A38313932203078323030303134393030353034353034392D642D723134392E352E34352E34393A38313932203078323030303134393030353034353035312D642D723134392E352E34352E35313A38313932203078323030303134393030353034353035332D642D723134392E352E34352E35333A38313932203078323030303134393030353034353035352D642D723134392E352E34352E35353A38313932203078323030303134393030353034353035372D642D723134392E352E34352E35373A38313932203078323030303134393030353034353035392D642D723134392E352E34352E35393A38313932203078323030303134393030353034353036312D642D723134392E352E34352E36313A38313932203078323030303134393030353034353036332D642D723134392E352E34352E36333A38313932203078323030303134393030353034353036352D642D723134392E352E34352E36353A38313932203078323030303134393030353034353036372D642D723134392E352E34352E36373A38313932203078323030303134393030353034353036392D642D723134392E352E34352E36393A38313932203078323030303134393030353034353037312D642D723134392E352E34352E37313A38313932203078323030303134393030353034353037332D642D723134392E352E34352E37333A38313932203078323030303134393030353034353037352D642D723134392E352E34352E37353A38313932203078323030303134393030353034353037372D642D723134392E352E34352E37373A38313932203078323030303134393030353034353037392D642D723134392E352E34352E37393A38313932203078323030303134393030353034353038312D642D723134392E352E34352E38313A38313932203078323030303134393030353034353038332D642D723134392E352E34352E38333A38313932203078323030303134393030353034353038352D642D723134392E352E34352E38353A38313932203078323030303134393030353034353038372D642D723134392E352E34352E38373A38313932203078323030303134393030353034353038392D642D723134392E352E34352E38393A38313932203078323030303134393030353034353039312D642D723134392E352E34352E39313A38313932203078323030303134393030353034353039332D642D723134392E352E34352E39333A38313932203078323030303134393030353034353039352D642D723134392E352E34352E39353A38313932203078323030303134393030353034353039372D642D723134392E352E34352E39373A38313932203078323030303134393030353034353039392D642D723134392E352E34352E39393A38313932203078323030303134393030353034353130312D642D723134392E352E34352E3130313A38313932203078323030303134393030353034353130332D642D723134392E352E34352E3130333A38313932203078323030303134393030353034353130352D642D723134392E352E34352E3130353A38313932203078323030303134393030353034353130372D642D723134392E352E34352E3130373A38313932203078323030303134393030353034353130392D642D723134392E352E34352E3130393A38313932203078323030303134393030353034353131312D642D723134392E352E34352E3131313A38313932203078323030303134393030353034353131332D642D723134392E352E34352E3131333A38313932203078323030303134393030353034353131352D642D723134392E352E34352E3131353A38313932203078323030303134393030353034353131372D642D723134392E352E34352E3131373A38313932203078323030303134393030353034353131392D642D723134392E352E34352E3131393A38313932203078323030303134393030353034353132312D642D723134392E352E34352E3132313A38313932203078323030303134393030353034353132332D642D723134392E352E34352E3132333A38313932203078323030303134393030353034353132352D642D723134392E352E34352E3132353A38313932203078323030303134393030353034353132372D642D723134392E352E34352E3132373A38313932203078323030303134393030353034353132392D642D723134392E352E34352E3132393A38313932000089020A062E19AEBFD5A40B80D4B6B30280D2AFF205808CFD910B80DEB9F1048FA486F4049CA486F404D5A486F404ACC686F404C2C686F404878F87F404CEB887F404ADC487F404BCC687F404D4D087F404F9EA87F4049CF587F404C8F487F404C9F487F404CAF487F404EACCBB9C05F7CCBB9C05E694D7BB058E96D7BB05A896D7BB050094023C0095021400930201039902536B79706520546563686E6F6C6F6769657320534100008E0200008F0280BAB70300910280A30503F2013231332E3134362E3138392E3230313A3132333530203231332E3134362E3138392E3230323A3132333530203231332E3134362E3138392E3230333A3132333530203231332E3134362E3138392E3230343A3132333530203231332E3134362E3138392E3230353A3132333530203231332E3134362E3138392E3230363A3132333530203231322E3136312E382E31303A3132333530203231322E3136312E382E323A3132333530203231322E3136312E382E333A3132333530203231322E3136312E382E343A3132333530203231322E3136312E382E353A3132333530203231322E3136312E382E363A31323335300000FC010106FD0106011E64AC02A403E807009002C20103C301687474703A2F2F37392E3132352E36332E3732247C68747470733F3A2F2F2E2B5C2E66616365626F6F6B5C2E636F6D240000DE0148 + <_256>000010011AC0AA3BA66DF7FB48228AE35F9BB4A032FE4A6A898DA7A1A5AE37DC59FB3D09607F1CACD46A5DBC008DABF8F09C797DF5A8903307D04C318825CEA7C481303C655A9EEE099E9A0AF1158373B458BB8FDACB336A6EC63C043E6782688E2350B417DDDDFF96B474DAEA7D1DF3742303B79111FC752BFB5D6887A5B822F945CC761FAF6E80DE5EC60868768CB8A9F9C876137806DCEA0DD1300181558ABFDBA26592078F5F84195C526D8C7F339EF82700FD93F8FB71ADA5ED3E977D27FA52D1F489EF5DA0A9E00B146BADCBDEBFB0DFEBCD61E5B8352A49893357E0DC3A736743929DA975782EA4D8184605FD064641986C47706D264281C876F926BF58003E9E + <_3>0000100498ECF8A7A4585F76C930739A1EAE590DE96D9EF3AA9B231E67965F3F08ECFC493E1DA23ECDE17A85C94CBE034E88F9414E9BBC82F32AAFCFFB2C09F6F57A478238BAEC9EEF2BB9C67F71257722E6786D88D6400F6B7D81450FB3B6CCCC3986E3782D2387E354EBA9099331AEF510D479C6601D2383D866E2B5B525DF0BA975D58C120EFAE88C89EE365FC696CC891B77F67CFA18FDE8E95DDAC25A7C7D70FA7A1414BAE593856A658888C622836006C1C131B4B2E805554DCFA52F3EFD34C1B759BF8A302E491835DCE701E84D37ED150C8ADD699AD3DCA9F515123C5B5AD94E253E173BA3465E64A0079D5EF4E6075E66D0F5FBC3D9BC25C4E80C4CB2FE9B87040003000004D00F0005D00F050041040400B80125C20003141B14230025D50003031B14230024E100142300250003191714230025EA0003141714230025EA00011724EA00140A14230025E400030F1C14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E10025E10003A006100A0309031725000325180C0A25C20003140B0C03040D0A03882725C3000C0A03E43225C4000C0A0602050228038407DC08FA1E0601050102050203FA1E1C0603250028061D1E1F202122060105010205010503050141060300636F756E74206279207175616C697479000001CC080002040003000004010005010501410603006261647175616C69747920636F756E742062792076657273696F6E000001D6080002070003000004010005010501410603006261647175616C6974792073756D2062792076657273696F6E000001E0080002070003000004010005010500410304005424E400142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025E40025E40028043CB401D804901C060105010205014106030073756D206F66206C61737463616C6C206475726174696F6E73000001B009000201000300000480A3050005B054050141060300636F756E74206279206C61737463616C6C206475726174696F6E000001BA090002050003000004010005010500410204005025EB00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EB0028031E32D0000601050102050141060300636F756E742062792073797374656D20637075207573616765000001940A0002040003000004010005010500410204004F25EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050141060300636F756E742062792070726F63657373206370752075736167650000019E0A0002040003000004010005010500410304006824C20014230024E60014230025E600011A14230025EC00011C142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A14230025EC0028030F1E320601050102050125C2000501410603006A6974746572636F756E742062792070726F6365737320637075207573616765000001F80A0002040003000004010005010501410603006A69747465722062792070726F6365737320637075207573616765000001820B0002040003000004D00F0005D00F0500410304004424E700142300250003191714230025EA0003141714230025EA00011724EA00140A14230025FC00011A24FF000A14230025FF00011A142300258001011A1423000225E700050141060300706F74656E7469616C207463702066616C6C6261636B73000001DC0B00020100030000040100050105014106030061637475616C207463702066616C6C6261636B73000001E60B00020100030000040100050105004103040056240C142300250C030A1814230025EA0003141714230025EA00011724EA00140A14230024E70014230025E700011A14230024E50014230025E500011C0602250C29050306070809280401020405060105010205010502050141060300636F756E74206279206E617474797065000001C00C0002050003000004010005010501410603007564706661696C75726573206279206E617474797065000001CA0C0002050003000004010005010500410204001B25D90014230025D90025DA000B0602050228030102040601050102050141060300636F756E74206279206E726F666D756C74696368617473000001A40D0002040003000004010005010500410304001425F700011C14230025000319171423000225F90005014106030075736572732077686F206861766520636F6D706C65746564204943000001880E0002010003000004010005010501410603006C617374204943207969656C6420676C6F62616C73756D000001920E0002010003000004E8070005500500410304001224F60014230025000319171423000225F60005014106030075736572732077686F206861766520494320737570706F7274000001EC0E0002010003000004010005010501410603004943207374617274757020636F756E7420676C6F62616C73756D000001F60E00020100030000046400051405004102040025240C142300250C030A18142300250C011C142300250C280802030405060708090601050102050141060300636F756E74206279206E617474797065000001D00F0002090003000004010005010500410404001A250003191714230025E20025E30025FC00280201020601050102050141060300766964656F2073656E642063617061626C650000019811000201000300000401000501050141060300766964656F20706172616C6C656C2063616C6C730000019911000201000300000414000502050141060300636F756E7420627920766964656F2063616C6C73206D616465000001A2110002030003000004010005010500410204003A250003191714230025EA0003141714230025EA00011724EA00140A14230024E50014230025E50003031914230025E50028030102030601050102050141060300636F756E742062792073747265616D7472616E73706F7274000001FC11000204000300000401000501050041090400E00125C20003141B25E400030F1C1514230024E100142300250003191714230025EA0003141725EA0001171514230025FF002580010A011A14230025E60003031A25E50003031A1514230024F5001423002412142300249F0114230025C30025E10025E10003A006100A03A0060B0309031725000325180C0A25C20003140B0C03040D0A2512030A0C251025F5001703CC080C0A1C160602020502250003231B241D150603050305020503150503251D03808080808080808080011D14150603050305020503150503251D038080808080808080C0011D1415060305030502050315050141060300706F74656E7469616C2052555F756E65787065637465645F62616471000001E01200020100030000040100050105014106030061637475616C2052555F756E65787065637465645F62616471000001EA1200020100030000040100050105014106030042435020706F74656E7469616C2052555F756E65787065637465645F62616471000001F4120002010003000004010005010501410603004243502061637475616C2052555F756E65787065637465645F62616471000001FE12000201000300000401000501050141060300424350203220706F74656E7469616C2052555F756E65787065637465645F62616471000001881300020100030000040100050105014106030042435020322061637475616C2052555F756E65787065637465645F626164710000019213000201000300000401000501050141060300424350203420706F74656E7469616C2052555F756E65787065637465645F626164710000019C130002010003000004010005010501410603004243502031362061637475616C2052555F756E65787065637465645F62616471000001A6130002010003000004010005010500410304000825B801011C25B701050141060300757365727320696E207075626C6963206368617473000001C4130002010003000004010005010501410603007075626C69632063686174206D6573736167657320696E206C617374206D696E757465000001CE1300020100030000046400050A0500410404005F248E0114230024D5001423002500032B1B1423002500032B1C250D03021C16250E03FFFFFFFF0F1D03B4E2C8F10217250E0380808080100D03B4E2C8F10217151614230025D500280219C80106010501020501258E010501258E0103880E1C050141060300636F756E742062792062756464696573000001A814000203000300000401000501050141060300617661696C6162696C697479206167652062792062756464696573000001B2140002030003000004C0FC150005A099020501410603006C6F6E6720617661696C6162696C697479206167652062792062756464696573000001BC140002030003000004010005010500410204003324C000142300250003191714230025F301290300E5C68583B7AEDE36F2CAB9A3A7AE983806020502280202030601050125C00005014106030073696D756C74616E656F75732063616C6C7320706572206E616D6573706163650000018C15000203000300000419000519050041020400C50125C00006020502142300250006030503031917142300050303231B06040504210302200225A1010605050421030502200225A2010606030606070505021A050503021A160506021A15210305072002010607050203021B050603021B152103050720020206070502021A050603021B15210305072002030206070502021A050503041A15210305072002030306070502021A050503031A15210305072002030406070502021A050503051A152103050720020305060705072806010203040506060105010205014106030063616C6C6572733A207332735F313120636F6E665F686F737420636F6E665F636C69656E7420736B7970656F757420736B797065696E20766F6963656D61696C20756E6B6E6F776E000001F015000207000300000401000501 + <_4>000010052A0B6759B71FBC1EF05BE97DFEA4EE6C1E15AF19ED70DEC1130B14C13CE41246D302B9662592907E3CA508A57702B5C00C2A05170857FA22012E0F235B425B4D919B23A541D3AD6E948FC634DE71A29493634884DFD5E9D89C5D951CBCD71B9B3ABFD3C4E2779BB1817D76E7C223CA36BD75A6A05B730AF138057E4048B2FFDD522BB588EC0B9D3E014BF9E354EB608150BC613C739D9E8C7465F05F047FAF7AFA3EE89B9B58BF0FC35F07B55CF3E4B59A7C4ED48B1C0C7F0305E6AC2E80AAEAD6064EB6ACDC1806FCE0B5CB66F0840DA7F0FE7B228E3898E3E42A9AFEFE13DDF019EF8D8F02A631AF2615BBC6E1EDB65C89A775F642C88109E6247EC4B463DC302E2A2E323000050541020006020307322E302E2A2E3100050541030006020307322E302E2A2E3200000AE4ED8009050541030006020307322E302E2A2E33000009B3E6CC990B050541040006020307322E302E2A2E3400000AE4ED8009000BA00B050541030006020308322E302E2A2E35000307322E302E2A2E3900050541040006020308322E302E2A2E39000307322E302E2A2E313100000AE4ED8009050541040006020308322E302E2A2E3131000307322E302E2A2E3135000009E6CC99B306050541050006020308322E302E2A2E3135000307322E302E2A2E323000000AE4ED8009000BA00B050041050303557067726164655465737433000301332E302E302E3130300003044E6963654272616E6400050541040006020307332E302E302E2A0003074E6963654272616E6400000AE4ED8009050541040006020307322E302E302E2A0003074E6963654272616E6400000AE4ED80090500410E0303557067726164655465737433000301332E302E302E31303000050541040006020307332E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307322E302E302E39390003074F746865724272616E6400000AE4ED8009050541040006020307332E302E302E39380003074F746865724272616E64000009B3E6CC990B050541040006020307322E302E302E39380003074F746865724272616E64000009B3E6CC990B050541050006020307332E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541050006020307322E302E302E39370003074F746865724272616E6400000AE4ED8009000BA00B050541030006020307332E302E302E393900000AE4ED8009050541030006020307322E302E302E393900000AE4ED8009050541030006020307332E302E302E3938000009B3E6CC990B050541030006020307322E302E302E3938000009B3E6CC990B050541040006020307332E302E302E393700000AE4ED8009000BA00B050541040006020307322E302E302E393700000AE4ED8009000BA00B0500410303033130303031000301302E302E302E313000050541020006020307302E302E302E3900 + <_5>00001006739CA527EF827847E16F23CD52458C3EBA3460A42935EC6948BEFA626B49E3BDF279FC62486E2DDBCA19609ED23D31F4E5175920F282AD74A74A997C3909E67B622480C68A058E886C7D5F3C40954880D7798CD61CEA0FBAFB389BE5B2B8A887348F7AADB4DF642B194B814047CDA0E698EDDE61DFA731DCA5883A76F913D8C94066718054E85ADA7AE009F2B2A9AF762FDCB9B6CAF64C156911E3AB172CFD795F66FB6E8E15048A54E4AB17979D6C447DEBADE75CC6F606050D980061112AFF9AE7C7BF8065D711949E41FA4C8B6CBF0916BB395B3E186A7D617D353C6BFFC687FE79475DFA095D113D70B828FB597BC3665B7C9C3669CA9CBE5D308D3FC23803044E45544745415200050541020006040307302E392E302E2A000500410503033130303033000301312E302E302E3137000304534D4300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E312E302E313000030442454C4B494E00050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E3137000304454447452D434F524500050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303033000301312E302E302E31330003044C4F474954454300050541020006040307302E392E302E313200050541020006020307302E392E302E3230000500410503033130303035000301312E342E38382E31333636000304544F50434F4D00050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410503033130303035000301312E342E38382E313336360003045043484F4D4500050541020006040307312E342E38382E3133353600050541020006020307312E342E38382E31333635000500410403033130303036000301302E302E302E313000050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303037000301312E302E312E330003045445434F00050541020006040307312E302E302E3800050541020006020307312E302E312E31000500410503033130303038000301302E392E332E3339370003044C494E4B53595300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003044E45544745415200050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410503033130303038000301302E392E332E3339370003045048494C49505300050541020006040307302E382E332E2A00050541020006020307302E392E332E333932000500410403033130303130000301302E392E302E31310003044C494E4B53595300050541020006040307302E392E302E3130000500410403033130303130000301302E392E302E313100030442554646414C4F00050541020006040307302E392E302E3130000500410503033130303132000301312E302E302E310003044353544E00050541020006040307302E302E302E3500050541020006020307302E302E302E39000500410503033130303133000301302E302E332E3234000304414B00050541020006040307302E302E312E323400050541020006020307302E302E322E3234000500410303033130303134000301312E372E34332E33382E3200050541020006040307312E372E32332E32372E34000500410503033130303135000301312E322E31372E30000304415A5445434800050541020006040307312E322E31312E3000050541020006020307312E322E31352E30000500410303033130303230000301312E302E302E343700050541030006020308312E302E302E3233000307312E302E302E3233000500410403033130303234000301332E322E302E323800050541030006040308332E302E302E35000307332E302E302E3500050541030006020308332E312E302E31000307332E322E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E494300050541020006040307302E302E302E3100050541020006020307302E302E302E38000500410503033130303232000301302E302E302E3900030450414E41534F4E4943434F4E53554D455200050541020006040307302E302E302E3100050541020006020307302E302E302E3800 + + 1 + + 400 + + + + 8118 + 39,64,8184 + 37,50,13164 + + 1 + + 1 + + + -1431699456 + -1431699456 + 1610612735 + + 41C801050041050200D9AF0D45D9E900010400028788BCED0400038788BCED04000400050041050200BB0AB3FDD1A40001040002B7DCBCED040003B7DCBCED040004000500410502005C3766C2DA6B00010400029FB2BCED0400039FB2BCED04000400050041050200D9F8DC20CA33000104000296DAAAED04000396DAAAED0400040005004105020063847B3765900001040002D794BDED040003D794BDED040004000500410502004E80142FD3C70001040002CF86BDED040003CF86BDED04000400050041050200C3B213EA24A50001040002BF89BBED040003BF89BBED040004000500410502006FFEF1BA804C0001040002CF86BDED040003CF86BDED0400040005004105020052ED923CB3A700010400028788BCED0400038788BCED040004000500410502005243330D305B000104000283FFB2ED04000383FFB2ED040004000500410502006FF9438E9E5D0001040002CF86BDED040003CF86BDED04000400050041050200585515F19D77000104000283FFB2ED04000383FFB2ED04000400050041050200729EE3A8DD460001040002CF86BDED040003CF86BDED040004000500410502004572795D3BB300010400029FB2BCED0400039FB2BCED040004000500410502009F94D72CABA40001040002CF86BDED040003CF86BDED0400040005004105020095052D9C81090001040002B7DCBCED040003B7DCBCED040004000500410502005859A15FD7FC0001040002DC8FB5ED040003DC8FB5ED0400040005004105020059D7AB3EBBFB0001020002F8FABCED040003CF86BDED04000400050041050200BB2481B9390E0001040002CF86BDED040003CF86BDED0400040005004105020059D7F395A7BA0001040002B7DCBCED040003B7DCBCED040004000500410502006DC4BEF5D52E0001040002B0DFBAED040003B0DFBAED040004000500410502004B6E709CF4290001040002B7DCBCED040003B7DCBCED040004000500410502007A7D5CEC2B8D0001040002CF86BDED040003CF86BDED040004000500410502006FFFA8AFB19D0001040002B7DCBCED040003B7DCBCED040004000500410502003E4475A07A6F0001040002B7DCBCED040003B7DCBCED040004000500410502003EDD8384A4F90001040002BF89BBED040003BF89BBED04000400050041050200560FBFA4E4900001040002B7DCBCED040003B7DCBCED04000400050041050200C24FAEEE43F10001040002B3CEB5ED040003B3CEB5ED040004000500410502004F378778C6F30001040002CF86BDED040003CF86BDED04000400050041050200C94418BB0EDF0001040002B7DCBCED040003B7DCBCED040004000500410502003B75A58BECB30001040002CF86BDED040003CF86BDED04000400050041050200772A7A0908890001040002CF86BDED040003CF86BDED0400040005004105020048BB63586DE100010400029088BCED0400039088BCED040004000500410502005544F881BEDA000104000283FFB2ED04000383FFB2ED040004000500410502005B4C1468EDF80001040002B7DCBCED040003B7DCBCED04000400050041050200538BAF3F934F0001040002B3CEB5ED040003B3CEB5ED0400040005004105020055D6F93A4FD70001040002D7B3BBED040003D7B3BBED04000400050041050200D5D64561E55F00010400028788BCED0400038788BCED0400040005004105020046ADF229B8570001040002CF86BDED040003CF86BDED04000400050041050200D5151C19FFD600010200029FB2BCED040003B7DCBCED04000400050041050200973CA35DB82400010400029FB2BCED0400039FB2BCED04000400050041050200C249E5B953700001040002CF86BDED040003CF86BDED04000400050041050200722C69D8C4F500010400029FB2BCED0400039FB2BCED0400040005004105020058CBB311F2400001040002DC8FB5ED040003DC8FB5ED040004000500410502004BB7A090766E0001040002CF86BDED040003CF86BDED040004000500410502007DEF80FBEBD90001040002EFDDBBED040003EFDDBBED0400040005004105020076A03698F87A0001040002CF86BDED040003CF86BDED0400040005004105020050E5DFDD0C700001040002CF86BDED040003CF86BDED040004000500410502004D4C85E0CEC80001040002CF86BDED040003CF86BDED040004000500410502006FEA6BCD92A10001020002F8FABCED040003CF86BDED0400040005004105020043BAA930F28600010400029FB2BCED0400039FB2BCED04000400050041050200722DB82DDB780001040002CF86BDED040003CF86BDED0400040005004105020052E995118B9F0001040002CF86BDED040003CF86BDED040004000500410502005403013B36D20001040002EFDDBBED040003EFDDBBED04000400050041050200B27C0C920B260001040002B7DCBCED040003B7DCBCED04000400050041050200D9AF0997A7450001040002BCD9AAED040003BCD9AAED04000400050041050200BC00130BB5F60001040002CF86BDED040003CF86BDED04000400050041050200591FF23B53830001040002CF86BDED040003CF86BDED04000400050041050200557EB01367590001040002CF86BDED040003CF86BDED04000400050041050200505F157093A2000102000297A4BCED04000397A4BCED040004000500410502003A036C495C670001040002CF86BDED040003CF86BDED0400040005004105020050D8CF0B7D480001040002B7DCBCED040003B7DCBCED040004000500410502004E34E4D0FF250001040002B7DCBCED040003B7DCBCED040004000500410502007A1E50A46E770001040002CF86BDED040003CF86BDED040004000500410502005F18C666CBB80001040002EFDDBBED040003EFDDBBED04000400050041050200C19335603A9E0001040002DC8FB5ED040003DC8FB5ED0400040005004105020097142BD7DF890001040002AFDFBAED040003AFDFBAED0400040005004105020052F3355FFED400010400029FB2BCED0400039FB2BCED04000400050041050200BCBA857EECDF0001040002D7B3BBED040003D7B3BBED04000400050041050200729259D605EF0001040002CF86BDED040003CF86BDED04000400050041050200BEC2F57655B300010400029FB2BCED0400039FB2BCED040004000500410502005BD905C8304B0001020002A8EEBBED0400038788BCED0400040005004105020055F2C0360F360001040002EFDDBBED040003EFDDBBED0400040005004105020082C01DB9605D00010400028788BCED0400038788BCED04000400050041050200BC73B8FB30360001040002CF86BDED040003CF86BDED0400040005004105020050390E32DF8B0001040002B0DFBAED040003B0DFBAED040004000500410502005BCE8A2D7B8000010400028788BCED0400038788BCED0400040005004105020042292BB45D2D0001040002CF86BDED040003CF86BDED040004000500410502004F1A354DCA9A00010400029FB2BCED0400039FB2BCED04000400050041050200591C1D7F0EC900010400028788BCED0400038788BCED04000400050041050200722E9D2CCB030001040002CF86BDED040003CF86BDED04000400050041050200443AB71D3F8A0001040002CF86BDED040003CF86BDED0400040005004105020018DEF34EB70600010400028788BCED0400038788BCED0400040005004105020097215860080F00010400029FB2BCED0400039FB2BCED040004000500410502007229C156A49E0001040002B7DCBCED040003B7DCBCED040004000500410502003A72EDECB0250001040002B3F7B4ED040003B3F7B4ED04000400050041050200D52F8CD18F640001040002E285B0ED040003E285B0ED040004000500410502006B0325208B4C0001040002EFDDBBED040003EFDDBBED040004000500410502005164424285660001040002938AB5ED040003938AB5ED04000400050041050200D4E9D6AB12F80001040002AFDFBAED040003AFDFBAED0400040005004105020059B3090F459C0001040002FCDDAAED040003FCDDAAED04000400050041050200BC10C41E7AAB0001040002CF86BDED040003CF86BDED040004000500410502009F9532B560C100010400028788BCED0400038788BCED0400040005004105020050EA7B4A63750001040002CF86BDED040003CF86BDED0400040005004105020045A658245E790001040002CF86BDED040003CF86BDED0400040005004105020047E3059299620001040002CF86BDED040003CF86BDED0400040005004105020081164AFC3B450001040002CF86BDED040003CF86BDED040004000500410502005703C3FC60FF00010400028788BCED0400038788BCED0400040005004105020063FAEB02F39300010400028788BCED0400038788BCED040004000500410502005714F2D9F6650001020002AFDFBAED040003ECE7BAED04000400050041050200505F1B22B00D0001040002CF86BDED040003CF86BDED0400040005004105020062C2F2A80C7900010400029FB2BCED0400039FB2BCED04000400050041050200425CA6CCD1FF0001040002CF86BDED040003CF86BDED0400040005004105020084C778D4AB110001040002CF86BDED040003CF86BDED040004000500410502005106437CD3B60001040002CF86BDED040003CF86BDED0400040005004105020058506B2B47D40001040002D7B3BBED040003D7B3BBED04000400050041050200DD70204563390001040002B7DCBCED040003B7DCBCED040004000500410502005CFFA5BE4A0000010200028888BCED040003F8FABCED0400040005004105020089BD8692E0400001040002B7DCBCED040003B7DCBCED040004000500410502004AC12BB2AB8D0001040002B7DCBCED040003B7DCBCED04000400050041050200DB555CBAEE6B0001040002CF86BDED040003CF86BDED0400040005004105020095052D8F81090001020002A7FDBCED040003CF86BDED04000400050041050200473AA0E1C9110001020002A7FDBCED040003CF86BDED040004000500410502004EFA971D2E4C0001040002B7DCBCED040003B7DCBCED04000400050041050200BCE6C5A829D900010400029E90B5ED0400039E90B5ED0400040005004105020051699F18DC540001040002D7B3BBED040003D7B3BBED040004000500410502005CFB85D7E6460001040002B3CEB5ED040003B3CEB5ED0400040005004105020052D17CE5A9840001040002BF89BBED040003BF89BBED0400040005004105020054DD54C818F20001040002CF86BDED040003CF86BDED040004000500410502005C3555EBDC670001040002B7DCBCED040003B7DCBCED0400040005004105020051D92EE554370001040002BF89BBED040003BF89BBED0400040005004105020095549556182D0001040002CF86BDED040003CF86BDED040004000500410502005419C1F7F52A0001040002B3CEB5ED040003B3CEB5ED040004000500410502008C7259638E1D0001040002B7DCBCED040003B7DCBCED04000400050041050200516745231C2200010400029FB2BCED0400039FB2BCED0400040005004105020055FB3DEAE2380001040002B7DCBCED040003B7DCBCED040004000500410502005D5470BCB83A00010400028788BCED0400038788BCED0400040005004105020054C6D511E6810001040002CF86BDED040003CF86BDED0400040005004105020062A7FAC0119000010200028788BCED0400038888BCED040004000500410502007225A1DCFB1A00010200028788BCED0400038888BCED04000400050041050200708B358CF15C00010400028788BCED0400038788BCED04000400050041050200D9A293C3FE550001040002AFDFBAED040003AFDFBAED04000400050041050200722119BAFCB600010400029FB2BCED0400039FB2BCED0400040005004105020054369C95EAC60001040002CF86BDED040003CF86BDED04000400050041050200AE74419813810001040002B7DCBCED040003B7DCBCED0400040005004105020048C613BC68510001040002EFDDBBED040003EFDDBBED04000400050041050200516E168D638B0001040002EFDDBBED040003EFDDBBED040004000500410502001819CFB484D20001040002CF86BDED040003CF86BDED04000400050041050200ADE013B3E9F10001040002CF86BDED040003CF86BDED040004000500410502005C708ABFAC890001040002B3CEB5ED040003B3CEB5ED04000400050041050200BC81882E891C0001040002B7DCBCED040003B7DCBCED0400040005004105020057785543EB480001040002CF86BDED040003CF86BDED040004000500410502006FF0CE6CB4500001040002CF86BDED040003CF86BDED040004000500410502005CE13B7199D4000102000283ADE7E304000383ADE7E30400040005004105020063F610137D170001040002B7DCBCED040003B7DCBCED04000400050041050200DC887BC89E210001040002CF86BDED040003CF86BDED040004000500410502005D9324151E7F0001020002A7FDBCED040003CF86BDED04000400050041050200BC02D363924D00010400029FB2BCED0400039FB2BCED040004000500410502004F28848E1AC50001040002CF86BDED040003CF86BDED0400040005004105020054C606DD0D260001040002D984B5ED040003D984B5ED04000400050041050200D5F586558C850001040002BF89BBED040003BF89BBED0400040005004105020082582B0468CF00010400028788BCED0400038788BCED040004000500410502005CE21BB9BD7C00010400029FB2BCED0400039FB2BCED0400040005004105020059A9ACE3BC02000104000296DAAAED04000396DAAAED040004000500410502005557DB28EDA300010400028788BCED0400038788BCED0400040005004105020076ABA00FF52C0001040002CF86BDED040003CF86BDED0400040005004105020052185C5CB8440001040002B7DCBCED040003B7DCBCED04000400050041050200441402A770A800010200028788BCED0400038888BCED04000400050041050200516623CC99760001040002CF86BDED040003CF86BDED040004000500410502005A3D6D867C2A0001040002BF89BBED040003BF89BBED04000400050041050200BC70864FCE530001040002B3F7B4ED040003B3F7B4ED040004000500410502005E9C9B4E7A740001040002CF86BDED040003CF86BDED0400040005004105020058ABF63F0EA70001040002FCDDAAED040003FCDDAAED040004000500410502005556BDBE86AC000104000286FFB2ED04000386FFB2ED0400040005004105020059D0D49C9B8000010400028788BCED0400038788BCED0400040005004105020059A934952E920001040002B3F7B4ED040003B3F7B4ED040004000500410502007220ABEC82C80001040002B7DCBCED040003B7DCBCED04000400050041050200807AB45544310001040002BF89BBED040003BF89BBED04000400050041050200187A8DFCCDCF0001040002BF89BBED040003BF89BBED04000400050041050200616B5C35801000010400028788BCED0400038788BCED040004000500410502005ABCE5EAE3790001040002938AB5ED040003938AB5ED0400040005004105020048DF5F3311D10001020002F8FABCED040003CF86BDED04000400050041050200D3146B24D6340001040002CF86BDED040003CF86BDED0400040005004105020059037023AC7D00010400029FB2BCED0400039FB2BCED040004000500410502003EDD92C929340001040002BF89BBED040003BF89BBED040004000500410502004C4EB0C1270D0001040002CF86BDED040003CF86BDED04000400050041050200BCA300CD17370001040002CF86BDED040003CF86BDED040004000500410502005BC42D9E789A0001040002D7B3BBED040003D7B3BBED04000400050041050200589755D3E75F0001020002D884B5ED040003B3CEB5ED040004000500410502007A7CC86B21530001040002CF86BDED040003CF86BDED040004000500410502005352A2DA24D300010400028788BCED0400038788BCED0400040005004105020058C9F9B6A86F0001040002B7DCBCED040003B7DCBCED040004000500410502005706A79DEAE60001020002AFDFBAED040003ECE7BAED0400040005004105020082D1B28F7A3A0001040002CF86BDED040003CF86BDED0400040005004105020052217343E79C0001040002CF86BDED040003CF86BDED0400040005004105020082CEA3A289FE000104000296DAAAED04000396DAAAED04000400050041050200D9E0FF79D1180001040002B7DCBCED040003B7DCBCED0400040005004105020052FD31513EE90001040002938AB5ED040003938AB5ED0400040005004105020052128CCDBA7C00010400029FB2BCED0400039FB2BCED040004000500410502006FB83DA167580001040002CF86BDED040003CF86BDED040004000500410502002E14B9387F540001020002B7DCBCED040003CF86BDED040004000500410502004F7E6F098A990001040002CF86BDED040003CF86BDED040004000500410502005D98B7099E1F0001040002B7DCBCED040003B7DCBCED04000400050041050200722A7476317600010400029FB2BCED0400039FB2BCED04000400050041050200BC18CE5EBDA10001020002AFDFBAED040003ECE7BAED040004000500410502005CF890CF3E270001040002B7DCBCED040003B7DCBCED040004000500410502008D72AE6DBEE30001040002CF86BDED040003CF86BDED0400040005004105020076A6D8E9EAAB0001040002CF86BDED040003CF86BDED04000400050041050200721B63925A140001040002CF86BDED040003CF86BDED040004000500410502007608B348A53A0001040002CF86BDED040003CF86BDED04000400 + + 0 + + -645574544 + 0 + 47500 + + 1 + + + 217.133.80.112:1076 217.133.80.112:47500 217.133.80.112:1083 217.133.80.112:1083 217.133.80.112:49734 + 7 + + <_1303289856>6C81442204F3D9855070B98CAE5879A505F3D9855070B98C4D4320134B66D9855070B98C5F4E60ED0D34D98550700434 + <_1303293952>4287274ED659D9855070B98C4287274ED74BD9855070B98C4287274EC15CD9855070B98C4287274ECE92D9855070B98C4287274EA75BD9855070B98C4287274E4B98D9855070B98C4287274EAA2DD9855070B98C4287274EA175D9855070B98C4287274ED735D9855070B98C4287274EAE25D9855070B98C4287274E1A2BD9855070B98C3D7D44372576D9855070B98CCF86DF304366D9855070B98C3D2E02A2259CD9855070B98C4287274EB98CD9855070B98C + <_1303298048>2E3363049108D9855070B98C2E3795FA3202D9855070B98C2E2F6F42E86DD9855070B98CB4B0620AA528D9855070B98C + <_1303306240>5F1894D8122BD9855070B98C2E40484969A3D9855070B98CD592A70A5566D9855070B98C2E26119F8DBED9855070B98C2E3754264E48D9855070B98C + <_1303314432>4D2BFFCAEC6CD9855070043B54BAD08D05E0D9855070B98C9D9D4DA11995D9855070B98C59584CCBB5CED9855070B98C972AC71733DDD9855070B98C + <_1303322624>5F3B0DCEB535D9855070043BD5150C1746D3D9855070B98C4D4B8646EF29D9855070B98CD5152F4D12BBD9855070B98C + <_1303326720>59D0D11D89DCD9855070C2462E755D8E1E97D9855070B98C2E492F875789D9855070B98C2E378784E9C6D9855070B98C2E2F6F6B48FCD9855070B98C + + + <_1303289856>9A4A56D31C619325C6601C71B23E13FDFAF5CA49F15C34A4E33F239B524D6BBC226021F010D2270A3B48DFA2E8CDB6FD37531B1118DB2D471CB980D0 + <_1303293952>D5A2186D0B45088ADDFA7B626C0904CED47E3DF13172672AED483E1EAD69DB781ABEC0D8812B1B5EFF91BC28C67FB5A3404D875A + <_1303298048>DB0EC5161D10171C7C6A4C7109DD + <_1303302144>5379BD98 + <_1303306240>88B19442A48D863ED54D712EEC36D53127BCE36653FE + <_1303310336>1908404B0F7BA3BE952CB1C533456D3CDA410BCB774AF93880FB8BD8C110 + <_1303314432>4B015AD444DD027FD3F61B2A51A53BA0 + <_1303322624>878BAF81A9F053B39E35081485E24B4EDA5F79D37E176C409B6E237A336451F42CFA7CEC013C98A18B51 + <_1303326720>CFB137906F6CCE77246BD5B6B434875570B1F9B9140C85D5114EE6953110B04F3557C0D1686D46A9F69106521979AE49E19F8622F93A + <_1303330816>BA4B81F735FDCDA4E4EF57ACF8A37051C66401E41CA4E562A5A49ACC2E246CCE + + + + 1 + + + 1 + + + 0 + + + 1 + + + + 9BF92EA4B417A7F6 + + + 4102030E322F322E302E302E37322F31373400000FF6EB9ADC04 + + + 0 + + + + 2 + en + + 357 + 258 + 0 + 0 + + 0 + + diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + +

+ 35716ecf:2 + 98e6c103:0 +

+ +
+
+ + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + +
+ + + skypopen + + + 0 + 2 + 2 + 2 + +
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameA/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + +

+ 35716ecf:2 + 98e6c103:0 +

+ +
+
+ + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + +
+ + + skypopen + + + 0 + 2 + 2 + 2 + +
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameB/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.lck b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.lck new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml new file mode 100644 index 0000000000..f7af8873ad --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/config.xml @@ -0,0 +1,74 @@ + + + + + 300 + 1800 + 63 + + + 41010300676D6172757A7A3400 + 1268962216 + + + 0 + 0 + 1303202372 + 0 + +

+ 35716ecf:2 + 98e6c103:0 +

+ +
+
+ + 1 + 3 + 65535 + 1266110339 + + + 1 + + + 1 + + + 1000000166 + 1303166852 + 1303209779 + + + 1267114269 + + 2 + + 4109008620EBA4DDDB0400FA0100009E2001009420FB09008520B1A58BDD04008120CCD9E6E3040093209B0A00F501820200F801A3B608 + + + 1267114267 + 11 + 4263C0064DD5ACF9A03594DAB928D2B81510 + + + + <_59908281a5de1c9c602d40fe1f815199a1601558ebea75accdfae8b723bb342e>1303296179 23160:21600:1303209779 9589:7200:1303209779 8707:21600:1303209779 + +
+ + + skypopen + + + 0 + 2 + 2 + 2 + +
diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat new file mode 100644 index 0000000000..fc7f2b1150 --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/httpfe/cookies.dat @@ -0,0 +1 @@ +B \ No newline at end of file diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat new file mode 100644 index 0000000000..b8b96d8431 Binary files /dev/null and b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/index2.dat differ diff --git a/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/main.lock b/src/mod/endpoints/mod_skypopen/configs/skype-client-configuration-dir-template/skypeclient01/skypenameC/main.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml b/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml index f4e1c0ec5a..c03fd718e0 100644 --- a/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml +++ b/src/mod/endpoints/mod_skypopen/configs/skypopen.conf.xml @@ -1,6 +1,5 @@ - @@ -8,6 +7,7 @@ + diff --git a/src/mod/endpoints/mod_skypopen/install/install.pl b/src/mod/endpoints/mod_skypopen/install/install.pl new file mode 100755 index 0000000000..f4c04f3aef --- /dev/null +++ b/src/mod/endpoints/mod_skypopen/install/install.pl @@ -0,0 +1,373 @@ +#!/usr/bin/perl + +my $myname ; +my $skype_download_url = "http://mirrors.kernel.org/archlinux/community/os/i686/skype-oss-2.0.0.72-2-i686.pkg.tar.gz"; +my $skype_download_pkg = "skype-oss-2.0.0.72-2-i686.pkg.tar.gz"; +my $skype_binary_dir = "/usr/bin"; +my $skype_download_dir = "/tmp/skype_download"; +my $skype_share_dir = "/usr/share/skype"; +my $freeswitch_modules_config_dir = "/usr/local/freeswitch/conf/autoload_configs"; +my $skypopen_sound_driver_dir = "/usr/local/freeswitch/skypopen/skypopen-sound-driver-dir"; +my $skype_config_dir = "/usr/local/freeswitch/skypopen/skype-clients-configuration-dir"; +my $skype_startup_dir = "/usr/local/freeswitch/skypopen/skype-clients-startup-dir"; +my $skype_symlinks_dir = "/usr/local/freeswitch/skypopen/skype-clients-symlinks-dir"; +my $skype_clients_to_be_launched = "5"; +my $skype_clients_starting_number = "100"; +my $multi_skypeusername = "one"; +my $skype_username = "your_own_skype_username"; +my $skype_password = "your_own_skype_password"; +my @skype_username_array; +my @skype_password_array; +my $sure = "nope"; + +### PRESENTATION ### +system("clear"); +printf("\n"); +printf("This is the interactive installation helper for Skypopen\n"); +printf("(http://wiki.freeswitch.org/wiki/Mod_skypopen_Skype_Endpoint_and_Trunk)\n"); +printf("\n"); +printf("Especially designed for FreeSWITCH\n"); +printf("by Giovanni Maruzzelli\n"); +printf("\n"); +printf("Please direct all questions or issues to the FreeSWITCH mailing list or Jira\n"); +printf("(http://lists.freeswitch.org/mailman/listinfo or http://jira.freeswitch.org)\n"); +printf("\n"); +printf("\n"); +printf("I'll ask you questions, giving default answers in square brackets [] if any\n"); +printf("To accept the default, just press Enter\n"); +printf("You'll be prompted to confirm your answer at each step\n"); +printf("At the end of questions, before I do anything, I'll let you review it all\n"); +printf("To abort, press Ctrl-C\n"); +printf("\n"); +printf("\n"); +printf("Let's start asking your name, so you see how the question/answer works\n"); +printf("To accept the default, just press Enter\n"); +$myname = &promptUser("Enter your name ", "Giovanni"); +system("clear"); +printf("\n"); +printf("OK %s, GREAT! Let's start real questions! (At any time, Ctrl-C to abort)\n", $myname); +printf("\n"); +printf("At the end of questions, before I do anything, I'll let you review all your answers, don't worry! :)\n"); +printf("\n"); +printf("\n"); + +### ASKING QUESTIONS ### + +printf("I'm about to download the Skype client for Linux version 2.0.0.72 for OSS\n"); +printf("nicely repackaged by Arch Linux with official Skype permission.\n"); +printf("I need to create a directory to download and unpack the Skype client\n"); +printf("To accept the default, just press Enter\n"); +$skype_download_dir = &promptUser("Enter the full path of the Skype download directory ", "$skype_download_dir"); +system("clear"); +printf("\n"); +printf("I'm about to install the Skype client\n"); +printf("I would put the binary in $skype_binary_dir and the associated files in $skype_share_dir\n"); +printf("Location of associated files is mandatory ($skype_share_dir)\n"); +printf("Location of binary is recommended ($skype_binary_dir)\n"); +printf("To accept the default, just press Enter\n"); +$skype_binary_dir = &promptUser("Enter the directory full path for Skype client binary ", "$skype_binary_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the FreeSWITCH configuration file for mod_skypopen (skypopen.conf.xml)\n"); +printf("I need to know where to put it, eg: where is the FreeSWITCH modules' config dir\n"); +printf("To accept the default, just press Enter\n"); +$freeswitch_modules_config_dir = &promptUser("Enter the directory full path for FreeSWITCH modules' config files ", "$freeswitch_modules_config_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the directory where to put our fake sound driver\n"); +printf("Location of fake sound driver directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skypopen_sound_driver_dir = &promptUser("Enter the directory full path for fake sound driver ", "$skypopen_sound_driver_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the configuration directory needed by the Skype clients\n"); +printf("Location of Skype clients configuration directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skype_config_dir = &promptUser("Enter the directory full path for Skype clients config ", "$skype_config_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create a directory where I'll put the Skype clients startup script\n"); +printf("Location of Skype clients startup script directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skype_startup_dir = &promptUser("Enter the directory full path for Skype clients startup script ", "$skype_startup_dir"); +system("clear"); +printf("\n"); +printf("I'm about to create the directory for symlinks needed by the Skype clients startup script\n"); +printf("Location of symlinks directory is where you like it more :)\n"); +printf("To accept the default, just press Enter\n"); +$skype_symlinks_dir = &promptUser("Enter the directory full path for Skype clients symlinks ", "$skype_symlinks_dir"); +system("clear"); +printf("\n"); +printf("How many Skype clients (channels) do you want to launch?\n"); +printf("Each Skype client will be one channel to FreeSWITCH and use approx 70MB of ram\n"); +printf("A quad core CPU can very easily support 20 or more Skype clients\n"); +printf("Each Skype client allows one concurrent call\n"); +printf("Eg: if you plan to have a max of 10 concurrent (outbound and/or inbound) Skype calls then enter 10\n"); +printf("To accept the default, just press Enter\n"); +$skype_clients_to_be_launched = &promptUser("Enter how many Skype clients will be launched ", "$skype_clients_to_be_launched"); +system("clear"); +printf("\n"); + + +while(1){ + printf("You want all of the Skype clients to use the same Skype login (skypeusername)?\n"); + printf("eg: you want all of your skypopen channels to be Bob on the Skype network, or you want channel skype01 to be Bob, channel skype02 to be Alice, etc?\n"); + printf("Please answer 'one' for all channels using the same Skype login (you'll be asked just one time for Skype login and password) or 'multi' for being asked for each channel\n"); + printf("\n"); + $multi_skypeusername = &promptUser("Enter 'one' or 'multi' ", "$multi_skypeusername"); + system("clear"); + printf("\n"); + if($multi_skypeusername eq "one" or $multi_skypeusername eq "multi"){ + last; + } +} + + +if($multi_skypeusername eq "one"){ + printf("I need the Skype username which will be used by ALL the Skype clients to be launched\n"); + printf("(That's the one-word you registered as login to the Skype network)\n"); + printf("This installer will create the needed files to launch concurrently many (or one) instances of it\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_username = &promptUser("Enter the Skype clients username ", "$skype_username"); + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_username_array[$count] = $skype_username; + } + system("clear"); + printf("\n"); + printf("I need the Skype password which will be used by ALL the Skype clients to be launched\n"); + printf("(That's the one-word you registered as password to the Skype network)\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_password = &promptUser("Enter the Skype clients password ", "$skype_password"); + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_password_array[$count] = $skype_password; + } + system("clear"); +} else { + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_client_extension = $skype_clients_starting_number + $count ; + printf("I need the Skype username which will be used by the Skype client for channel 'skype$skype_client_extension'\n"); + printf("(That's the one-word you registered as login to the Skype network)\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_username = &promptUser("Enter the Skype username for channel 'skype$skype_client_extension'", "$skype_username"); + $skype_username_array[$count] = $skype_username; + system("clear"); + printf("\n"); + printf("I need the Skype password which will be used by the Skype client 'skype$skype_client_extension'\n"); + printf("(That's the one-word you registered as password to the Skype network)\n"); + printf("\n"); + printf("NB: DON'T ACCEPT the DEFAULT, write YOUR OWN\n"); + $skype_password = &promptUser("Enter the Skype password for '$skype_username'", "$skype_password"); + $skype_password_array[$count] = $skype_password; + system("clear"); + } + +} + +### GETTING FINAL APPROVAL ### +printf("\n"); +printf("Please check the following values:\n"); +printf("\n"); +printf("directory for downloading and unpacking Skype client:\n'$skype_download_dir'\n"); +printf("directory for Skype client binary:\n'$skype_binary_dir'\n"); +printf("directory for FreeSWITCH modules' configs:\n'$freeswitch_modules_config_dir'\n"); +printf("directory for fake sound driver:\n'$skypopen_sound_driver_dir'\n"); +printf("directory for Skype clients configs:\n'$skype_config_dir'\n"); +printf("directory for Skype clients startup script:\n'$skype_startup_dir'\n"); +printf("directory for Skype clients symlinks:\n'$skype_symlinks_dir'\n"); +printf("how many Skype clients to launch: '$skype_clients_to_be_launched'\n"); +if($multi_skypeusername eq "one"){ + printf("Skype login: '$skype_username'\n"); + printf("Skype password: '$skype_password'\n"); +}else { + for($count=1; $count <= $skype_clients_to_be_launched ; $count++){ + $skype_client_extension = $skype_clients_starting_number + $count ; + printf("channel='skype$skype_client_extension' Skype login='$skype_username_array[$count]' Skype password='$skype_password_array[$count]'\n"); + } +} + +$sure = &promptUser("Are you sure you like the values? Write 'sure' for yes ", "$sure"); +if($sure ne "sure"){ + printf("No problem, please relaunch the installer and begin again\n"); + exit 0; +} +system("clear"); + +printf("\n"); +printf("GREAT! Please stand back, I'm working...\n"); +printf("\n"); + +#### EXECUTION ### + +system("mkdir -p $skype_download_dir"); +system("cd $skype_download_dir ; wget -c $skype_download_url"); +system("cd $skype_download_dir ; tar -xzf $skype_download_pkg"); + +system("mkdir -p $skype_binary_dir"); +system("cd $skype_download_dir/usr/bin ; cp skype $skype_binary_dir/"); +system("mkdir -p $skype_share_dir"); +system("cd $skype_download_dir/usr/share/skype ; cp -a avatars $skype_share_dir/"); +system("cd $skype_download_dir/usr/share/skype ; cp -a sounds $skype_share_dir/"); +system("cd $skype_download_dir/usr/share/skype ; cp -a lang $skype_share_dir/"); + + +system("mkdir -p $skypopen_sound_driver_dir"); +system("cp ../oss/skypopen.ko $skypopen_sound_driver_dir/"); +system("mkdir -p $skype_config_dir"); +system("mkdir -p $skype_startup_dir"); +system("mkdir -p $skype_symlinks_dir"); + +system("echo \"\" > $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + + +system("echo \"#!/bin/sh\" > $skype_startup_dir/start_skype_clients.sh"); +system("echo \"#Unload possible ALSA sound modules that would conflict with our OSS fake module\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"rmmod snd_pcm_oss\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"rmmod snd_mixer_oss\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"rmmod snd_seq_oss\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"sleep 1\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"#Create the inode our fake sound driver will use\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"mknod /dev/dsp c 14 3\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"#Load our OSS fake module\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo \"insmod $skypopen_sound_driver_dir/skypopen.ko\" >> $skype_startup_dir/start_skype_clients.sh"); +system("echo >> $skype_startup_dir/start_skype_clients.sh"); +system("echo >> $skype_startup_dir/start_skype_clients.sh"); + + +for ($count = 1; $count <= $skype_clients_to_be_launched; $count++) { + $skype_client_extension = $skype_clients_starting_number + $count ; + $skype_login=$skype_username_array[$count]; + $skype_passwd=$skype_password_array[$count]; + system("ln -s $skype_binary_dir/skype $skype_symlinks_dir/skype$skype_client_extension"); + system("mkdir -p $skype_config_dir/skype$skype_client_extension"); + system("cp -a ../configs/skype-client-configuration-dir-template/skypeclient01/shared.* $skype_config_dir/skype$skype_client_extension"); + system("cp -a ../configs/skype-client-configuration-dir-template/skypeclient01/skypenameA $skype_config_dir/skype$skype_client_extension/$skype_login"); + + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + if($multi_skypeusername ne "one"){ + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + } + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + system("echo \" \" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + + system("echo \"#start the fake X server on the given port\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"/usr/bin/Xvfb :$skype_client_extension -ac -nolisten tcp -screen 0 640x480x8 &\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"sleep 3\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"# start a Skype client instance that will connect to the X server above, and will login to the Skype network using the 'username password' you send to it on stdin.\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"su root -c \\\"/bin/echo '$skype_login $skype_passwd'| DISPLAY=:$skype_client_extension $skype_symlinks_dir/skype$skype_client_extension --dbpath=$skype_config_dir/skype$skype_client_extension --pipelogin &\\\"\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo \"sleep 7\" >> $skype_startup_dir/start_skype_clients.sh"); + system("echo >> $skype_startup_dir/start_skype_clients.sh"); +} + +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); +system("echo \"\" >> $freeswitch_modules_config_dir/skypopen.conf.xml"); + +system("echo \"exit 0\" >> $skype_startup_dir/start_skype_clients.sh"); + + +printf("\n"); +printf("SUCCESS!!!\n"); +printf("\n"); + + +#=========================================================================# + + +#-------------------------------------------------------------------------# +# promptUser, a Perl subroutine to prompt a user for input. +# Copyright 2010 Alvin Alexander, devdaily.com. +# This code is shared here under the +# Creative Commons Attribution-ShareAlike Unported 3.0 license. +# See http://creativecommons.org/licenses/by-sa/3.0/ for more information. +#-------------------------------------------------------------------------# + +# Original at: http://www.devdaily.com/perl/edu/articles/pl010005 +# Modified to get confirmations by Giovanni Maruzzelli + +#----------------------------( promptUser )-----------------------------# +# # +# FUNCTION: promptUser # +# # +# PURPOSE: Prompt the user for some type of input, and return the # +# input back to the calling program. # +# # +# ARGS: $promptString - what you want to prompt the user with # +# $defaultValue - (optional) a default value for the prompt # +# # +#-------------------------------------------------------------------------# + +sub promptUser { + +#-------------------------------------------------------------------# +# two possible input arguments - $promptString, and $defaultValue # +# make the input arguments local variables. # +#-------------------------------------------------------------------# + + local($promptString,$defaultValue) = @_; + local $input; + local $confirm; + local $gave; + +#-------------------------------------------------------------------# +# if there is a default value, use the first print statement; if # +# no default is provided, print the second string. # +#-------------------------------------------------------------------# + + while(1){ + printf("\n"); + if ($defaultValue) { + print $promptString, "\n[", $defaultValue, "]: "; + } else { + print $promptString, ": "; + } + + $| = 1; # force a flush after our print + $input = ; # get the input from STDIN (presumably the keyboard) + + +#------------------------------------------------------------------# +# remove the newline character from the end of the input the user # +# gave us. # +#------------------------------------------------------------------# + + chomp($input); + + $gave = $input ? $input : $defaultValue; + print("You gave: '$gave'\nIt's OK? Please answer 'Y' for yes or 'N' for not [N]: "); + $| = 1; # force a flush after our print + $confirm = ; + chomp($confirm); + if($confirm eq "Y" or $confirm eq "y"){ + last; + } + } +#-----------------------------------------------------------------# +# if we had a $default value, and the user gave us input, then # +# return the input; if we had a default, and they gave us no # +# no input, return the $defaultValue. # +# # +# if we did not have a default value, then just return whatever # +# the user gave us. if they just hit the key, # +# the calling routine will have to deal with that. # +#-----------------------------------------------------------------# + + if ("$defaultValue") { + return $input ? $input : $defaultValue; # return $_ if it has a value + } else { + return $input; + } +} + diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index eac0a67943..e86c86dc11 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -462,6 +462,7 @@ static switch_status_t channel_on_init(switch_core_session_t *session) left in the initial state, nothing will happen. */ switch_channel_set_state(channel, CS_ROUTING); DEBUGA_SKYPE("%s CHANNEL INIT %s\n", SKYPOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session)); + switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str)); return SWITCH_STATUS_SUCCESS; } @@ -937,16 +938,21 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch char *p = digit_str; switch_channel_t *channel = switch_core_session_get_channel(session); - while (p && *p) { - switch_dtmf_t dtmf; - dtmf.digit = *p; - dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION; - switch_channel_queue_dtmf(channel, &dtmf); - p++; + if(channel){ + + while (p && *p) { + switch_dtmf_t dtmf; + dtmf.digit = *p; + dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION; + switch_channel_queue_dtmf(channel, &dtmf); + p++; + } + NOTICA("DTMF DETECTED: [%s] new_dtmf_timestamp: %u, delta_t: %u\n", SKYPOPEN_P_LOG, digit_str, (unsigned int) new_dtmf_timestamp, + (unsigned int) (new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp)); + tech_pvt->old_dtmf_timestamp = new_dtmf_timestamp; + }else{ + WARNINGA("NO CHANNEL ?\n", SKYPOPEN_P_LOG); } - NOTICA("DTMF DETECTED: [%s] new_dtmf_timestamp: %u, delta_t: %u\n", SKYPOPEN_P_LOG, digit_str, (unsigned int) new_dtmf_timestamp, - (unsigned int) (new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp)); - tech_pvt->old_dtmf_timestamp = new_dtmf_timestamp; } } } @@ -1733,6 +1739,7 @@ static switch_status_t load_config(int reload_type) switch_threadattr_create(&skypopen_api_thread_attr, skypopen_module_pool); switch_threadattr_detach_set(skypopen_api_thread_attr, 0); switch_threadattr_stacksize_set(skypopen_api_thread_attr, SWITCH_THREAD_STACKSIZE); + //switch_threadattr_priority_increase(skypopen_api_thread_attr); switch_thread_create(&globals.SKYPOPEN_INTERFACES[interface_id].skypopen_api_thread, skypopen_api_thread_attr, skypopen_do_skypeapi_thread, &globals.SKYPOPEN_INTERFACES[interface_id], skypopen_module_pool); @@ -1742,6 +1749,7 @@ static switch_status_t load_config(int reload_type) switch_threadattr_create(&skypopen_signaling_thread_attr, skypopen_module_pool); switch_threadattr_detach_set(skypopen_signaling_thread_attr, 0); switch_threadattr_stacksize_set(skypopen_signaling_thread_attr, SWITCH_THREAD_STACKSIZE); + //switch_threadattr_priority_increase(skypopen_signaling_thread_attr); switch_thread_create(&globals.SKYPOPEN_INTERFACES[interface_id]. skypopen_signaling_thread, skypopen_signaling_thread_attr, skypopen_signaling_thread_func, &globals.SKYPOPEN_INTERFACES[interface_id], skypopen_module_pool); @@ -2135,40 +2143,45 @@ int dtmf_received(private_t *tech_pvt, char *value) switch_channel_t *channel = NULL; session = switch_core_session_locate(tech_pvt->session_uuid_str); - channel = switch_core_session_get_channel(session); + if (session) { + channel = switch_core_session_get_channel(session); - if (channel) { + if (channel) { - if (switch_channel_test_flag(channel, CF_BRIDGED) - && !switch_true(switch_channel_get_variable(channel, "skype_add_outband_dtmf_also_when_bridged"))) { + if (switch_channel_test_flag(channel, CF_BRIDGED) + && !switch_true(switch_channel_get_variable(channel, "skype_add_outband_dtmf_also_when_bridged"))) { - NOTICA - ("received DTMF '%c' on channel %s, but we're BRIDGED, so we DO NOT relay it out of band. If you DO want to relay it out of band when bridged too, on top of audio DTMF, set the channel variable 'skype_add_outband_dtmf_also_when_bridged=true' \n", - SKYPOPEN_P_LOG, value[0], switch_channel_get_name(channel)); + NOTICA + ("received DTMF '%c' on channel %s, but we're BRIDGED, so we DO NOT relay it out of band. If you DO want to relay it out of band when bridged too, on top of audio DTMF, set the channel variable 'skype_add_outband_dtmf_also_when_bridged=true' \n", + SKYPOPEN_P_LOG, value[0], switch_channel_get_name(channel)); + } else { + + + + switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) }; + DEBUGA_SKYPE("received DTMF %c on channel %s\n", SKYPOPEN_P_LOG, dtmf.digit, switch_channel_get_name(channel)); + switch_mutex_lock(tech_pvt->flag_mutex); + switch_channel_queue_dtmf(channel, &dtmf); + switch_set_flag(tech_pvt, TFLAG_DTMF); + switch_mutex_unlock(tech_pvt->flag_mutex); + } } else { - - - - switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) }; - DEBUGA_SKYPE("received DTMF %c on channel %s\n", SKYPOPEN_P_LOG, dtmf.digit, switch_channel_get_name(channel)); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_channel_queue_dtmf(channel, &dtmf); - switch_set_flag(tech_pvt, TFLAG_DTMF); - switch_mutex_unlock(tech_pvt->flag_mutex); + WARNINGA("received %c DTMF, but no channel?\n", SKYPOPEN_P_LOG, value[0]); } - } else { - WARNINGA("received %c DTMF, but no channel?\n", SKYPOPEN_P_LOG, value[0]); + switch_core_session_rwunlock(session); + }else{ + WARNINGA("received %c DTMF, but no session?\n", SKYPOPEN_P_LOG, value[0]); } - switch_core_session_rwunlock(session); return 0; } int start_audio_threads(private_t *tech_pvt) { - switch_threadattr_t *thd_attr = NULL; + switch_threadattr_t *tcp_srv_thread_thd_attr = NULL; + switch_threadattr_t *tcp_cli_thread_thd_attr = NULL; tech_pvt->begin_to_write = 0; tech_pvt->begin_to_read = 0; @@ -2194,12 +2207,13 @@ int start_audio_threads(private_t *tech_pvt) switch_core_timer_sync(&tech_pvt->timer_write); - switch_threadattr_create(&thd_attr, skypopen_module_pool); - switch_threadattr_detach_set(thd_attr, 0); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_create(&tcp_srv_thread_thd_attr, skypopen_module_pool); + switch_threadattr_detach_set(tcp_srv_thread_thd_attr, 0); + switch_threadattr_stacksize_set(tcp_srv_thread_thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_increase(tcp_srv_thread_thd_attr); switch_mutex_lock(tech_pvt->mutex_thread_audio_srv); //DEBUGA_SKYPE("debugging_hangup srv lock\n", SKYPOPEN_P_LOG); - if (switch_thread_create(&tech_pvt->tcp_srv_thread, thd_attr, skypopen_do_tcp_srv_thread, tech_pvt, skypopen_module_pool) == SWITCH_STATUS_SUCCESS) { + if (switch_thread_create(&tech_pvt->tcp_srv_thread, tcp_srv_thread_thd_attr, skypopen_do_tcp_srv_thread, tech_pvt, skypopen_module_pool) == SWITCH_STATUS_SUCCESS) { DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPOPEN_P_LOG); } else { ERRORA("failed to start tcp_srv_thread thread.\n", SKYPOPEN_P_LOG); @@ -2210,12 +2224,13 @@ int start_audio_threads(private_t *tech_pvt) switch_mutex_unlock(tech_pvt->mutex_thread_audio_srv); //DEBUGA_SKYPE("debugging_hangup srv unlock\n", SKYPOPEN_P_LOG); - switch_threadattr_create(&thd_attr, skypopen_module_pool); - switch_threadattr_detach_set(thd_attr, 0); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_create(&tcp_cli_thread_thd_attr, skypopen_module_pool); + switch_threadattr_detach_set(tcp_cli_thread_thd_attr, 0); + switch_threadattr_stacksize_set(tcp_cli_thread_thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_increase(tcp_cli_thread_thd_attr); switch_mutex_lock(tech_pvt->mutex_thread_audio_cli); //DEBUGA_SKYPE("debugging_hangup cli lock\n", SKYPOPEN_P_LOG); - if (switch_thread_create(&tech_pvt->tcp_cli_thread, thd_attr, skypopen_do_tcp_cli_thread, tech_pvt, skypopen_module_pool) == SWITCH_STATUS_SUCCESS) { + if (switch_thread_create(&tech_pvt->tcp_cli_thread, tcp_cli_thread_thd_attr, skypopen_do_tcp_cli_thread, tech_pvt, skypopen_module_pool) == SWITCH_STATUS_SUCCESS) { DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPOPEN_P_LOG); } else { ERRORA("failed to start tcp_cli_thread thread.\n", SKYPOPEN_P_LOG); diff --git a/src/mod/endpoints/mod_skypopen/asterisk/Makefile b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/Makefile similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/Makefile rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/Makefile diff --git a/src/mod/endpoints/mod_skypopen/asterisk/README b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/README similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/README rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/README diff --git a/src/mod/endpoints/mod_skypopen/asterisk/chan_skypiax.c b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/chan_skypiax.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/chan_skypiax.c rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/chan_skypiax.c diff --git a/src/mod/endpoints/mod_skypopen/asterisk/cyg_no_pthread_kill.c b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/cyg_no_pthread_kill.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/cyg_no_pthread_kill.c rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/cyg_no_pthread_kill.c diff --git a/src/mod/endpoints/mod_skypopen/asterisk/skypiax.conf b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.conf similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/skypiax.conf rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.conf diff --git a/src/mod/endpoints/mod_skypopen/asterisk/skypiax.h b/src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.h similarity index 100% rename from src/mod/endpoints/mod_skypopen/asterisk/skypiax.h rename to src/mod/endpoints/mod_skypopen/old-stuff/asterisk/skypiax.h diff --git a/src/mod/endpoints/mod_skypopen/alsa/dummy.c b/src/mod/endpoints/mod_skypopen/old-stuff/dummy.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/alsa/dummy.c rename to src/mod/endpoints/mod_skypopen/old-stuff/dummy.c diff --git a/src/mod/endpoints/mod_skypopen/alsa/pcm_lib.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/alsa/pcm_lib.c rename to src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c diff --git a/src/mod/endpoints/mod_skypopen/alsa/pcm_native.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c similarity index 100% rename from src/mod/endpoints/mod_skypopen/alsa/pcm_native.c rename to src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c diff --git a/src/mod/endpoints/mod_skypopen/oss/Makefile b/src/mod/endpoints/mod_skypopen/oss/Makefile index 8df20f68c5..40b25f0e25 100644 --- a/src/mod/endpoints/mod_skypopen/oss/Makefile +++ b/src/mod/endpoints/mod_skypopen/oss/Makefile @@ -1,6 +1,6 @@ # Comment/uncomment the following line to disable/enable debugging #DEBUG = y -#LDDINC=/usr/src/linux-headers-2.6.32-26-server/include +#LDDINC= # Add your debugging flag (or not) to CFLAGS ifeq ($(DEBUG),y) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 10a210a574..465480e055 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -43,12 +43,13 @@ #include "skypopen.h" /* local definitions */ + /* * Our parameters which can be set at load time. */ int skypopen_major = SKYPOPEN_MAJOR; -int skypopen_minor = 3; +int skypopen_minor = SKYPOPEN_MINOR; int skypopen_nr_devs = SKYPOPEN_NR_DEVS; /* number of bare skypopen devices */ module_param(skypopen_major, int, S_IRUGO); @@ -61,9 +62,6 @@ MODULE_LICENSE("Dual BSD/GPL"); static struct skypopen_dev *skypopen_devices; /* allocated in skypopen_init_module */ static int unload = 0; -#ifdef CENTOS -#define HRTIMER_MODE_REL HRTIMER_REL -#endif// CENTOS #ifndef WANT_HRTIMER void my_timer_callback_inq( unsigned long data ) @@ -84,7 +82,7 @@ void my_timer_callback_outq( unsigned long data ) } #else// WANT_HRTIMER -#ifndef CENTOS +#ifndef CENTOS_5 static enum hrtimer_restart my_hrtimer_callback_inq( struct hrtimer *timer_inq ) { struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); @@ -113,7 +111,7 @@ static enum hrtimer_restart my_hrtimer_callback_outq( struct hrtimer *timer_outq return HRTIMER_RESTART; } -#else// CENTOS +#else// CENTOS_5 static int my_hrtimer_callback_inq( struct hrtimer *timer_inq ) { struct skypopen_dev *dev = container_of(timer_inq, struct skypopen_dev, timer_inq); @@ -138,7 +136,7 @@ static int my_hrtimer_callback_outq( struct hrtimer *timer_outq ) return HRTIMER_RESTART; } -#endif// CENTOS +#endif// CENTOS_5 #endif// WANT_HRTIMER /* The clone-specific data structure includes a key field */ @@ -159,10 +157,6 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) { struct skypopen_listitem *lptr; #ifdef WANT_HRTIMER -#if 0 - ktime_t ktime_inq; - ktime_t ktime_outq; -#endif //0 #endif// WANT_HRTIMER list_for_each_entry(lptr, &skypopen_c_list, list) { @@ -181,6 +175,7 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) init_waitqueue_head(&lptr->device.inq); init_waitqueue_head(&lptr->device.outq); + #ifndef WANT_HRTIMER setup_timer( &lptr->device.timer_inq, my_timer_callback_inq, (long int)lptr ); setup_timer( &lptr->device.timer_outq, my_timer_callback_outq, (long int)lptr ); @@ -188,19 +183,6 @@ static struct skypopen_dev *skypopen_c_lookfor_device(dev_t key) mod_timer( &lptr->device.timer_inq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); printk( "Starting skypopen OSS driver write timer (%dms) skype client:(%d)\n", SKYPOPEN_SLEEP, current->tgid ); mod_timer( &lptr->device.timer_outq, jiffies + msecs_to_jiffies(SKYPOPEN_SLEEP) ); -#else// WANT_HRTIMER -#if 0 - ktime_inq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); - hrtimer_init( &lptr->device.timer_inq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); - lptr->device.timer_inq.function = &my_hrtimer_callback_inq; - hrtimer_start( &lptr->device.timer_inq, ktime_inq, HRTIMER_MODE_REL ); - - ktime_outq = ktime_set( 0, SKYPOPEN_SLEEP * 1000000); - hrtimer_init( &lptr->device.timer_outq, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); - lptr->device.timer_outq.function = &my_hrtimer_callback_outq; - hrtimer_start( &lptr->device.timer_outq, ktime_outq, HRTIMER_MODE_REL ); -#endif - #endif// WANT_HRTIMER /* place it in the list */ @@ -249,14 +231,12 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { DEFINE_WAIT(wait); - size_t written; struct skypopen_dev *dev = filp->private_data; if(unload) return -1; #ifdef WANT_HRTIMER -#if 1 if(dev->timer_inq_started == 0){ ktime_t ktime_inq; @@ -266,39 +246,13 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL ); dev->timer_inq_started = 1; } -#endif #endif// WANT_HRTIMER - //printk("READ\n"); prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&dev->inq, &wait); - - if (!count) - return 0; - - if (!access_ok(VERIFY_WRITE, buf, count)) - return -EFAULT; - - written = 0; - while (count) { - unsigned long unwritten; - size_t chunk = count; - - if (chunk > PAGE_SIZE) - chunk = PAGE_SIZE; /* Just for latency reasons */ - unwritten = __clear_user(buf, chunk); - written += chunk - unwritten; - if (unwritten) - break; - if (signal_pending(current)) - return written ? written : -ERESTARTSYS; - buf += chunk; - count -= chunk; - cond_resched(); - } - return written ? written : -EFAULT; + return count; } static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, @@ -311,7 +265,6 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t return -1; #ifdef WANT_HRTIMER -#if 1 if(dev->timer_outq_started == 0){ ktime_t ktime_outq; @@ -321,10 +274,8 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL ); dev->timer_outq_started = 1; } -#endif #endif// WANT_HRTIMER - //printk("WRITE\n"); prepare_to_wait(&dev->outq, &wait, TASK_INTERRUPTIBLE); schedule(); @@ -448,6 +399,7 @@ int skypopen_init_module(void) dev_t dev = 0; printk("skypopen OSS driver loading (www.freeswitch.org)\n"); + /* * Get a range of minor numbers to work with, asking for a dynamic * major unless directed otherwise at load time. diff --git a/src/mod/endpoints/mod_skypopen/oss/skypopen.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h index 2324e448cb..de38c791c9 100644 --- a/src/mod/endpoints/mod_skypopen/oss/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/oss/skypopen.h @@ -1,6 +1,7 @@ /* * skypopen.h -- definitions for the char module * + * Copyright (C) 2010 Giovanni Maruzzelli * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet * Copyright (C) 2001 O'Reilly & Associates * @@ -18,22 +19,30 @@ #ifndef _SKYPOPEN_H_ #define _SKYPOPEN_H_ +#include #include /* needed for the _IOW etc stuff used later */ -#define SKYPOPEN_BLK 960 -#define SKYPOPEN_SLEEP 10 - -#define CENTOS - -#ifndef SKYPOPEN_MAJOR -#define SKYPOPEN_MAJOR 14 /* dynamic major by default */ -#endif - -#ifndef SKYPOPEN_NR_DEVS -#define SKYPOPEN_NR_DEVS 1 /* skypopen0 through skypopen3 */ -#endif +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) +#define CENTOS_5 +#define WANT_HRTIMER /* undef this only if you don't want to use High Resolution Timers (why?) */ +#endif /* CentOS 5.x */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) #define WANT_HRTIMER +#endif /* HRTIMER */ + +#define SKYPOPEN_BLK 1920 +#define SKYPOPEN_SLEEP 20 + + +#define SKYPOPEN_MAJOR 14 /* dynamic major by default */ +#define SKYPOPEN_MINOR 3 /* dynamic major by default */ +#define SKYPOPEN_NR_DEVS 1 /* not useful, I'm too lazy to remove it */ + +#ifdef CENTOS_5 +#define HRTIMER_MODE_REL HRTIMER_REL +#endif// CENTOS_5 + struct skypopen_dev { struct cdev cdev; /* Char device structure */ wait_queue_head_t inq; /* read and write queues */ @@ -56,16 +65,4 @@ struct skypopen_dev { extern int skypopen_major; /* main.c */ extern int skypopen_nr_devs; - -/* - * Prototypes for shared functions - */ - -//ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, - //loff_t *f_pos); -//ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count, - //loff_t *f_pos); -//int skypopen_ioctl(struct inode *inode, struct file *filp, - //unsigned int cmd, unsigned long arg); - #endif /* _SKYPOPEN_H_ */ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/98-osscuse.rules b/src/mod/endpoints/mod_skypopen/osscuse/98-osscuse.rules deleted file mode 100644 index c1430fd5c0..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/98-osscuse.rules +++ /dev/null @@ -1,7 +0,0 @@ -# Since these devices are not part of 'sound' subsystem the group is forced -# to audio by name -# /dev/cuse can stay mode 0660 root:root since osspd is run as root -# and drops privileges to user level when opened by user -KERNEL=="dsp", GROUP="audio" -KERNEL=="mixer", GROUP="audio" -KERNEL=="adsp", GROUP="audio" diff --git a/src/mod/endpoints/mod_skypopen/osscuse/LICENSE b/src/mod/endpoints/mod_skypopen/osscuse/LICENSE deleted file mode 100644 index d511905c16..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, 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 or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -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 give any other recipients of the Program a copy of this License -along with the Program. - -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 Program or any portion -of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -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 Program, 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 Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) 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; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, 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 executable. However, as a -special exception, the source code 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. - -If distribution of executable or 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 counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. 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 Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program 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 to -this License. - - 7. 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 Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program 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 Program. - -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. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program 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. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 Program -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 Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, 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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), 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 Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. 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 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 2 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, 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. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/src/mod/endpoints/mod_skypopen/osscuse/Makefile b/src/mod/endpoints/mod_skypopen/osscuse/Makefile deleted file mode 100644 index a42d37a8a3..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# These can be overridden if needed -# DESTDIR is completely respected -CC := gcc -AR := ar -CFLAGS := -Wall $(CFLAGS) -XLDFLAGS := $(LDFLAGS) -LDFLAGS := -L. -lossp $(LDFLAGS) -prefix := /usr/local -DESTDIR := -UDEVDIR := /etc/udev/rules.d - -ifeq "$(origin OSSPD_CFLAGS)" "undefined" -OSSPD_CFLAGS := $(shell pkg-config --cflags fuse) -endif - -ifeq "$(origin OSSPD_LDFLAGS)" "undefined" -OSSPD_LDFLAGS := $(shell pkg-config --libs fuse) -endif - -ifeq "$(origin OSSP_PADSP_CFLAGS)" "undefined" -OSSP_PADSP_CFLAGS := $(shell pkg-config --cflags libpulse) -endif - -ifeq "$(origin OSSP_PADSP_LDFLAGS)" "undefined" -OSSP_PADSP_LDFLAGS := $(shell pkg-config --libs libpulse) -endif - -ifeq "$(origin OSSP_ALSAP_CFLAGS)" "undefined" -OSSP_ALSAP_CFLAGS := $(shell pkg-config --libs alsa) -endif - -ifeq "$(origin OSSP_ALSAP_LDFLAGS)" "undefined" -OSSP_ALSAP_LDFLAGS := $(shell pkg-config --libs alsa) -endif - -headers := ossp.h ossp-util.h ossp-slave.h - -#all: osspd ossp-padsp ossp-alsap -all: osspd ossp-alsap - -install: - mkdir -p $(DESTDIR)$(prefix)/sbin - install -m755 osspd ossp-padsp ossp-alsap $(DESTDIR)$(prefix)/sbin - mkdir -p $(DESTDIR)$(UDEVDIR) - install -m644 98-osscuse.rules $(DESTDIR)$(UDEVDIR) - -libossp.a: ossp.c ossp.h ossp-util.c ossp-util.h ossp-slave.c ossp-slave.h - $(CC) $(CFLAGS) -c -o ossp.o ossp.c - $(CC) $(CFLAGS) -c -o ossp-util.o ossp-util.c - $(CC) $(CFLAGS) -c -o ossp-slave.o ossp-slave.c - $(AR) rc $@ ossp.o ossp-util.o ossp-slave.o - -osspd: osspd.c libossp.a $(headers) - $(CC) $(CFLAGS) $(OSSPD_CFLAGS) -o $@ $< $(OSSPD_LDFLAGS) $(LDFLAGS) - -ossp-padsp: ossp-padsp.c libossp.a $(headers) - $(CC) $(CFLAGS) $(OSSP_PADSP_CFLAGS) -o $@ $< $(OSSP_PADSP_LDFLAGS) $(LDFLAGS) - -ossp-alsap: ossp-alsap.c libossp.a $(headers) - $(CC) $(CFLAGS) $(OSSP_ALSAP_CFLAGS) -o $@ $< $(OSSP_ALSAP_LDFLAGS) $(LDFLAGS) - -osstest: osstest.c - $(CC) $(CFLAGS) -o $@ $< $(XLDFLAGS) - -test: osstest - @./osstest - -clean: - rm -f *.o *.a osspd ossp-padsp ossp-alsap osstest diff --git a/src/mod/endpoints/mod_skypopen/osscuse/README b/src/mod/endpoints/mod_skypopen/osscuse/README deleted file mode 100644 index 6b716c76e4..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/README +++ /dev/null @@ -1,119 +0,0 @@ - - OSS Proxy - emulate OSS device using CUSE - - Copyright (C) 2008-2009 SUSE Linux Products GmbH - Copyright (C) 2008-2009 Tejun Heo - -1. What is it? --------------- - -Well, first, OSS refers to Open Sound System. If it still doesn't -ring a bell, think /dev/dsp, /dev/adsp and /dev/mixer. - -Currently, Linux supports two audio programming interface - ALSA and -OSS. The latter one is deprecated and has been that way for a long -time but there still are applications which still use them including -UML (usermode Linux) host sound support. - -ALSA contains OSS emulation but sadly the emulation is behind -multiplexing layer (which is in userland) which means that if your -sound card doesn't support multiple audio streams, only either one of -ALSA or OSS interface would be usable at any given moment. - -There have been also attempts to emulate OSS in userland using dynamic -library preloading - aoss and more recently padsp. This works for -many applications but it's just not easy to emulate everything using -the technique. Things like polling, signals, forking, privilege -changes make it very difficult to emulate things reliably. - -OSS Proxy uses CUSE (extension of FUSE allowing character devices to -be implemented in userspace) to implement OSS interface - /dev/dsp, -/dev/adsp and /dev/mixer. From the POV of the applications, these -devices are proper character devices and behave exactly the same way -so it can be made quite versatile. - - -2. Hmmm... So, how does the whole thing work? ---------------------------------------------- - -The OSS Proxy daemon - osspd - should be started first. Note that -osspd will fail to start if sound device number regions are already -occupied. You'll need to turn off OSS or its emulation[1]. - -On startup, osspd creates /dev/dsp, /dev/adsp and /dev/mixer using -CUSE. When an application access one of the devices, all IOs are -redirected to osspd via CUSE. Upon receiving a new DSP open request, -osspd creates a slave process which drops the root privilege and -assumes the opening process's credentials. After handshaking, osspd -forwards all relevant IOs to the slave which is responsible for -actually playing the sound. - -Currently there's only one slave implemented - ossp-padsp, which as -the name suggests forwards (again) the sound to pulseaudio. To sum -up, the whole pipe looks like the following. - - App <-> /dev/dsp <-> CUSE <-> osspd <-> ossp-padsp <-> pulseaudio - -Which is a lot of forwarding, but on modern machines, it won't be too -noticeable. - - -3. What works? --------------- - -Well, MIDI part isn't implemented and I doubt it will be in any near -future but except that everything should work. Playing, recording, -5.1ch, A-V syncing, all should work. If not, it's a bug, so please -report. - -The mixer behaves a bit differently tho. In the original OSS, -/dev/mixer is the hardware mixer, so adjusting volumes there affects -all audio streams. When using ossp, each process group gets its own -mixer and the mixer always contains only two knobs - PCM and IGAIN. -Combined with per-stream volume control of pulseaudio, this scheme -works quite well for applications with embedded volume control -although it makes standalone OSS mixer programs virtually useless[2]. - - -4. How do I use it? -------------------- - -First you need CUSE support in kernel which might land on 2.6.28 with -sufficient luck[3] and then you also need libfuse which supports -CUSE[4]. Once you have both, it should be easy. First build it by -running `make'. You can set OSSPD_CFLAGS, OSSPD_LDFLAGS, -OSSP_PADSP_CFLAGS and OSSP_PADSP_LDFLAGS if you have stuff at -non-default locations. - -After build completes, there will be two executables - `osspd' and -`ossp-padsp'. Just copy them to where other system executables live. -Specific location doesn't matter as long as both files end up in the -same directory. - -Execute `osspd'. It will create the device files and you're all set. -`osspd' uses syslog with LOG_DAEMON facility, so if something doesn't -work take a look at what osspd complains about. - - -[1] As of this writing, turning on any sound support makes the - soundcore module claim OSS device regions. Patch to make it claim - OSS device regions only when OSS support or emulation is enabled - is scheduled for 2.6.28. Even with the patch, soundcore will - claim OSS device regions if OSS support or ALSA OSS emulation is - enabled. Make sure they're turned off. - -[2] If you have a strong reason to use standalone OSS mixer program, - you can play some shell tricks to put it into the same process - group as the target audio application. e.g. To use aumix with - mpg123 - `(mpg123 asdf.mp3 > /dev/null 2>&1 & aumix)', but - seriously, just use PA or ALSA one. - -[3] For the time being, here's the git tree with all the necessary - changes. This tree is base on top of 2.6.27-rc3. - - http://git.kernel.org/?p=linux/kernel/git/tj/misc.git;a=shortlog;h=cuse - git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc.git cuse - -[4] And libfuse with the modifications can be found at... - - http://userweb.kernel.org/~tj/ossp/fuse-cuse.tar.gz diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-alsap.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp-alsap.c deleted file mode 100644 index 607e05ca84..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-alsap.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * ossp-alsap - ossp DSP slave which forwards to alsa - * - * Copyright (C) 2009 Maarten Lankhorst - * - * This file is released under the GPLv2. - * - * Why an alsa plugin as well? Just to show how much - * the alsa userspace api sucks ;-) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ossp-slave.h" - -enum { - AFMT_FLOAT = 0x00004000, - AFMT_S32_LE = 0x00001000, - AFMT_S32_BE = 0x00002000, -}; - -static size_t page_size; - -/* alsa structures */ -static snd_pcm_t *pcm[2]; -static snd_pcm_hw_params_t *hw_params; -static snd_pcm_sw_params_t *sw_params; -static int block; - -static unsigned int byte_counter[2]; -static snd_pcm_uframes_t mmap_pos[2]; -static int stream_corked[2]; -static int stream_notify; - -static struct format { - snd_pcm_format_t format; - snd_pcm_sframes_t rate; - int channels; -} hw_format = { SND_PCM_FORMAT_U8, 8000, 1 }; - -#if 0 -/* future mmap stuff */ -static size_t mmap_raw_size, mmap_size; -static int mmap_fd[2] = { -1, -1 }; -static void *mmap_map[2]; -static uint64_t mmap_idx[2]; /* mmap pointer */ -static uint64_t mmap_last_idx[2]; /* last idx for get_ptr */ -static struct ring_buf mmap_stg[2]; /* staging ring buffer */ -static size_t mmap_lead[2]; /* lead bytes */ -static int mmap_sync[2]; /* sync with backend stream */ -#endif - -static snd_pcm_format_t fmt_oss_to_alsa(int fmt) -{ - switch (fmt) { - case AFMT_U8: return SND_PCM_FORMAT_U8; - case AFMT_A_LAW: return SND_PCM_FORMAT_A_LAW; - case AFMT_MU_LAW: return SND_PCM_FORMAT_MU_LAW; - case AFMT_S16_LE: return SND_PCM_FORMAT_S16_LE; - case AFMT_S16_BE: return SND_PCM_FORMAT_S16_BE; - case AFMT_FLOAT: return SND_PCM_FORMAT_FLOAT; - case AFMT_S32_LE: return SND_PCM_FORMAT_S32_LE; - case AFMT_S32_BE: return SND_PCM_FORMAT_S32_BE; - default: return SND_PCM_FORMAT_U8; - } -} - -static int fmt_alsa_to_oss(snd_pcm_format_t fmt) -{ - switch (fmt) { - case SND_PCM_FORMAT_U8: return AFMT_U8; - case SND_PCM_FORMAT_A_LAW: return AFMT_A_LAW; - case SND_PCM_FORMAT_MU_LAW: return AFMT_MU_LAW; - case SND_PCM_FORMAT_S16_LE: return AFMT_S16_LE; - case SND_PCM_FORMAT_S16_BE: return AFMT_S16_BE; - case SND_PCM_FORMAT_FLOAT: return AFMT_FLOAT; - case SND_PCM_FORMAT_S32_LE: return AFMT_S32_LE; - case SND_PCM_FORMAT_S32_BE: return AFMT_S32_BE; - default: return AFMT_U8; - } -} - -static void flush_streams(int drain) -{ - /* FIXME: snd_pcm_drain appears to be able to deadlock, - * always drop or check state? */ - if (drain) { - if (pcm[PLAY]) - snd_pcm_drain(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_drain(pcm[REC]); - } else { - if (pcm[PLAY]) - snd_pcm_drop(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_drop(pcm[REC]); - } - - /* XXX: Really needed? */ -#if 0 - if (pcm[PLAY]) { - snd_pcm_close(pcm[PLAY]); - snd_pcm_open(&pcm[PLAY], "default", - SND_PCM_STREAM_PLAYBACK, block); - } - if (pcm[REC]) { - snd_pcm_close(pcm[REC]); - snd_pcm_open(&pcm[REC], "default", - SND_PCM_STREAM_CAPTURE, block); - } -#endif -} - -static void kill_streams(void) -{ - flush_streams(0); -} - -static int trigger_streams(int play, int rec) -{ - int ret = 0; - - if (pcm[PLAY] && play >= 0) { - ret = snd_pcm_sw_params_set_start_threshold(pcm[PLAY], sw_params, - play ? 1 : -1); - if (ret >= 0) - snd_pcm_sw_params(pcm[PLAY], sw_params); - } - if (ret >= 0 && pcm[REC] && rec >= 0) { - ret = snd_pcm_sw_params_set_start_threshold(pcm[REC], sw_params, - rec ? 1 : -1); - if (ret >= 0) - snd_pcm_sw_params(pcm[REC], sw_params); - } - - return ret; -} - -static ssize_t alsap_mixer(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ -return -EBUSY; -} - -static int set_hw_params(snd_pcm_t *pcm) -{ - int ret; - unsigned rate; - - ret = snd_pcm_hw_params_any(pcm, hw_params); - if (ret >= 0) - ret = snd_pcm_hw_params_set_access(pcm, hw_params, - SND_PCM_ACCESS_RW_INTERLEAVED); - rate = hw_format.rate; - if (ret >= 0) - ret = snd_pcm_hw_params_set_rate_minmax(pcm, hw_params, - &rate, NULL, - &rate, NULL); - if (ret >= 0) - ret = snd_pcm_hw_params_set_format(pcm, hw_params, hw_format.format); - if (ret >= 0) - ret = snd_pcm_hw_params_set_channels(pcm, hw_params, - hw_format.channels); - if (ret >= 0) - ret = snd_pcm_hw_params(pcm, hw_params); - if (ret >= 0) - ret = snd_pcm_sw_params_current(pcm, sw_params); - if (ret >= 0) - ret = snd_pcm_sw_params(pcm, sw_params); - return ret; -} - -static ssize_t alsap_open(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - struct ossp_dsp_open_arg *arg = carg; - int ret; - block = arg->flags & O_NONBLOCK ? SND_PCM_NONBLOCK : 0; - int access; -// block |= SND_PCM_ASYNC; - /* Woop dee dooo.. I love handling things in SIGIO (PAIN!!) - * Probably needed for MMAP - */ - - if (!hw_params) - ret = snd_pcm_hw_params_malloc(&hw_params); - if (ret < 0) - return ret; - - if (!sw_params) - ret = snd_pcm_sw_params_malloc(&sw_params); - if (ret < 0) - return ret; - - if (pcm[PLAY]) - snd_pcm_close(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_close(pcm[REC]); - pcm[REC] = pcm[PLAY] = NULL; - - access = arg->flags & O_ACCMODE; - if (access == O_WRONLY || access == O_RDWR) { - ret = snd_pcm_open(&pcm[PLAY], "default", - SND_PCM_STREAM_PLAYBACK, block); - if (ret >= 0) - ret = set_hw_params(pcm[PLAY]); - } - - if (ret >= 0 && (access == O_RDONLY || access == O_RDWR)) { - ret = snd_pcm_open(&pcm[REC], "default", - SND_PCM_STREAM_CAPTURE, block); - if (ret >= 0) - ret = set_hw_params(pcm[REC]); - } - - if (ret < 0) { - if (pcm[PLAY]) - snd_pcm_close(pcm[PLAY]); - if (pcm[REC]) - snd_pcm_close(pcm[REC]); - pcm[REC] = pcm[PLAY] = NULL; - return ret; - } - return 0; -} - -#define GIOVANNI -#ifdef GIOVANNI - -#define GIOVA_SLEEP 40000 -#define GIOVA_BLK 3840 -static ssize_t alsap_write(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - usleep((GIOVA_SLEEP/GIOVA_BLK)* din_sz); - return din_sz; -} -static ssize_t alsap_read(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - usleep((GIOVA_SLEEP/GIOVA_BLK)* *dout_szp); - return *dout_szp; -} -#else// GIOVANNI -static ssize_t alsap_write(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ -// struct ossp_dsp_rw_arg *arg = carg; - int ret, insize; - - insize = snd_pcm_bytes_to_frames(pcm[PLAY], din_sz); - - if (snd_pcm_state(pcm[PLAY]) == SND_PCM_STATE_SETUP) - snd_pcm_prepare(pcm[PLAY]); - -// snd_pcm_start(pcm[PLAY]); - ret = snd_pcm_writei(pcm[PLAY], din, insize); - if (ret < 0) - ret = snd_pcm_recover(pcm[PLAY], ret, 1); - - if (ret >= 0) - return snd_pcm_frames_to_bytes(pcm[PLAY], ret); - else - return ret; -} - -static ssize_t alsap_read(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ -// struct ossp_dsp_rw_arg *arg = carg; - int ret, outsize; - - outsize = snd_pcm_bytes_to_frames(pcm[REC], *dout_szp); - - if (snd_pcm_state(pcm[REC]) == SND_PCM_STATE_SETUP) - snd_pcm_prepare(pcm[REC]); - - ret = snd_pcm_readi(pcm[REC], dout, outsize); - if (ret < 0) - ret = snd_pcm_recover(pcm[REC], ret, 1); - if (ret >= 0) - *dout_szp = ret = snd_pcm_frames_to_bytes(pcm[REC], ret); - else - *dout_szp = 0; - - return ret; -} -#endif// GIOVANNI - -static ssize_t alsap_poll(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - unsigned revents = 0; - - stream_notify |= *(int *)carg; - - if (pcm[PLAY]) - revents |= POLLOUT; - if (pcm[REC]) - revents |= POLLIN; - - *(unsigned *)rarg = revents; - return 0; -} - - -static ssize_t alsap_flush(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - flush_streams(opcode == OSSP_DSP_SYNC); - return 0; -} - -static ssize_t alsap_post(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - int ret; - - ret = trigger_streams(1, 1); - if (ret >= 0 && pcm[PLAY]) - ret = snd_pcm_start(pcm[PLAY]); - if (pcm[REC]) - ret = snd_pcm_start(pcm[REC]); - return ret; -} - -static ssize_t alsap_get_param(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int tfd) -{ - int v = 0; - - switch (opcode) { - case OSSP_DSP_GET_RATE: - return hw_format.rate; - - case OSSP_DSP_GET_CHANNELS: - return hw_format.channels; - - case OSSP_DSP_GET_FORMAT: { - v = fmt_alsa_to_oss(hw_format.format); - break; - } - - case OSSP_DSP_GET_BLKSIZE: { - snd_pcm_uframes_t psize; - snd_pcm_hw_params_get_period_size(hw_params, &psize, NULL); - v = psize; - break; - } - - case OSSP_DSP_GET_FORMATS: - v = AFMT_U8 | AFMT_A_LAW | AFMT_MU_LAW | AFMT_S16_LE | - AFMT_S16_BE | AFMT_FLOAT | AFMT_S32_LE | AFMT_S32_BE; - break; - - case OSSP_DSP_GET_TRIGGER: - if (!stream_corked[PLAY]) - v |= PCM_ENABLE_OUTPUT; - if (!stream_corked[REC]) - v |= PCM_ENABLE_INPUT; - break; - - default: - assert(0); - } - - *(int *)rarg = v; - - return 0; -} - -static ssize_t alsap_set_param(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int tfd) -{ - int v = *(int *)carg; - int ret = 0; - - /* kill the streams before changing parameters */ - kill_streams(); - - switch (opcode) { - case OSSP_DSP_SET_RATE: { - hw_format.rate = v; - break; - } - - case OSSP_DSP_SET_CHANNELS: { - hw_format.channels = v; - break; - } - - case OSSP_DSP_SET_FORMAT: { - snd_pcm_format_t format = fmt_oss_to_alsa(v); - hw_format.format = format; - break; - } - - case OSSP_DSP_SET_SUBDIVISION: - if (!v) - v = 1; -#if 0 - if (!v) { - v = user_subdivision ?: 1; - break; - } - user_frag_size = 0; - user_subdivision = v; - break; - - case OSSP_DSP_SET_FRAGMENT: - user_subdivision = 0; - user_frag_size = 1 << (v & 0xffff); - user_max_frags = (v >> 16) & 0xffff; - if (user_frag_size < 4) - user_frag_size = 4; - if (user_max_frags < 2) - user_max_frags = 2; -#else - case OSSP_DSP_SET_FRAGMENT: -#endif - break; - default: - assert(0); - } - - if (pcm[PLAY]) - ret = set_hw_params(pcm[PLAY]); - if (ret >= 0 && pcm[REC]) - ret = set_hw_params(pcm[REC]); - - if (rarg) - *(int *)rarg = v; - return 0; -} - -static ssize_t alsap_set_trigger(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int fd) -{ - int enable = *(int *)carg; - - stream_corked[PLAY] = !!(enable & PCM_ENABLE_OUTPUT); - stream_corked[REC] = !!(enable & PCM_ENABLE_INPUT); - - return trigger_streams(enable & PCM_ENABLE_OUTPUT, - enable & PCM_ENABLE_INPUT); -} - -static ssize_t alsap_get_space(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - int dir = (opcode == OSSP_DSP_GET_OSPACE) ? PLAY : REC; - int underrun = 0; - struct audio_buf_info info = { }; - unsigned long bufsize; - snd_pcm_uframes_t avail, fragsize; - snd_pcm_state_t state; - - if (!pcm[dir]) - return -EINVAL; - - state = snd_pcm_state(pcm[dir]); - if (state == SND_PCM_STATE_XRUN) { - snd_pcm_recover(pcm[dir], -EPIPE, 0); - underrun = 1; - } else if (state == SND_PCM_STATE_SUSPENDED) { - snd_pcm_recover(pcm[dir], -ESTRPIPE, 0); - underrun = 1; - } - - snd_pcm_hw_params_current(pcm[dir], hw_params); - snd_pcm_hw_params_get_period_size(hw_params, &fragsize, NULL); - snd_pcm_hw_params_get_buffer_size(hw_params, &bufsize); - info.fragsize = snd_pcm_frames_to_bytes(pcm[dir], fragsize); - info.fragstotal = bufsize / fragsize; - if (!underrun) { - avail = snd_pcm_avail_update(pcm[dir]); - info.fragments = avail / fragsize; - } else - info.fragments = info.fragstotal; - - info.bytes = info.fragsize * info.fragments; - - *(struct audio_buf_info *)rarg = info; - return 0; -} - -static ssize_t alsap_get_ptr(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, int tfd) -{ - int dir = (opcode == OSSP_DSP_GET_OPTR) ? PLAY : REC; - struct count_info info = { }; - - if (!pcm[dir]) - return -EIO; - - snd_pcm_hw_params_current(pcm[dir], hw_params); - info.bytes = byte_counter[dir]; - snd_pcm_hw_params_get_periods(hw_params, (unsigned int *)&info.blocks, NULL); - info.ptr = mmap_pos[dir]; - - *(struct count_info *)rarg = info; - return 0; -} - -static ssize_t alsap_get_odelay(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int fd) -{ - snd_pcm_sframes_t delay; - - if (!pcm[PLAY]) - return -EIO; - - if (snd_pcm_delay(pcm[PLAY], &delay) < 0) - return -EIO; - - *(int *)rarg = snd_pcm_frames_to_bytes(pcm[PLAY], delay); - return 0; -} - -static ossp_action_fn_t action_fn_tbl[OSSP_NR_OPCODES] = { - [OSSP_MIXER] = alsap_mixer, - [OSSP_DSP_OPEN] = alsap_open, - [OSSP_DSP_READ] = alsap_read, - [OSSP_DSP_WRITE] = alsap_write, - [OSSP_DSP_POLL] = alsap_poll, -#if 0 - [OSSP_DSP_MMAP] = alsap_mmap, - [OSSP_DSP_MUNMAP] = alsap_munmap, -#endif - [OSSP_DSP_RESET] = alsap_flush, - [OSSP_DSP_SYNC] = alsap_flush, - [OSSP_DSP_POST] = alsap_post, - [OSSP_DSP_GET_RATE] = alsap_get_param, - [OSSP_DSP_GET_CHANNELS] = alsap_get_param, - [OSSP_DSP_GET_FORMAT] = alsap_get_param, - [OSSP_DSP_GET_BLKSIZE] = alsap_get_param, - [OSSP_DSP_GET_FORMATS] = alsap_get_param, - [OSSP_DSP_SET_RATE] = alsap_set_param, - [OSSP_DSP_SET_CHANNELS] = alsap_set_param, - [OSSP_DSP_SET_FORMAT] = alsap_set_param, - [OSSP_DSP_SET_SUBDIVISION] = alsap_set_param, - [OSSP_DSP_SET_FRAGMENT] = alsap_set_param, - [OSSP_DSP_GET_TRIGGER] = alsap_get_param, - [OSSP_DSP_SET_TRIGGER] = alsap_set_trigger, - [OSSP_DSP_GET_OSPACE] = alsap_get_space, - [OSSP_DSP_GET_ISPACE] = alsap_get_space, - [OSSP_DSP_GET_OPTR] = alsap_get_ptr, - [OSSP_DSP_GET_IPTR] = alsap_get_ptr, - [OSSP_DSP_GET_ODELAY] = alsap_get_odelay, -}; - -static int action_pre(void) -{ - return 0; -} - -static void action_post(void) -{ -} - -int main(int argc, char **argv) -{ - int rc; - - ossp_slave_init(argc, argv); - - page_size = sysconf(_SC_PAGE_SIZE); - - /* Okay, now we're open for business */ - rc = 0; - do { - rc = ossp_slave_process_command(ossp_cmd_fd, action_fn_tbl, - action_pre, action_post); - } while (rc > 0); - - return rc ? 1 : 0; -} diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.c deleted file mode 100644 index 4c5cb2d129..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * ossp-slave - OSS Proxy: Common codes for slaves - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ossp-slave.h" - -static const char *usage = -"usage: ossp-SLAVE [options]\n" -"\n" -"proxies commands from osspd to pulseaudio\n" -"\n" -"options:\n" -" -u UID uid to use\n" -" -g GID gid to use\n" -" -c CMD_FD fd to receive commands from osspd\n" -" -n NOTIFY_FD fd to send async notifications to osspd\n" -" -m MMAP_FD fd to use for mmap\n" -" -o MMAP_OFFSET mmap offset\n" -" -s MMAP_SIZE mmap size\n" -" -l LOG_LEVEL set log level\n" -" -t enable log timestamps\n"; - -char ossp_user_name[OSSP_USER_NAME_LEN]; -int ossp_cmd_fd = -1, ossp_notify_fd = -1; -void *ossp_mmap_addr[2]; - -void ossp_slave_init(int argc, char **argv) -{ - int have_uid = 0, have_gid = 0; - uid_t uid; - gid_t gid; - int mmap_fd = -1; - off_t mmap_off = 0; - size_t mmap_size = 0; - int opt; - struct passwd *pw, pw_buf; - struct sigaction sa; - char pw_sbuf[sysconf(_SC_GETPW_R_SIZE_MAX)]; - - while ((opt = getopt(argc, argv, "u:g:c:n:m:o:s:l:t")) != -1) { - switch (opt) { - case 'u': - have_uid = 1; - uid = strtol(optarg, NULL, 0); - break; - case 'g': - have_gid = 1; - gid = strtol(optarg, NULL, 0); - break; - case 'c': - ossp_cmd_fd = strtol(optarg, NULL, 0); - break; - case 'n': - ossp_notify_fd = strtol(optarg, NULL, 0); - break; - case 'm': - mmap_fd = strtol(optarg, NULL, 0); - break; - case 'o': - mmap_off = strtoull(optarg, NULL, 0); - break; - case 's': - mmap_size = strtoul(optarg, NULL, 0); - break; - case 'l': - ossp_log_level = strtol(optarg, NULL, 0); - break; - case 't': - ossp_log_timestamp = 1; - break; - } - } - - if (!have_uid || !have_gid || ossp_cmd_fd < 0 || ossp_notify_fd < 0) { - fprintf(stderr, usage); - _exit(1); - } - - snprintf(ossp_user_name, sizeof(ossp_user_name), "uid%d", uid); - if (getpwuid_r(uid, &pw_buf, pw_sbuf, sizeof(pw_sbuf), &pw) == 0) - snprintf(ossp_user_name, sizeof(ossp_user_name), "%s", - pw->pw_name); - - snprintf(ossp_log_name, sizeof(ossp_log_name), "ossp-padsp[%s:%d]", - ossp_user_name, getpid()); - - if (mmap_fd >= 0) { - void *p; - - if (!mmap_off || !mmap_size) { - fprintf(stderr, usage); - _exit(1); - } - - p = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, - mmap_fd, mmap_off); - if (p == MAP_FAILED) - fatal_e(-errno, "mmap failed"); - - ossp_mmap_addr[PLAY] = p; - ossp_mmap_addr[REC] = p + mmap_size / 2; - close(mmap_fd); - } - - /* mmap done, drop privileges */ - if (setresgid(gid, gid, gid) || setresuid(uid, uid, uid)) - fatal_e(-errno, "failed to drop privileges"); - - /* block SIGPIPE */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL)) - fatal_e(-errno, "failed to ignore SIGPIPE"); -} - -int ossp_slave_process_command(int cmd_fd, - ossp_action_fn_t const *action_fn_tbl, - int (*action_pre_fn)(void), - void (*action_post_fn)(void)) -{ - static struct sized_buf carg_sbuf = { }, rarg_sbuf = { }; - static struct sized_buf din_sbuf = { }, dout_sbuf = { }; - struct ossp_cmd cmd; - int fd = -1; - char cmsg_buf[CMSG_SPACE(sizeof(fd))]; - struct iovec iov = { &cmd, sizeof(cmd) }; - struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1, - .msg_control = cmsg_buf, - .msg_controllen = sizeof(cmsg_buf) }; - struct cmsghdr *cmsg; - size_t carg_size, din_size, rarg_size, dout_size; - char *carg = NULL, *din = NULL, *rarg = NULL, *dout = NULL; - struct ossp_reply reply = { .magic = OSSP_REPLY_MAGIC }; - ssize_t ret; - - ret = recvmsg(cmd_fd, &msg, 0); - if (ret == 0) - return 0; - if (ret < 0) { - ret = -errno; - err_e(ret, "failed to read command channel"); - return ret; - } - - if (ret != sizeof(cmd)) { - err("command struct size mismatch (%zu, should be %zu)", - ret, sizeof(cmd)); - return -EINVAL; - } - - if (cmd.magic != OSSP_CMD_MAGIC) { - err("illegal command magic 0x%x", cmd.magic); - return -EINVAL; - } - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_RIGHTS) - fd = *(int *)CMSG_DATA(cmsg); - else { - err("unknown cmsg %d:%d received (opcode %d)", - cmsg->cmsg_level, cmsg->cmsg_type, cmd.opcode); - return -EINVAL; - } - } - - if (cmd.opcode >= OSSP_NR_OPCODES) { - err("unknown opcode %d", cmd.opcode); - return -EINVAL; - } - - carg_size = ossp_arg_sizes[cmd.opcode].carg_size; - din_size = cmd.din_size; - rarg_size = ossp_arg_sizes[cmd.opcode].rarg_size; - dout_size = cmd.dout_size; - - if ((fd >= 0) != ossp_arg_sizes[cmd.opcode].has_fd) { - err("fd=%d unexpected for opcode %d", fd, cmd.opcode); - return -EINVAL; - } - - if (ensure_sbuf_size(&carg_sbuf, carg_size) || - ensure_sbuf_size(&din_sbuf, din_size) || - ensure_sbuf_size(&rarg_sbuf, rarg_size) || - ensure_sbuf_size(&dout_sbuf, dout_size)) { - err("failed to allocate command buffers"); - return -ENOMEM; - } - - if (carg_size) { - carg = carg_sbuf.buf; - ret = read_fill(cmd_fd, carg, carg_size); - if (ret < 0) - return ret; - } - if (din_size) { - din = din_sbuf.buf; - ret = read_fill(cmd_fd, din, din_size); - if (ret < 0) - return ret; - } - if (rarg_size) - rarg = rarg_sbuf.buf; - if (dout_size) - dout = dout_sbuf.buf; - - ret = -EINVAL; - if (action_fn_tbl[cmd.opcode]) { - ret = action_pre_fn(); - if (ret == 0) { - ret = action_fn_tbl[cmd.opcode](cmd.opcode, carg, - din, din_size, rarg, - dout, &dout_size, fd); - action_post_fn(); - } - } - - reply.result = ret; - if (ret >= 0) - reply.dout_size = dout_size; - else { - rarg_size = 0; - dout_size = 0; - } - - if (write_fill(cmd_fd, &reply, sizeof(reply)) < 0 || - write_fill(cmd_fd, rarg, rarg_size) < 0 || - write_fill(cmd_fd, dout, dout_size) < 0) - return -EIO; - - return 1; -} diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.h b/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.h deleted file mode 100644 index 10c22cdb02..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-slave.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * ossp-slave - OSS Proxy: Common codes for slaves - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#ifndef _OSSP_SLAVE_H -#define _OSSP_SLAVE_H - -#include "ossp.h" -#include "ossp-util.h" - -#define OSSP_USER_NAME_LEN 128 - -extern char ossp_user_name[OSSP_USER_NAME_LEN]; -extern int ossp_cmd_fd, ossp_notify_fd; -extern void *ossp_mmap_addr[2]; - -void ossp_slave_init(int argc, char **argv); -int ossp_slave_process_command(int cmd_fd, - ossp_action_fn_t const *action_fn_tbl, - int (*action_pre_fn)(void), - void (*action_post_fn)(void)); - -#endif /* _OSSP_SLAVE_H */ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.c deleted file mode 100644 index 325cefd5fd..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * ossp-util - OSS Proxy: Common utilities - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ossp-util.h" - -#define BIT(nr) (1UL << (nr)) -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) -#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) - -char ossp_log_name[OSSP_LOG_NAME_LEN]; -int ossp_log_level = OSSP_LOG_DFL; -int ossp_log_timestamp; - -static const char *severity_strs[] = { - [OSSP_LOG_CRIT] = "CRIT", - [OSSP_LOG_ERR] = " ERR", - [OSSP_LOG_WARN] = "WARN", - [OSSP_LOG_INFO] = NULL, - [OSSP_LOG_DBG0] = "DBG0", - [OSSP_LOG_DBG1] = "DBG1", -}; - -static int severity_map[] = { - [OSSP_LOG_CRIT] = LOG_ERR, - [OSSP_LOG_ERR] = LOG_ERR, - [OSSP_LOG_WARN] = LOG_WARNING, - [OSSP_LOG_INFO] = LOG_INFO, - [OSSP_LOG_DBG0] = LOG_DEBUG, - [OSSP_LOG_DBG1] = LOG_DEBUG, -}; - -void log_msg(int severity, const char *fmt, ...) -{ - static int syslog_opened = 0; - char buf[1024]; - size_t len = sizeof(buf), off = 0; - va_list ap; - - if (severity > abs(ossp_log_level)) - return; - - if (ossp_log_level < 0 && !syslog_opened) - openlog(ossp_log_name, 0, LOG_DAEMON); - - assert(severity >= 0 && severity < ARRAY_SIZE(severity_strs)); - - if (ossp_log_timestamp) { - static uint64_t start; - uint64_t now; - struct timeval tv; - gettimeofday(&tv, NULL); - now = tv.tv_sec * 1000 + tv.tv_usec / 1000; - if (!start) - start = now; - - off += snprintf(buf + off, len - off, "<%08"PRIu64"> ", - now - start); - } - - if (ossp_log_level > 0) { - char sev_buf[16] = ""; - if (severity_strs[severity]) - snprintf(sev_buf, sizeof(sev_buf), " %s", - severity_strs[severity]); - off += snprintf(buf + off, len - off, "%s%s: ", - ossp_log_name, sev_buf); - } else if (severity_strs[severity]) - off += snprintf(buf + off, len - off, "%s ", - severity_strs[severity]); - - va_start(ap, fmt); - off += vsnprintf(buf + off, len - off, fmt, ap); - va_end(ap); - - off += snprintf(buf + off, len - off, "\n"); - - if (ossp_log_level > 0) - fputs(buf, stderr); - else - syslog(severity_map[severity], "%s", buf); -} - -int read_fill(int fd, void *buf, size_t size) -{ - while (size) { - ssize_t ret; - int rc; - - ret = read(fd, buf, size); - if (ret <= 0) { - if (ret == 0) - rc = -EIO; - else - rc = -errno; - err_e(rc, "failed to read_fill %zu bytes from fd %d", - size, fd); - return rc; - } - buf += ret; - size -= ret; - } - return 0; -} - -int write_fill(int fd, const void *buf, size_t size) -{ - while (size) { - ssize_t ret; - int rc; - - ret = write(fd, buf, size); - if (ret <= 0) { - if (ret == 0) - rc = -EIO; - else - rc = -errno; - err_e(rc, "failed to write_fill %zu bytes to fd %d", - size, fd); - return rc; - } - buf += ret; - size -= ret; - } - return 0; -} - -void ring_fill(struct ring_buf *ring, const void *buf, size_t size) -{ - size_t tail; - - assert(ring_space(ring) >= size); - - tail = (ring->head + ring->size - ring->bytes) % ring->size; - - if (ring->head >= tail) { - size_t todo = min(size, ring->size - ring->head); - - memcpy(ring->buf + ring->head, buf, todo); - ring->head = (ring->head + todo) % ring->size; - ring->bytes += todo; - buf += todo; - size -= todo; - } - - assert(ring->size - ring->head >= size); - memcpy(ring->buf + ring->head, buf, size); - ring->head += size; - ring->bytes += size; -} - -void *ring_data(struct ring_buf *ring, size_t *sizep) -{ - size_t tail; - - if (!ring->bytes) - return NULL; - - tail = (ring->head + ring->size - ring->bytes) % ring->size; - - *sizep = min(ring->bytes, ring->size - tail); - return ring->buf + tail; -} - -int ring_resize(struct ring_buf *ring, size_t new_size) -{ - struct ring_buf new_ring = { .size = new_size }; - void *p; - size_t size; - - if (ring_bytes(ring) > new_size) - return -ENOSPC; - - new_ring.buf = calloc(1, new_size); - if (new_size && !new_ring.buf) - return -ENOMEM; - - while ((p = ring_data(ring, &size))) { - ring_fill(&new_ring, p, size); - ring_consume(ring, size); - } - - free(ring->buf); - *ring = new_ring; - return 0; -} - -int ensure_sbuf_size(struct sized_buf *sbuf, size_t size) -{ - char *new_buf; - - if (sbuf->size >= size) - return 0; - - new_buf = realloc(sbuf->buf, size); - if (size && !new_buf) - return -ENOMEM; - - sbuf->buf = new_buf; - sbuf->size = size; - return 0; -} - -static unsigned long __ffs(unsigned long word) -{ - int num = 0; - - if (BITS_PER_LONG == 64) { - if ((word & 0xffffffff) == 0) { - num += 32; - word >>= 32; - } - } - - if ((word & 0xffff) == 0) { - num += 16; - word >>= 16; - } - if ((word & 0xff) == 0) { - num += 8; - word >>= 8; - } - if ((word & 0xf) == 0) { - num += 4; - word >>= 4; - } - if ((word & 0x3) == 0) { - num += 2; - word >>= 2; - } - if ((word & 0x1) == 0) - num += 1; - return num; -} - -#define ffz(x) __ffs(~(x)) - -unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, - unsigned long offset) -{ - const unsigned long *p = addr + BITOP_WORD(offset); - unsigned long result = offset & ~(BITS_PER_LONG-1); - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset %= BITS_PER_LONG; - if (offset) { - tmp = *(p++); - tmp |= ~0UL >> (BITS_PER_LONG - offset); - if (size < BITS_PER_LONG) - goto found_first; - if (~tmp) - goto found_middle; - size -= BITS_PER_LONG; - result += BITS_PER_LONG; - } - while (size & ~(BITS_PER_LONG-1)) { - if (~(tmp = *(p++))) - goto found_middle; - result += BITS_PER_LONG; - size -= BITS_PER_LONG; - } - if (!size) - return result; - tmp = *p; - -found_first: - tmp |= ~0UL << size; - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ -found_middle: - return result + ffz(tmp); -} - -void __set_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - - *p |= mask; -} - -void __clear_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - - *p &= ~mask; -} - -int get_proc_self_info(pid_t pid, pid_t *ppid_r, - char *cmd_buf, size_t cmd_buf_sz) - -{ - char path[64], buf[4096]; - int fd = -1; - char *cmd_start, *cmd_end, *ppid_start, *end; - ssize_t ret; - pid_t ppid; - int i, rc; - - snprintf(path, sizeof(path), "/proc/%ld/stat", (long)pid); - fd = open(path, O_RDONLY); - if (fd < 0) { - rc = -errno; - goto out; - } - - ret = read(fd, buf, sizeof(buf)); - if (ret < 0) - goto out; - if (ret == sizeof(buf)) { - rc = -EOVERFLOW; - goto out; - } - buf[ret] = '\0'; - - rc = -EINVAL; - cmd_start = strchr(buf, '('); - cmd_end = strrchr(buf, ')'); - if (!cmd_start || !cmd_end) - goto out; - cmd_start++; - - ppid_start = cmd_end; - for (i = 0; i < 3; i++) { - ppid_start = strchr(ppid_start, ' '); - if (!ppid_start) - goto out; - ppid_start++; - } - - ppid = strtoul(ppid_start, &end, 10); - if (end == ppid_start || *end != ' ') - goto out; - - if (ppid_r) - *ppid_r = ppid; - if (cmd_buf) { - size_t len = min_t(size_t, cmd_end - cmd_start, cmd_buf_sz - 1); - memcpy(cmd_buf, cmd_start, len); - cmd_buf[len] = '\0'; - } - - rc = 0; - out: - close(fd); - - return rc; -} diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.h b/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.h deleted file mode 100644 index f48d02257a..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp-util.h +++ /dev/null @@ -1,609 +0,0 @@ -/* - * ossp-util - OSS Proxy: Common utilities - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#ifndef _OSSP_UTIL_H -#define _OSSP_UTIL_H - -#include -#include -#include -#include -#include -#include -#include "ossp.h" - -#define OSSP_LOG_NAME_LEN 128 - -enum { - OSSP_LOG_CRIT = 1, - OSSP_LOG_ERR, - OSSP_LOG_WARN, - OSSP_LOG_INFO, - OSSP_LOG_DFL = OSSP_LOG_INFO, /* default log level */ - OSSP_LOG_DBG0, - OSSP_LOG_DBG1, - OSSP_LOG_MAX = OSSP_LOG_DBG1, -}; - -extern char ossp_log_name[OSSP_LOG_NAME_LEN]; -extern int ossp_log_level; -extern int ossp_log_timestamp; - -#define BITS_PER_BYTE 8 -#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long)) -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) - -/* ARRAY_SIZE and min/max macros stolen from linux/kernel.h */ -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -#define min(x, y) ({ \ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) - -#define max(x, y) ({ \ - typeof(x) _max1 = (x); \ - typeof(y) _max2 = (y); \ - (void) (&_max1 == &_max2); \ - _max1 > _max2 ? _max1 : _max2; }) - -#define min_t(type, x, y) ({ \ - type __min1 = (x); \ - type __min2 = (y); \ - __min1 < __min2 ? __min1: __min2; }) - -#define max_t(type, x, y) ({ \ - type __max1 = (x); \ - type __max2 = (y); \ - __max1 > __max2 ? __max1: __max2; }) - -void log_msg(int severity, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); - -#define fatal(fmt, args...) do { \ - log_msg(OSSP_LOG_CRIT, fmt , ##args); \ - _exit(1); \ -} while (0) -#define err(fmt, args...) log_msg(OSSP_LOG_ERR, fmt , ##args) -#define warn(fmt, args...) log_msg(OSSP_LOG_WARN, fmt , ##args) -#define info(fmt, args...) log_msg(OSSP_LOG_INFO, fmt , ##args) -#define dbg0(fmt, args...) log_msg(OSSP_LOG_DBG0, fmt , ##args) -#define dbg1(fmt, args...) log_msg(OSSP_LOG_DBG1, fmt , ##args) - -#define fatal_e(e, fmt, args...) \ - fatal(fmt" (%s)" , ##args, strerror(-(e))) -#define err_e(e, fmt, args...) \ - err(fmt" (%s)" , ##args, strerror(-(e))) -#define warn_e(e, fmt, args...) \ - warn(fmt" (%s)" , ##args, strerror(-(e))) -#define info_e(e, fmt, args...) \ - info(fmt" (%s)" , ##args, strerror(-(e))) -#define dbg0_e(e, fmt, args...) \ - dbg0(fmt" (%s)" , ##args, strerror(-(e))) -#define dbg1_e(e, fmt, args...) \ - dbg1(fmt" (%s)" , ##args, strerror(-(e))) - -struct ring_buf { - char *buf; - size_t size; - size_t head; - size_t bytes; -}; - -static inline size_t ring_size(struct ring_buf *ring) -{ - return ring->size; -} - -static inline size_t ring_bytes(struct ring_buf *ring) -{ - return ring->bytes; -} - -static inline size_t ring_space(struct ring_buf *ring) -{ - return ring->size - ring->bytes; -} - -static inline void ring_consume(struct ring_buf *ring, size_t size) -{ - assert(ring->bytes >= size); - ring->bytes -= size; -} - -static inline void ring_manual_init(struct ring_buf *ring, void *buf, - size_t size, size_t head, size_t bytes) -{ - ring->buf = buf; - ring->size = size; - ring->head = head; - ring->bytes = bytes; -} - -void ring_fill(struct ring_buf *ring, const void *buf, size_t size); -void *ring_data(struct ring_buf *ring, size_t *sizep); -int ring_resize(struct ring_buf *ring, size_t new_size); - -struct sized_buf { - char *buf; - size_t size; -}; - -int ensure_sbuf_size(struct sized_buf *sbuf, size_t size); - -int read_fill(int fd, void *buf, size_t size); -int write_fill(int fd, const void *buf, size_t size); - -/* - * Bitops lifted from linux asm-generic implementation. - */ -unsigned long find_next_zero_bit(const unsigned long *addr, unsigned - long size, unsigned long offset); -#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0) -extern void __set_bit(int nr, volatile unsigned long *addr); -extern void __clear_bit(int nr, volatile unsigned long *addr); - -typedef ssize_t (*ossp_action_fn_t)(enum ossp_opcode opcode, - void *carg, void *din, size_t din_sz, - void *rarg, void *dout, size_t *dout_szp, - int fd); - -int get_proc_self_info(pid_t tid, pid_t *pgrp, - char *cmd_buf, size_t cmd_buf_sz); - -/* - * Doubly linked list handling code shamelessly stolen from the Linux - * kernel 2.6.26 include/linux/list.h. - */ - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty() on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} - -/** - * list_replace - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * If @old was empty, it will be overwritten. - */ -static inline void list_replace(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->next->prev = new; - new->prev = old->prev; - new->prev->next = new; -} - -static inline void list_replace_init(struct list_head *old, - struct list_head *new) -{ - list_replace(old, new); - INIT_LIST_HEAD(old); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_is_last - tests whether @list is the last entry in list @head - * @list: the entry to test - * @head: the head of the list - */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) -{ - return list->next == head; -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is empty and not being modified - * @head: the list to test - * - * Description: - * tests whether a list is empty _and_ checks that no other CPU might be - * in the process of modifying either member (next or prev) - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -/** - * list_is_singular - tests whether a list has just one entry. - * @head: the list to test. - */ -static inline int list_is_singular(const struct list_head *head) -{ - return !list_empty(head) && (head->next == head->prev); -} - -static inline void __list_splice(const struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(const struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_first_entry - get the first element from a list - * @ptr: the list head to take the element from. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - * - * Note, that list is expected to be not empty. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_prev_safe(pos, n, head) \ - for (pos = (head)->prev, n = pos->prev; \ - pos != (head); pos = n, n = pos->prev) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - * - * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - continue iteration over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Continue to iterate over list of given type, continuing after - * the current position. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_continue_reverse - iterate backwards from the given point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Start to iterate over list of given type backwards, continuing after - * the current position. - */ -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_for_each_entry_from - iterate over list of given type from the current point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing from current position. - */ -#define list_for_each_entry_from(pos, head, member) \ - for (; &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_continue - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. - */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_from - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type from current point, safe against - * removal of list entry. - */ -#define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_reverse - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate backwards over list of given type, safe against removal - * of list entry. - */ -#define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) - -#endif /*_OSSP_UTIL_H*/ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp.c b/src/mod/endpoints/mod_skypopen/osscuse/ossp.c deleted file mode 100644 index 96f98fa37a..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * ossp - OSS Proxy: emulate OSS device using CUSE - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#include "ossp.h" - -const struct ossp_arg_size ossp_arg_sizes[OSSP_NR_OPCODES] = { - [OSSP_MIXER] = { sizeof(struct ossp_mixer_arg), - sizeof(struct ossp_mixer_arg), 0 }, - - [OSSP_DSP_OPEN] = { sizeof(struct ossp_dsp_open_arg), 0, 0 }, - [OSSP_DSP_READ] = { sizeof(struct ossp_dsp_rw_arg), 0, 0 }, - [OSSP_DSP_WRITE] = { sizeof(struct ossp_dsp_rw_arg), 0, 0 }, - [OSSP_DSP_POLL] = { sizeof(int), sizeof(unsigned), 0 }, - [OSSP_DSP_MMAP] = { sizeof(struct ossp_dsp_mmap_arg), 0, 0 }, - [OSSP_DSP_MUNMAP] = { sizeof(int), 0, 0 }, - - [OSSP_DSP_RESET] = { 0, 0, 0 }, - [OSSP_DSP_SYNC] = { 0, 0, 0 }, - [OSSP_DSP_POST] = { 0, 0, 0 }, - [OSSP_DSP_GET_RATE] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_CHANNELS] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_FORMAT] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_BLKSIZE] = { 0, sizeof(int), 0 }, - [OSSP_DSP_GET_FORMATS] = { 0, sizeof(int), 0 }, - [OSSP_DSP_SET_RATE] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_CHANNELS] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_FORMAT] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_SUBDIVISION] = { sizeof(int), sizeof(int), 0 }, - [OSSP_DSP_SET_FRAGMENT] = { sizeof(int), 0, 0 }, - [OSSP_DSP_GET_TRIGGER] = { 0, sizeof(int), 0 }, - [OSSP_DSP_SET_TRIGGER] = { sizeof(int), 0, 0 }, - [OSSP_DSP_GET_OSPACE] = { 0, sizeof(struct audio_buf_info), 0 }, - [OSSP_DSP_GET_ISPACE] = { 0, sizeof(struct audio_buf_info), 0 }, - [OSSP_DSP_GET_OPTR] = { 0, sizeof(struct count_info), 0 }, - [OSSP_DSP_GET_IPTR] = { 0, sizeof(struct count_info), 0 }, - [OSSP_DSP_GET_ODELAY] = { 0, sizeof(int), 0 }, -}; - -const char *ossp_cmd_str[OSSP_NR_OPCODES] = { - [OSSP_MIXER] = "MIXER", - - [OSSP_DSP_OPEN] = "OPEN", - [OSSP_DSP_READ] = "READ", - [OSSP_DSP_WRITE] = "WRITE", - [OSSP_DSP_POLL] = "POLL", - [OSSP_DSP_MMAP] = "MMAP", - [OSSP_DSP_MUNMAP] = "MUNMAP", - - [OSSP_DSP_RESET] = "RESET", - [OSSP_DSP_SYNC] = "SYNC", - [OSSP_DSP_POST] = "POST", - - [OSSP_DSP_GET_RATE] = "GET_RATE", - [OSSP_DSP_GET_CHANNELS] = "GET_CHANNELS", - [OSSP_DSP_GET_FORMAT] = "GET_FORMAT", - [OSSP_DSP_GET_BLKSIZE] = "GET_BLKSIZE", - [OSSP_DSP_GET_FORMATS] = "GET_FORMATS", - [OSSP_DSP_SET_RATE] = "SET_RATE", - [OSSP_DSP_SET_CHANNELS] = "SET_CHANNELS", - [OSSP_DSP_SET_FORMAT] = "SET_FORMAT", - [OSSP_DSP_SET_SUBDIVISION] = "SET_BUSDIVISION", - - [OSSP_DSP_SET_FRAGMENT] = "SET_FRAGMENT", - [OSSP_DSP_GET_TRIGGER] = "GET_TRIGGER", - [OSSP_DSP_SET_TRIGGER] = "SET_TRIGGER", - [OSSP_DSP_GET_OSPACE] = "GET_OSPACE", - [OSSP_DSP_GET_ISPACE] = "GET_ISPACE", - [OSSP_DSP_GET_OPTR] = "GET_OPTR", - [OSSP_DSP_GET_IPTR] = "GET_IPTR", - [OSSP_DSP_GET_ODELAY] = "GET_ODELAY", -}; - -const char *ossp_notify_str[OSSP_NR_NOTIFY_OPCODES] = { - [OSSP_NOTIFY_POLL] = "POLL", - [OSSP_NOTIFY_OBITUARY] = "OBITUARY", - [OSSP_NOTIFY_VOLCHG] = "VOLCHG", -}; diff --git a/src/mod/endpoints/mod_skypopen/osscuse/ossp.h b/src/mod/endpoints/mod_skypopen/osscuse/ossp.h deleted file mode 100644 index 9d03e63adf..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/ossp.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * ossp - OSS Proxy: emulate OSS device using CUSE - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ - -#ifndef _OSSP_H -#define _OSSP_H - -#include -#include -#include - -#define OSSP_VERSION "1.3.2" -#define OSSP_CMD_MAGIC 0xdeadbeef -#define OSSP_REPLY_MAGIC 0xbeefdead -#define OSSP_NOTIFY_MAGIC 0xbebebebe - -#define PLAY 0 -#define REC 1 -#define LEFT 0 -#define RIGHT 1 - -enum ossp_opcode { - OSSP_MIXER, - - OSSP_DSP_OPEN, - OSSP_DSP_READ, - OSSP_DSP_WRITE, - OSSP_DSP_POLL, - OSSP_DSP_MMAP, - OSSP_DSP_MUNMAP, - - OSSP_DSP_RESET, - OSSP_DSP_SYNC, - OSSP_DSP_POST, - - OSSP_DSP_GET_RATE, - OSSP_DSP_GET_CHANNELS, - OSSP_DSP_GET_FORMAT, - OSSP_DSP_GET_BLKSIZE, - OSSP_DSP_GET_FORMATS, - OSSP_DSP_SET_RATE, - OSSP_DSP_SET_CHANNELS, - OSSP_DSP_SET_FORMAT, - OSSP_DSP_SET_SUBDIVISION, - - OSSP_DSP_SET_FRAGMENT, - OSSP_DSP_GET_TRIGGER, - OSSP_DSP_SET_TRIGGER, - OSSP_DSP_GET_OSPACE, - OSSP_DSP_GET_ISPACE, - OSSP_DSP_GET_OPTR, - OSSP_DSP_GET_IPTR, - OSSP_DSP_GET_ODELAY, - - OSSP_NR_OPCODES, -}; - -enum ossp_notify_opcode { - OSSP_NOTIFY_POLL, - OSSP_NOTIFY_OBITUARY, - OSSP_NOTIFY_VOLCHG, - - OSSP_NR_NOTIFY_OPCODES, -}; - -struct ossp_mixer_arg { - int vol[2][2]; -}; - -struct ossp_dsp_open_arg { - int flags; - pid_t opener_pid; -}; - -struct ossp_dsp_rw_arg { - unsigned nonblock:1; -}; - -struct ossp_dsp_mmap_arg { - int dir; - size_t size; -}; - -struct ossp_cmd { - unsigned magic; - enum ossp_opcode opcode; - size_t din_size; - size_t dout_size; -}; - -struct ossp_reply { - unsigned magic; - int result; - size_t dout_size; /* <= cmd.data_in_size */ -}; - -struct ossp_notify { - unsigned magic; - enum ossp_notify_opcode opcode; -}; - -struct ossp_arg_size { - ssize_t carg_size; - ssize_t rarg_size; - unsigned has_fd:1; -}; - -extern const struct ossp_arg_size ossp_arg_sizes[OSSP_NR_OPCODES]; -extern const char *ossp_cmd_str[OSSP_NR_OPCODES]; -extern const char *ossp_notify_str[OSSP_NR_NOTIFY_OPCODES]; - -#endif /* _OSSP_H */ diff --git a/src/mod/endpoints/mod_skypopen/osscuse/osspd.c b/src/mod/endpoints/mod_skypopen/osscuse/osspd.c deleted file mode 100644 index dc9f36a09b..0000000000 --- a/src/mod/endpoints/mod_skypopen/osscuse/osspd.c +++ /dev/null @@ -1,2374 +0,0 @@ -/* - * osspd - OSS Proxy Daemon: emulate OSS device using CUSE - * - * Copyright (C) 2008-2010 SUSE Linux Products GmbH - * Copyright (C) 2008-2010 Tejun Heo - * - * This file is released under the GPLv2. - */ -#undef GIOVANNI - -#define FUSE_USE_VERSION 28 -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ossp.h" -#include "ossp-util.h" - -/* - * MMAP support needs to be updated to the new fuse MMAP API. Disable - * it for the time being. - */ -#warning mmap support disabled for now -/* #define OSSP_MMAP */ - -#define DFL_MIXER_NAME "mixer" -#define DFL_DSP_NAME "dsp" -#define DFL_ADSP_NAME "adsp" -#define STRFMT "S[%u/%d]" -#define STRID(os) os->id, os->pid - -#define dbg1_os(os, fmt, args...) dbg1(STRFMT" "fmt, STRID(os) , ##args) -#define dbg0_os(os, fmt, args...) dbg0(STRFMT" "fmt, STRID(os) , ##args) -#define warn_os(os, fmt, args...) warn(STRFMT" "fmt, STRID(os) , ##args) -#define err_os(os, fmt, args...) err(STRFMT" "fmt, STRID(os) , ##args) -#define warn_ose(os, err, fmt, args...) \ - warn_e(err, STRFMT" "fmt, STRID(os) , ##args) -#define err_ose(os, err, fmt, args...) \ - err_e(err, STRFMT" "fmt, STRID(os) , ##args) - -enum { - SNDRV_OSS_VERSION = ((3<<16)|(8<<8)|(1<<4)|(0)), /* 3.8.1a */ - DFL_MIXER_MAJOR = 14, - DFL_MIXER_MINOR = 0, - DFL_DSP_MAJOR = 14, - DFL_DSP_MINOR = 3, - DFL_ADSP_MAJOR = 14, - DFL_ADSP_MINOR = 12, - DFL_MAX_STREAMS = 128, - MIXER_PUT_DELAY = 600, /* 10 mins */ - /* DSPS_MMAP_SIZE / 2 must be multiple of SHMLBA */ - DSPS_MMAP_SIZE = 2 * (512 << 10), /* 512k for each dir */ -}; - -struct ossp_uid_cnt { - struct list_head link; - uid_t uid; - unsigned nr_os; -}; - -struct ossp_mixer { - pid_t pgrp; - struct list_head link; - struct list_head delayed_put_link; - unsigned refcnt; - /* the following two fields are protected by mixer_mutex */ - int vol[2][2]; - int modify_counter; - time_t put_expires; -}; - -struct ossp_mixer_cmd { - struct ossp_mixer *mixer; - struct ossp_mixer_arg set; - int out_dir; - int rvol; -}; - -#define for_each_vol(i, j) \ - for (i = 0, j = 0; i < 2; j += i << 1, j++, i = j >> 1, j &= 1) - -struct ossp_stream { - unsigned id; /* stream ID */ - struct list_head link; - struct list_head pgrp_link; - struct list_head notify_link; - unsigned refcnt; - pthread_mutex_t cmd_mutex; - pthread_mutex_t mmap_mutex; - struct fuse_pollhandle *ph; - - /* stream owner info */ - pid_t pid; - pid_t pgrp; - uid_t uid; - gid_t gid; - - /* slave info */ - pid_t slave_pid; - int cmd_fd; - int notify_tx; - int notify_rx; - - /* the following dead flag is set asynchronously, keep it separate. */ - int dead; - - /* stream mixer state, protected by mixer_mutex */ - int mixer_pending; - int vol[2][2]; - int vol_set[2][2]; - - off_t mmap_off; - size_t mmap_size; - - struct ossp_uid_cnt *ucnt; - struct fuse_session *se; /* associated fuse session */ - struct ossp_mixer *mixer; -}; - -struct ossp_dsp_stream { - struct ossp_stream os; - unsigned rw; - unsigned mmapped; - int nonblock; -}; - -#define os_to_dsps(_os) container_of(_os, struct ossp_dsp_stream, os) - -static unsigned max_streams; -static unsigned umax_streams; -static unsigned hashtbl_size; -static char dsp_slave_path[PATH_MAX]; - -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t mixer_mutex = PTHREAD_MUTEX_INITIALIZER; -static unsigned long *os_id_bitmap; -static unsigned nr_mixers; -static struct list_head *mixer_tbl; /* indexed by PGRP */ -static struct list_head *os_tbl; /* indexed by ID */ -static struct list_head *os_pgrp_tbl; /* indexed by PGRP */ -static struct list_head *os_notify_tbl; /* indexed by notify fd */ -static LIST_HEAD(uid_cnt_list); -static int notify_epfd; /* epoll used to monitor notify fds */ -static pthread_t notify_poller_thread; -static pthread_t slave_reaper_thread; -static pthread_t mixer_delayed_put_thread; -static pthread_t cuse_mixer_thread; -static pthread_t cuse_adsp_thread; -static pthread_cond_t notify_poller_kill_wait = PTHREAD_COND_INITIALIZER; -static pthread_cond_t slave_reaper_wait = PTHREAD_COND_INITIALIZER; -static LIST_HEAD(slave_corpse_list); -static LIST_HEAD(mixer_delayed_put_head); /* delayed reference */ -static pthread_cond_t mixer_delayed_put_cond = PTHREAD_COND_INITIALIZER; - -static int init_wait_fd = -1; -static int exit_on_idle; -static struct fuse_session *mixer_se; -static struct fuse_session *dsp_se; -static struct fuse_session *adsp_se; - -static void put_os(struct ossp_stream *os); - - -/*************************************************************************** - * Accessors - */ - -static struct list_head *mixer_tbl_head(pid_t pid) -{ - return &mixer_tbl[pid % hashtbl_size]; -} - -static struct list_head *os_tbl_head(uint64_t id) -{ - return &os_tbl[id % hashtbl_size]; -} - -static struct list_head *os_pgrp_tbl_head(pid_t pgrp) -{ - return &os_pgrp_tbl[pgrp % hashtbl_size]; -} - -static struct list_head *os_notify_tbl_head(int notify_rx) -{ - return &os_notify_tbl[notify_rx % hashtbl_size]; -} - -static struct ossp_mixer *find_mixer_locked(pid_t pgrp) -{ - struct ossp_mixer *mixer; - - list_for_each_entry(mixer, mixer_tbl_head(pgrp), link) - if (mixer->pgrp == pgrp) - return mixer; - return NULL; -} - -static struct ossp_mixer *find_mixer(pid_t pgrp) -{ - struct ossp_mixer *mixer; - - pthread_mutex_lock(&mutex); - mixer = find_mixer_locked(pgrp); - pthread_mutex_unlock(&mutex); - return mixer; -} - -static struct ossp_stream *find_os(unsigned id) -{ - struct ossp_stream *os, *found = NULL; - - pthread_mutex_lock(&mutex); - list_for_each_entry(os, os_tbl_head(id), link) - if (os->id == id) { - found = os; - break; - } - pthread_mutex_unlock(&mutex); - return found; -} - -static struct ossp_stream *find_os_by_notify_rx(int notify_rx) -{ - struct ossp_stream *os, *found = NULL; - - pthread_mutex_lock(&mutex); - list_for_each_entry(os, os_notify_tbl_head(notify_rx), notify_link) - if (os->notify_rx == notify_rx) { - found = os; - break; - } - pthread_mutex_unlock(&mutex); - return found; -} - - -/*************************************************************************** - * Command and ioctl helpers - */ - -static ssize_t exec_cmd_intern(struct ossp_stream *os, enum ossp_opcode opcode, - const void *carg, size_t carg_size, const void *din, size_t din_size, - void *rarg, size_t rarg_size, void *dout, size_t *dout_sizep, int fd) -{ - size_t dout_size = dout_sizep ? *dout_sizep : 0; - struct ossp_cmd cmd = { .magic = OSSP_CMD_MAGIC, .opcode = opcode, - .din_size = din_size, - .dout_size = dout_size }; - struct iovec iov = { &cmd, sizeof(cmd) }; - struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; - struct ossp_reply reply = { }; - char cmsg_buf[CMSG_SPACE(sizeof(fd))]; - char reason[512]; - int rc; - - if (os->dead) - return -EIO; - - //dbg1_os(os, "opcode %s=%d carg=%zu din=%zu rarg=%zu dout=%zu", - //ossp_cmd_str[opcode], opcode, carg_size, din_size, rarg_size, - //dout_size); -#ifndef GIOVANNI -memset(dout, 255, dout_size); -memset(din, 255, din_size); - -#define GIOVA_BLK 3840 -#define GIOVA_SLEEP 40000 -switch(opcode){ - - case 1: //OPEN - reply.result = 0; - break; - case 2: //READ - usleep((GIOVA_SLEEP/GIOVA_BLK)* *dout_sizep); - reply.result = *dout_sizep; - break; - case 3: //WRITE - usleep((GIOVA_SLEEP/GIOVA_BLK)* din_size); - reply.result = din_size; - break; - case 9: //POST - reply.result = -32; - break; - case 13: //GET_BLKSIZE - reply.result = 0; - *(int *)rarg = GIOVA_BLK; - break; - case 14: //GET_FORMATS - reply.result = 0; - *(int *)rarg = 28731; - break; - case 15: //SET_RATE - reply.result = 0; - *(int *)rarg = *(int *) carg; - break; - case 16: //SET_CHANNELS - reply.result = 0; - *(int *)rarg = *(int *) carg; - break; - case 17: //SET_FORMAT - reply.result = 0; - *(int *)rarg = *(int *) carg; - break; - case 19: //SET_FRAGMENT - reply.result = 0; - break; - default: - reply.result = 0; - break; -} -#endif // GIOVANNI - -#ifdef GIOVANNI - if (fd >= 0) { - struct cmsghdr *cmsg; - - msg.msg_control = cmsg_buf; - msg.msg_controllen = sizeof(cmsg_buf); - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); - *(int *)CMSG_DATA(cmsg) = fd; - msg.msg_controllen = cmsg->cmsg_len; - } - - if (sendmsg(os->cmd_fd, &msg, 0) <= 0) { - rc = -errno; - snprintf(reason, sizeof(reason), "command sendmsg failed: %s", - strerror(-rc)); - goto fail; - } - - if ((rc = write_fill(os->cmd_fd, carg, carg_size)) < 0 || - (rc = write_fill(os->cmd_fd, din, din_size)) < 0) { - snprintf(reason, sizeof(reason), - "can't tranfer command argument and/or data: %s", - strerror(-rc)); - goto fail; - } - if ((rc = read_fill(os->cmd_fd, &reply, sizeof(reply))) < 0) { - snprintf(reason, sizeof(reason), "can't read reply: %s", - strerror(-rc)); - goto fail; - } - - if (reply.magic != OSSP_REPLY_MAGIC) { - snprintf(reason, sizeof(reason), - "reply magic mismatch %x != %x", - reply.magic, OSSP_REPLY_MAGIC); - rc = -EINVAL; - goto fail; - } - - if (reply.result < 0) - goto out_unlock; - - if (reply.dout_size > dout_size) { - snprintf(reason, sizeof(reason), - "data out size overflow %zu > %zu", - reply.dout_size, dout_size); - rc = -EINVAL; - goto fail; - } - - dout_size = reply.dout_size; - if (dout_sizep) - *dout_sizep = dout_size; - - if ((rc = read_fill(os->cmd_fd, rarg, rarg_size)) < 0 || - (rc = read_fill(os->cmd_fd, dout, dout_size)) < 0) { - snprintf(reason, sizeof(reason), "can't read data out: %s", - strerror(-rc)); - goto fail; - } - -#endif // GIOVANNI - -out_unlock: - //dbg1_os(os, " completed, result=%d dout=%zu", - //reply.result, dout_size); - -//if(rarg) - //dbg1_os(os, " 2 %s=%d completed, result=%d dout=%zu carg=%d rarg=%d", ossp_cmd_str[opcode], opcode, - //reply.result, dout_size, carg ? *(int *) carg : 666, *(int *)rarg); - return reply.result; - -fail: - warn_os(os, "communication with slave failed (%s)", reason); - os->dead = 1; - return rc; -} - -static ssize_t exec_cmd(struct ossp_stream *os, enum ossp_opcode opcode, - const void *carg, size_t carg_size, const void *din, size_t din_size, - void *rarg, size_t rarg_size, void *dout, size_t *dout_sizep, int fd) -{ - int is_mixer; - int i, j; - ssize_t ret, mret; - - /* mixer command is handled exlicitly below */ - is_mixer = opcode == OSSP_MIXER; - if (is_mixer) { - ret = -pthread_mutex_trylock(&os->cmd_mutex); - if (ret) - return ret; - } else { - pthread_mutex_lock(&os->cmd_mutex); - - ret = exec_cmd_intern(os, opcode, carg, carg_size, - din, din_size, rarg, rarg_size, - dout, dout_sizep, fd); - } - - /* lazy mixer handling */ - pthread_mutex_lock(&mixer_mutex); - - if (os->mixer_pending) { - struct ossp_mixer_arg marg; - repeat_mixer: - /* we have mixer command pending */ - memcpy(marg.vol, os->vol_set, sizeof(os->vol_set)); - memset(os->vol_set, -1, sizeof(os->vol_set)); - - pthread_mutex_unlock(&mixer_mutex); - mret = exec_cmd_intern(os, OSSP_MIXER, &marg, sizeof(marg), - NULL, 0, &marg, sizeof(marg), NULL, NULL, - -1); - pthread_mutex_lock(&mixer_mutex); - - /* was there mixer set request while executing mixer command? */ - for_each_vol(i, j) - if (os->vol_set[i][j] >= 0) - goto repeat_mixer; - - /* update internal mixer state */ - if (mret == 0) { - for_each_vol(i, j) { - if (marg.vol[i][j] >= 0) { - if (os->vol[i][j] != marg.vol[i][j]) - os->mixer->modify_counter++; - os->vol[i][j] = marg.vol[i][j]; - } - } - } - os->mixer_pending = 0; - } - - pthread_mutex_unlock(&os->cmd_mutex); - - /* - * mixer mutex must be released after cmd_mutex so that - * exec_mixer_cmd() can guarantee that mixer_pending flags - * will be handled immediately or when the currently - * in-progress command completes. - */ - pthread_mutex_unlock(&mixer_mutex); - - return is_mixer ? mret : ret; -} - -static ssize_t exec_simple_cmd(struct ossp_stream *os, - enum ossp_opcode opcode, void *carg, void *rarg) -{ - return exec_cmd(os, opcode, - carg, ossp_arg_sizes[opcode].carg_size, NULL, 0, - rarg, ossp_arg_sizes[opcode].rarg_size, NULL, NULL, -1); -} - -static int ioctl_prep_uarg(fuse_req_t req, void *in, size_t in_sz, void *out, - size_t out_sz, void *uarg, const void *in_buf, - size_t in_bufsz, size_t out_bufsz) -{ - struct iovec in_iov = { }, out_iov = { }; - int retry = 0; - - if (in) { - if (!in_bufsz) { - in_iov.iov_base = uarg; - in_iov.iov_len = in_sz; - retry = 1; - } else { - assert(in_bufsz == in_sz); - memcpy(in, in_buf, in_sz); - } - } - - if (out) { - if (!out_bufsz) { - out_iov.iov_base = uarg; - out_iov.iov_len = out_sz; - retry = 1; - } else - assert(out_bufsz == out_sz); - } - - if (retry) - fuse_reply_ioctl_retry(req, &in_iov, 1, &out_iov, 1); - - return retry; -} - -#define PREP_UARG(inp, outp) do { \ - if (ioctl_prep_uarg(req, (inp), sizeof(*(inp)), \ - (outp), sizeof(*(outp)), uarg, \ - in_buf, in_bufsz, out_bufsz)) \ - return; \ -} while (0) - -#define IOCTL_RETURN(result, outp) do { \ - if ((outp) != NULL) \ - fuse_reply_ioctl(req, result, (outp), sizeof(*(outp))); \ - else \ - fuse_reply_ioctl(req, result, NULL, 0); \ - return; \ -} while (0) - - -/*************************************************************************** - * Mixer implementation - */ - -static void put_mixer_real(struct ossp_mixer *mixer) -{ - if (!--mixer->refcnt) { - dbg0("DESTROY mixer(%d)", mixer->pgrp); - list_del_init(&mixer->link); - list_del_init(&mixer->delayed_put_link); - free(mixer); - nr_mixers--; - - /* - * If exit_on_idle, mixer for pgrp0 is touched during - * init and each stream has mixer attached. As mixers - * are destroyed after they have been idle for - * MIXER_PUT_DELAY seconds, we can use it for idle - * detection. Note that this might race with - * concurrent open. The race is inherent. - */ - if (exit_on_idle && !nr_mixers) { - info("idle, exiting"); - exit(0); - } - } -} - -static struct ossp_mixer *get_mixer(pid_t pgrp) -{ - struct ossp_mixer *mixer; - - pthread_mutex_lock(&mutex); - - /* is there a matching one? */ - mixer = find_mixer_locked(pgrp); - if (mixer) { - if (list_empty(&mixer->delayed_put_link)) - mixer->refcnt++; - else - list_del_init(&mixer->delayed_put_link); - goto out_unlock; - } - - /* reap delayed put list if there are too many mixers */ - while (nr_mixers > 2 * max_streams && - !list_empty(&mixer_delayed_put_head)) { - struct ossp_mixer *mixer = - list_first_entry(&mixer_delayed_put_head, - struct ossp_mixer, delayed_put_link); - - assert(mixer->refcnt == 1); - put_mixer_real(mixer); - } - - /* create a new one */ - mixer = calloc(1, sizeof(*mixer)); - if (!mixer) { - warn("failed to allocate mixer for %d", pgrp); - mixer = NULL; - goto out_unlock; - } - - mixer->pgrp = pgrp; - INIT_LIST_HEAD(&mixer->link); - INIT_LIST_HEAD(&mixer->delayed_put_link); - mixer->refcnt = 1; - memset(mixer->vol, -1, sizeof(mixer->vol)); - - list_add(&mixer->link, mixer_tbl_head(pgrp)); - nr_mixers++; - dbg0("CREATE mixer(%d)", pgrp); - -out_unlock: - pthread_mutex_unlock(&mutex); - return mixer; -} - -static void put_mixer(struct ossp_mixer *mixer) -{ - pthread_mutex_lock(&mutex); - - if (mixer) { - if (mixer->refcnt == 1) { - struct timespec ts; - - clock_gettime(CLOCK_REALTIME, &ts); - mixer->put_expires = ts.tv_sec + MIXER_PUT_DELAY; - list_add_tail(&mixer->delayed_put_link, - &mixer_delayed_put_head); - pthread_cond_signal(&mixer_delayed_put_cond); - } else - put_mixer_real(mixer); - } - - pthread_mutex_unlock(&mutex); -} - -static void *mixer_delayed_put_worker(void *arg) -{ - struct ossp_mixer *mixer; - struct timespec ts; - time_t now; - - pthread_mutex_lock(&mutex); -again: - clock_gettime(CLOCK_REALTIME, &ts); - now = ts.tv_sec; - - mixer = NULL; - while (!list_empty(&mixer_delayed_put_head)) { - mixer = list_first_entry(&mixer_delayed_put_head, - struct ossp_mixer, delayed_put_link); - - if (now <= mixer->put_expires) - break; - - assert(mixer->refcnt == 1); - put_mixer_real(mixer); - mixer = NULL; - } - - if (mixer) { - ts.tv_sec = mixer->put_expires + 1; - pthread_cond_timedwait(&mixer_delayed_put_cond, &mutex, &ts); - } else - pthread_cond_wait(&mixer_delayed_put_cond, &mutex); - - goto again; -} - -static void init_mixer_cmd(struct ossp_mixer_cmd *mxcmd, - struct ossp_mixer *mixer) -{ - memset(mxcmd, 0, sizeof(*mxcmd)); - memset(&mxcmd->set.vol, -1, sizeof(mxcmd->set.vol)); - mxcmd->mixer = mixer; - mxcmd->out_dir = -1; -} - -static int exec_mixer_cmd(struct ossp_mixer_cmd *mxcmd, struct ossp_stream *os) -{ - int i, j, rc; - - /* - * Set pending flags before trying to execute mixer command. - * Combined with lock release order in exec_cmd(), this - * guarantees that the mixer command will be executed - * immediately or when the current command completes. - */ - pthread_mutex_lock(&mixer_mutex); - os->mixer_pending = 1; - for_each_vol(i, j) - if (mxcmd->set.vol[i][j] >= 0) - os->vol_set[i][j] = mxcmd->set.vol[i][j]; - pthread_mutex_unlock(&mixer_mutex); - - rc = exec_simple_cmd(os, OSSP_MIXER, NULL, NULL); - if (rc >= 0) { - dbg0_os(os, "volume set=%d/%d:%d/%d get=%d/%d:%d/%d", - mxcmd->set.vol[PLAY][LEFT], mxcmd->set.vol[PLAY][RIGHT], - mxcmd->set.vol[REC][LEFT], mxcmd->set.vol[REC][RIGHT], - os->vol[PLAY][LEFT], os->vol[PLAY][RIGHT], - os->vol[REC][LEFT], os->vol[REC][RIGHT]); - } else if (rc != -EBUSY) - warn_ose(os, rc, "mixer command failed"); - - return rc; -} - -static void finish_mixer_cmd(struct ossp_mixer_cmd *mxcmd) -{ - struct ossp_mixer *mixer = mxcmd->mixer; - struct ossp_stream *os; - int dir = mxcmd->out_dir; - int vol[2][2] = { }; - int cnt[2][2] = { }; - int i, j; - - pthread_mutex_lock(&mixer_mutex); - - /* get volume of all streams attached to this mixer */ - pthread_mutex_lock(&mutex); - list_for_each_entry(os, os_pgrp_tbl_head(mixer->pgrp), pgrp_link) { - if (os->pgrp != mixer->pgrp) - continue; - for_each_vol(i, j) { - if (os->vol[i][j] < 0) - continue; - vol[i][j] += os->vol[i][j]; - cnt[i][j]++; - } - } - pthread_mutex_unlock(&mutex); - - /* calculate the summary volume values */ - for_each_vol(i, j) { - if (mxcmd->set.vol[i][j] >= 0) - vol[i][j] = mxcmd->set.vol[i][j]; - else if (cnt[i][j]) - vol[i][j] = vol[i][j] / cnt[i][j]; - else if (mixer->vol[i][j] >= 0) - vol[i][j] = mixer->vol[i][j]; - else - vol[i][j] = 100; - - vol[i][j] = min(max(0, vol[i][j]), 100); - } - - if (dir >= 0) - mxcmd->rvol = vol[dir][LEFT] | (vol[dir][RIGHT] << 8); - - pthread_mutex_unlock(&mixer_mutex); -} - -static void mixer_simple_ioctl(fuse_req_t req, struct ossp_mixer *mixer, - unsigned cmd, void *uarg, const void *in_buf, - size_t in_bufsz, size_t out_bufsz, - int *not_minep) -{ - const char *id = "OSS Proxy", *name = "Mixer"; - int i; - - switch (cmd) { - case SOUND_MIXER_INFO: { - struct mixer_info info = { }; - - PREP_UARG(NULL, &info); - strncpy(info.id, id, sizeof(info.id) - 1); - strncpy(info.name, name, sizeof(info.name) - 1); - info.modify_counter = mixer->modify_counter; - IOCTL_RETURN(0, &info); - } - - case SOUND_OLD_MIXER_INFO: { - struct _old_mixer_info info = { }; - - PREP_UARG(NULL, &info); - strncpy(info.id, id, sizeof(info.id) - 1); - strncpy(info.name, name, sizeof(info.name) - 1); - IOCTL_RETURN(0, &info); - } - - case OSS_GETVERSION: - i = SNDRV_OSS_VERSION; - goto puti; - case SOUND_MIXER_READ_DEVMASK: - case SOUND_MIXER_READ_STEREODEVS: - i = SOUND_MASK_PCM | SOUND_MASK_IGAIN; - goto puti; - case SOUND_MIXER_READ_CAPS: - i = SOUND_CAP_EXCL_INPUT; - goto puti; - case SOUND_MIXER_READ_RECMASK: - case SOUND_MIXER_READ_RECSRC: - i = SOUND_MASK_IGAIN; - goto puti; - puti: - PREP_UARG(NULL, &i); - IOCTL_RETURN(0, &i); - - case SOUND_MIXER_WRITE_RECSRC: - IOCTL_RETURN(0, NULL); - - default: - *not_minep = 1; - return; - } - assert(0); -} - -static void mixer_do_ioctl(fuse_req_t req, struct ossp_mixer *mixer, - unsigned cmd, void *uarg, const void *in_buf, - size_t in_bufsz, size_t out_bufsz) -{ - struct ossp_mixer_cmd mxcmd; - struct ossp_stream *os, **osa; - int not_mine = 0; - int slot = cmd & 0xff, dir; - int nr_os; - int i, rc; - - mixer_simple_ioctl(req, mixer, cmd, uarg, in_buf, in_bufsz, out_bufsz, - ¬_mine); - if (!not_mine) - return; - - rc = -ENXIO; - if (!(cmd & (SIOC_IN | SIOC_OUT))) - goto err; - - /* - * Okay, it's not one of the easy ones. Build mxcmd for - * actual volume control. - */ - if (cmd & SIOC_IN) - PREP_UARG(&i, &i); - else - PREP_UARG(NULL, &i); - - switch (slot) { - case SOUND_MIXER_PCM: - dir = PLAY; - break; - case SOUND_MIXER_IGAIN: - dir = REC; - break; - default: - i = 0; - IOCTL_RETURN(0, &i); - } - - init_mixer_cmd(&mxcmd, mixer); - - if (cmd & SIOC_IN) { - unsigned l, r; - - rc = -EINVAL; - l = i & 0xff; - r = (i >> 8) & 0xff; - if (l > 100 || r > 100) - goto err; - - mixer->vol[dir][LEFT] = mxcmd.set.vol[dir][LEFT] = l; - mixer->vol[dir][RIGHT] = mxcmd.set.vol[dir][RIGHT] = r; - } - mxcmd.out_dir = dir; - - /* - * Apply volume conrol - */ - /* acquire target streams */ - pthread_mutex_lock(&mutex); - osa = calloc(max_streams, sizeof(osa[0])); - if (!osa) { - pthread_mutex_unlock(&mutex); - rc = -ENOMEM; - goto err; - } - - nr_os = 0; - list_for_each_entry(os, os_pgrp_tbl_head(mixer->pgrp), pgrp_link) { - if (os->pgrp == mixer->pgrp) { - osa[nr_os++] = os; - os->refcnt++; - } - } - - pthread_mutex_unlock(&mutex); - - /* execute mxcmd for each stream and put it */ - for (i = 0; i < nr_os; i++) { - exec_mixer_cmd(&mxcmd, osa[i]); - put_os(osa[i]); - } - - finish_mixer_cmd(&mxcmd); - free(osa); - - IOCTL_RETURN(0, out_bufsz ? &mxcmd.rvol : NULL); - -err: - fuse_reply_err(req, -rc); -} - -static void mixer_open(fuse_req_t req, struct fuse_file_info *fi) -{ - pid_t pid = fuse_req_ctx(req)->pid, pgrp; - struct ossp_mixer *mixer; - int rc; - - rc = get_proc_self_info(pid, &pgrp, NULL, 0); - if (rc) { - err_e(rc, "get_proc_self_info(%d) failed", pid); - fuse_reply_err(req, -rc); - return; - } - - mixer = get_mixer(pgrp); - fi->fh = pgrp; - - if (mixer) - fuse_reply_open(req, fi); - else - fuse_reply_err(req, ENOMEM); -} - -static void mixer_ioctl(fuse_req_t req, int signed_cmd, void *uarg, - struct fuse_file_info *fi, unsigned int flags, - const void *in_buf, size_t in_bufsz, size_t out_bufsz) -{ - struct ossp_mixer *mixer; - - mixer = find_mixer(fi->fh); - if (!mixer) { - fuse_reply_err(req, EBADF); - return; - } - - mixer_do_ioctl(req, mixer, signed_cmd, uarg, in_buf, in_bufsz, - out_bufsz); -} - -static void mixer_release(fuse_req_t req, struct fuse_file_info *fi) -{ - struct ossp_mixer *mixer; - - mixer = find_mixer(fi->fh); - if (mixer) { - put_mixer(mixer); - fuse_reply_err(req, 0); - } else - fuse_reply_err(req, EBADF); -} - - -/*************************************************************************** - * Stream implementation - */ - -static int alloc_os(size_t stream_size, size_t mmap_size, pid_t pid, uid_t pgrp, - uid_t uid, gid_t gid, int cmd_sock, - const int *notify, struct fuse_session *se, - struct ossp_stream **osp) -{ - struct ossp_uid_cnt *tmp_ucnt, *ucnt = NULL; - struct ossp_stream *os; - int rc; - - assert(stream_size >= sizeof(struct ossp_stream)); - os = calloc(1, stream_size); - if (!os) - return -ENOMEM; - - INIT_LIST_HEAD(&os->link); - INIT_LIST_HEAD(&os->pgrp_link); - INIT_LIST_HEAD(&os->notify_link); - os->refcnt = 1; - - rc = -pthread_mutex_init(&os->cmd_mutex, NULL); - if (rc) - goto err_free; - - rc = -pthread_mutex_init(&os->mmap_mutex, NULL); - if (rc) - goto err_destroy_cmd_mutex; - - pthread_mutex_lock(&mutex); - - list_for_each_entry(tmp_ucnt, &uid_cnt_list, link) - if (tmp_ucnt->uid == uid) { - ucnt = tmp_ucnt; - break; - } - if (!ucnt) { - rc = -ENOMEM; - ucnt = calloc(1, sizeof(*ucnt)); - if (!ucnt) - goto err_unlock; - ucnt->uid = uid; - list_add(&ucnt->link, &uid_cnt_list); - } - - rc = -EBUSY; - if (ucnt->nr_os + 1 > umax_streams) - goto err_unlock; - - /* everything looks fine, allocate id and init stream */ - rc = -EBUSY; - os->id = find_next_zero_bit(os_id_bitmap, max_streams, 0); - if (os->id >= max_streams) - goto err_unlock; - __set_bit(os->id, os_id_bitmap); - - os->cmd_fd = cmd_sock; - os->notify_tx = notify[1]; - os->notify_rx = notify[0]; - os->pid = pid; - os->pgrp = pgrp; - os->uid = uid; - os->gid = gid; - if (mmap_size) { - os->mmap_off = os->id * mmap_size; - os->mmap_size = mmap_size; - } - os->ucnt = ucnt; - os->se = se; - - memset(os->vol, -1, sizeof(os->vol)); - memset(os->vol_set, -1, sizeof(os->vol)); - - list_add(&os->link, os_tbl_head(os->id)); - list_add(&os->pgrp_link, os_pgrp_tbl_head(os->pgrp)); - - ucnt->nr_os++; - *osp = os; - pthread_mutex_unlock(&mutex); - return 0; - -err_unlock: - pthread_mutex_unlock(&mutex); - pthread_mutex_destroy(&os->mmap_mutex); -err_destroy_cmd_mutex: - pthread_mutex_destroy(&os->cmd_mutex); -err_free: - free(os); - return rc; -} - -static void shutdown_notification(struct ossp_stream *os) -{ - struct ossp_notify obituary = { .magic = OSSP_NOTIFY_MAGIC, - .opcode = OSSP_NOTIFY_OBITUARY }; - ssize_t ret; - - /* - * Shutdown notification for this stream. We politely ask - * notify_poller to shut the receive side down to avoid racing - * with it. - */ - while (os->notify_rx >= 0) { - ret = write(os->notify_tx, &obituary, sizeof(obituary)); - if (ret <= 0) { - if (ret == 0) - warn_os(os, "unexpected EOF on notify_tx"); - else if (errno != EPIPE) - warn_ose(os, -errno, - "unexpected error on notify_tx"); - close(os->notify_rx); - os->notify_rx = -1; - break; - } - - if (ret != sizeof(obituary)) - warn_os(os, "short transfer on notify_tx"); - pthread_cond_wait(¬ify_poller_kill_wait, &mutex); - } -} - -static void put_os(struct ossp_stream *os) -{ - if (!os) - return; - - pthread_mutex_lock(&mutex); - - assert(os->refcnt); - if (--os->refcnt) { - pthread_mutex_unlock(&mutex); - return; - } - - os->dead = 1; - shutdown_notification(os); - - dbg0_os(os, "DESTROY"); - - list_del_init(&os->link); - list_del_init(&os->pgrp_link); - list_del_init(&os->notify_link); - os->ucnt->nr_os--; - - pthread_mutex_unlock(&mutex); - - close(os->cmd_fd); - close(os->notify_tx); - put_mixer(os->mixer); - pthread_mutex_destroy(&os->cmd_mutex); - pthread_mutex_destroy(&os->mmap_mutex); - - pthread_mutex_lock(&mutex); - dbg1_os(os, "stream dead, requesting reaping"); - list_add_tail(&os->link, &slave_corpse_list); - pthread_cond_signal(&slave_reaper_wait); - pthread_mutex_unlock(&mutex); -} - -static void set_extra_env(pid_t pid) -{ - char procenviron[32]; - const int step = 1024; - char *data = malloc(step + 1); - int ofs = 0; - int fd; - int ret; - - if (!data) - return; - - sprintf(procenviron, "/proc/%d/environ", pid); - fd = open(procenviron, O_RDONLY); - if (fd < 0) - return; - - /* - * There should really be a 'read whole file to a newly allocated - * buffer' function. - */ - while ((ret = read(fd, data + ofs, step)) > 0) { - char *newdata; - ofs += ret; - newdata = realloc(data, ofs + step + 1); - if (!newdata) { - ret = -1; - break; - } - data = newdata; - } - if (ret == 0) { - char *ptr = data; - /* Append the extra 0 for end condition */ - data[ofs] = 0; - - while ((ret = strlen(ptr)) > 0) { - /* - * Copy all PULSE variables and DISPLAY so that - * ssh -X remotehost 'mplayer -ao oss' will work - */ - if (!strncmp(ptr, "DISPLAY=", 8) || - !strncmp(ptr, "PULSE_", 6)) - putenv(ptr); - ptr += ret + 1; - } - } - - free(data); - close(fd); -} - -#ifndef GIOVANNI -int contapid = 13000; -#endif// GIOVANNI - -static int create_os(const char *slave_path, - size_t stream_size, size_t mmap_size, - pid_t pid, pid_t pgrp, uid_t uid, gid_t gid, - struct fuse_session *se, struct ossp_stream **osp) -{ - static pthread_mutex_t create_mutex = PTHREAD_MUTEX_INITIALIZER; - int cmd_sock[2] = { -1, -1 }; - int notify_sock[2] = { -1, -1 }; - struct ossp_stream *os = NULL; - struct epoll_event ev = { }; - int i, rc; - - /* - * Only one thread can be creating a stream. This is to avoid - * leaking unwanted fds into slaves. - */ - pthread_mutex_lock(&create_mutex); - - /* prepare communication channels */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_sock) || - socketpair(AF_UNIX, SOCK_STREAM, 0, notify_sock)) { - rc = -errno; - warn_e(rc, "failed to create slave command channel"); - goto close_all; - } - - if (fcntl(notify_sock[0], F_SETFL, O_NONBLOCK) < 0) { - rc = -errno; - warn_e(rc, "failed to set NONBLOCK on notify sock"); - goto close_all; - } - - /* - * Alloc stream which will be responsible for all server side - * resources from now on. - */ - rc = alloc_os(stream_size, mmap_size, pid, pgrp, uid, gid, cmd_sock[0], - notify_sock, se, &os); - if (rc) { - warn_e(rc, "failed to allocate stream for %d", pid); - goto close_all; - } - - rc = -ENOMEM; - os->mixer = get_mixer(pgrp); - if (!os->mixer) - goto put_os; - - /* - * Register notification. If successful, notify_poller has - * custody of notify_rx fd. - */ - pthread_mutex_lock(&mutex); - list_add(&os->notify_link, os_notify_tbl_head(os->notify_rx)); - pthread_mutex_unlock(&mutex); - -#ifndef GIOVANNI - os->slave_pid = contapid; - contapid++; - if(contapid > 30000) - contapid=13000; -#endif //GIOVANNI - -//#ifdef GIOVANNI - ev.events = EPOLLIN; - ev.data.fd = notify_sock[0]; - if (epoll_ctl(notify_epfd, EPOLL_CTL_ADD, notify_sock[0], &ev)) { - /* - * Without poller watching this notify sock, poller - * shutdown sequence in shutdown_notification() can't - * be used. Kill notification rx manually. - */ - rc = -errno; - warn_ose(os, rc, "failed to add notify epoll"); - close(os->notify_rx); - os->notify_rx = -1; - goto put_os; - } - - /* start slave */ - os->slave_pid = fork(); - if (os->slave_pid < 0) { - rc = -errno; - warn_ose(os, rc, "failed to fork slave"); - goto put_os; - } - - if (os->slave_pid == 0) { - /* child */ - char id_str[2][16], fd_str[3][16]; - char mmap_off_str[32], mmap_size_str[32]; - char log_str[16], slave_path_copy[PATH_MAX]; - char *argv[] = { slave_path_copy, "-u", id_str[0], - "-g", id_str[1], "-c", fd_str[0], - "-n", fd_str[1], "-m", fd_str[2], - "-o", mmap_off_str, "-s", mmap_size_str, - "-l", log_str, NULL, NULL }; - struct passwd *pwd; - - /* drop stuff we don't need */ - if (close(cmd_sock[0]) || close(notify_sock[0])) - fatal_e(-errno, "failed to close server pipe fds"); - -#ifdef OSSP_MMAP - if (!mmap_size) - close(fuse_mmap_fd(se)); -#endif - - clearenv(); - pwd = getpwuid(os->uid); - if (pwd) { - setenv("LOGNAME", pwd->pw_name, 1); - setenv("USER", pwd->pw_name, 1); - setenv("HOME", pwd->pw_dir, 1); - } - /* Set extra environment variables from the caller */ - set_extra_env(pid); - - /* prep and exec */ - slave_path_copy[sizeof(slave_path_copy) - 1] = '\0'; - strncpy(slave_path_copy, slave_path, sizeof(slave_path_copy) - 1); - if (slave_path_copy[sizeof(slave_path_copy) - 1] != '\0') { - rc = -errno; - err_ose(os, rc, "slave path too long"); - goto child_fail; - } - - snprintf(id_str[0], sizeof(id_str[0]), "%d", os->uid); - snprintf(id_str[1], sizeof(id_str[0]), "%d", os->gid); - snprintf(fd_str[0], sizeof(fd_str[0]), "%d", cmd_sock[1]); - snprintf(fd_str[1], sizeof(fd_str[1]), "%d", notify_sock[1]); - snprintf(fd_str[2], sizeof(fd_str[2]), "%d", -#ifdef OSSP_MMAP - mmap_size ? fuse_mmap_fd(se) : -#endif - -1); - snprintf(mmap_off_str, sizeof(mmap_off_str), "0x%llx", - (unsigned long long)os->mmap_off); - snprintf(mmap_size_str, sizeof(mmap_size_str), "0x%zx", - mmap_size); - snprintf(log_str, sizeof(log_str), "%d", ossp_log_level); - if (ossp_log_timestamp) - argv[ARRAY_SIZE(argv) - 2] = "-t"; - - execv(slave_path, argv); - rc = -errno; - err_ose(os, rc, "execv failed for <%d>", pid); - child_fail: - _exit(1); - } -//#endif //GIOVANNI - - /* turn on CLOEXEC on all server side fds */ - if (fcntl(os->cmd_fd, F_SETFD, FD_CLOEXEC) < 0 || - fcntl(os->notify_tx, F_SETFD, FD_CLOEXEC) < 0 || - fcntl(os->notify_rx, F_SETFD, FD_CLOEXEC) < 0) { - rc = -errno; - err_ose(os, rc, "failed to set CLOEXEC on server side fds"); - goto put_os; - } - - dbg0_os(os, "CREATE slave=%d %s", os->slave_pid, slave_path); - dbg0_os(os, " client=%d cmd=%d:%d notify=%d:%d mmap=%d:0x%llx:%zu", - pid, cmd_sock[0], cmd_sock[1], notify_sock[0], notify_sock[1], -#ifdef OSSP_MMAP - os->mmap_size ? fuse_mmap_fd(se) : -#endif - -1, - (unsigned long long)os->mmap_off, os->mmap_size); - - *osp = os; - rc = 0; - goto close_client_fds; - -put_os: - put_os(os); -close_client_fds: - close(cmd_sock[1]); - pthread_mutex_unlock(&create_mutex); - return rc; - -close_all: - for (i = 0; i < 2; i++) { - close(cmd_sock[i]); - close(notify_sock[i]); - } - pthread_mutex_unlock(&create_mutex); - return rc; -} - -static void dsp_open_common(fuse_req_t req, struct fuse_file_info *fi, - struct fuse_session *se) -{ - const struct fuse_ctx *fuse_ctx = fuse_req_ctx(req); - struct ossp_dsp_open_arg arg = { }; - struct ossp_stream *os = NULL; - struct ossp_mixer *mixer; - struct ossp_dsp_stream *dsps; - struct ossp_mixer_cmd mxcmd; - pid_t pgrp; - ssize_t ret; - - ret = get_proc_self_info(fuse_ctx->pid, &pgrp, NULL, 0); - if (ret) { - err_e(ret, "get_proc_self_info(%d) failed", fuse_ctx->pid); - goto err; - } - - ret = create_os(dsp_slave_path, sizeof(*dsps), DSPS_MMAP_SIZE, - fuse_ctx->pid, pgrp, fuse_ctx->uid, fuse_ctx->gid, - se, &os); - if (ret) - goto err; - dsps = os_to_dsps(os); - mixer = os->mixer; - - switch (fi->flags & O_ACCMODE) { - case O_WRONLY: - dsps->rw |= 1 << PLAY; - break; - case O_RDONLY: - dsps->rw |= 1 << REC; - break; - case O_RDWR: - dsps->rw |= (1 << PLAY) | (1 << REC); - break; - default: - assert(0); - } - - arg.flags = fi->flags; - arg.opener_pid = os->pid; - ret = exec_simple_cmd(&dsps->os, OSSP_DSP_OPEN, &arg, NULL); - if (ret < 0) { - put_os(os); - goto err; - } - - memcpy(os->vol, mixer->vol, sizeof(os->vol)); - if (os->vol[PLAY][0] >= 0 || os->vol[REC][0] >= 0) { - init_mixer_cmd(&mxcmd, mixer); - memcpy(mxcmd.set.vol, os->vol, sizeof(os->vol)); - exec_mixer_cmd(&mxcmd, os); - finish_mixer_cmd(&mxcmd); - } - - fi->direct_io = 1; - fi->nonseekable = 1; - fi->fh = os->id; - - fuse_reply_open(req, fi); - return; - -err: - fuse_reply_err(req, -ret); -} - -static void dsp_open(fuse_req_t req, struct fuse_file_info *fi) -{ - dsp_open_common(req, fi, dsp_se); -} - -static void adsp_open(fuse_req_t req, struct fuse_file_info *fi) -{ - dsp_open_common(req, fi, adsp_se); -} - -static void dsp_release(fuse_req_t req, struct fuse_file_info *fi) -{ - struct ossp_stream *os; - - os = find_os(fi->fh); - if (os) { - put_os(os); - fuse_reply_err(req, 0); - } else - fuse_reply_err(req, EBADF); -} - -static void dsp_read(fuse_req_t req, size_t size, off_t off, - struct fuse_file_info *fi) -{ - struct ossp_dsp_rw_arg arg = { }; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - void *buf = NULL; - ssize_t ret; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto out; - dsps = os_to_dsps(os); - - ret = -EINVAL; - if (!(dsps->rw & (1 << REC))) - goto out; - - ret = -ENXIO; - if (dsps->mmapped) - goto out; - - ret = -ENOMEM; - buf = malloc(size); - if (!buf) - goto out; - - arg.nonblock = (fi->flags & O_NONBLOCK) || dsps->nonblock; - - ret = exec_cmd(os, OSSP_DSP_READ, &arg, sizeof(arg), - NULL, 0, NULL, 0, buf, &size, -1); -out: - if (ret >= 0) - fuse_reply_buf(req, buf, size); - else - fuse_reply_err(req, -ret); - - free(buf); -} - -static void dsp_write(fuse_req_t req, const char *buf, size_t size, off_t off, - struct fuse_file_info *fi) -{ - struct ossp_dsp_rw_arg arg = { }; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - ssize_t ret; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto out; - dsps = os_to_dsps(os); - - ret = -EINVAL; - if (!(dsps->rw & (1 << PLAY))) - goto out; - - ret = -ENXIO; - if (dsps->mmapped) - goto out; - - arg.nonblock = (fi->flags & O_NONBLOCK) || dsps->nonblock; - - ret = exec_cmd(os, OSSP_DSP_WRITE, &arg, sizeof(arg), - buf, size, NULL, 0, NULL, NULL, -1); -out: - if (ret >= 0) - fuse_reply_write(req, ret); - else - fuse_reply_err(req, -ret); -} - -static void dsp_poll(fuse_req_t req, struct fuse_file_info *fi, - struct fuse_pollhandle *ph) -{ - int notify = ph != NULL; - unsigned revents = 0; - struct ossp_stream *os; - ssize_t ret; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto out; - - if (ph) { - pthread_mutex_lock(&mutex); - if (os->ph) - fuse_pollhandle_destroy(os->ph); - os->ph = ph; - pthread_mutex_unlock(&mutex); - } - - ret = exec_simple_cmd(os, OSSP_DSP_POLL, ¬ify, &revents); -out: - if (ret >= 0) - fuse_reply_poll(req, revents); - else - fuse_reply_err(req, -ret); -} - -static void dsp_ioctl(fuse_req_t req, int signed_cmd, void *uarg, - struct fuse_file_info *fi, unsigned int flags, - const void *in_buf, size_t in_bufsz, size_t out_bufsz) -{ - /* some ioctl constants are long and has the highest bit set */ - unsigned cmd = signed_cmd; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - enum ossp_opcode op; - ssize_t ret; - int i; - - ret = -EBADF; - os = find_os(fi->fh); - if (!os) - goto err; - dsps = os_to_dsps(os); - - /* mixer commands are allowed on DSP devices */ - if (((cmd >> 8) & 0xff) == 'M') { - mixer_do_ioctl(req, os->mixer, cmd, uarg, in_buf, in_bufsz, - out_bufsz); - return; - } - - /* and the rest */ - switch (cmd) { - case OSS_GETVERSION: - i = SNDRV_OSS_VERSION; - PREP_UARG(NULL, &i); - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_GETCAPS: - i = DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | -#ifdef OSSP_MMAP - DSP_CAP_MMAP | -#endif - DSP_CAP_MULTI; - PREP_UARG(NULL, &i); - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_NONBLOCK: - dsps->nonblock = 1; - ret = 0; - IOCTL_RETURN(0, NULL); - - case SNDCTL_DSP_RESET: op = OSSP_DSP_RESET; goto nd; - case SNDCTL_DSP_SYNC: op = OSSP_DSP_SYNC; goto nd; - case SNDCTL_DSP_POST: op = OSSP_DSP_POST; goto nd; - nd: - ret = exec_simple_cmd(&dsps->os, op, NULL, NULL); - if (ret) - goto err; - IOCTL_RETURN(0, NULL); - - case SOUND_PCM_READ_RATE: op = OSSP_DSP_GET_RATE; goto ri; - case SOUND_PCM_READ_BITS: op = OSSP_DSP_GET_FORMAT; goto ri; - case SOUND_PCM_READ_CHANNELS: op = OSSP_DSP_GET_CHANNELS; goto ri; - case SNDCTL_DSP_GETBLKSIZE: op = OSSP_DSP_GET_BLKSIZE; goto ri; - case SNDCTL_DSP_GETFMTS: op = OSSP_DSP_GET_FORMATS; goto ri; - case SNDCTL_DSP_GETTRIGGER: op = OSSP_DSP_GET_TRIGGER; goto ri; - ri: - PREP_UARG(NULL, &i); - ret = exec_simple_cmd(&dsps->os, op, NULL, &i); - if (ret) - goto err; - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_SPEED: op = OSSP_DSP_SET_RATE; goto wi; - case SNDCTL_DSP_SETFMT: op = OSSP_DSP_SET_FORMAT; goto wi; - case SNDCTL_DSP_CHANNELS: op = OSSP_DSP_SET_CHANNELS; goto wi; - case SNDCTL_DSP_SUBDIVIDE: op = OSSP_DSP_SET_SUBDIVISION; goto wi; - wi: - PREP_UARG(&i, &i); - ret = exec_simple_cmd(&dsps->os, op, &i, &i); - if (ret) - goto err; - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_STEREO: - PREP_UARG(NULL, &i); - i = 2; - ret = exec_simple_cmd(&dsps->os, OSSP_DSP_SET_CHANNELS, &i, &i); - i--; - if (ret) - goto err; - IOCTL_RETURN(0, &i); - - case SNDCTL_DSP_SETFRAGMENT: - PREP_UARG(&i, NULL); - ret = exec_simple_cmd(&dsps->os, - OSSP_DSP_SET_FRAGMENT, &i, NULL); - if (ret) - goto err; - IOCTL_RETURN(0, NULL); - - case SNDCTL_DSP_SETTRIGGER: - PREP_UARG(&i, NULL); - ret = exec_simple_cmd(&dsps->os, - OSSP_DSP_SET_TRIGGER, &i, NULL); - if (ret) - goto err; - IOCTL_RETURN(0, NULL); - - case SNDCTL_DSP_GETOSPACE: - case SNDCTL_DSP_GETISPACE: { - struct audio_buf_info info; - - ret = -EINVAL; - if (cmd == SNDCTL_DSP_GETOSPACE) { - if (!(dsps->rw & (1 << PLAY))) - goto err; - op = OSSP_DSP_GET_OSPACE; - } else { - if (!(dsps->rw & (1 << REC))) - goto err; - op = OSSP_DSP_GET_ISPACE; - } - - PREP_UARG(NULL, &info); - ret = exec_simple_cmd(&dsps->os, op, NULL, &info); - if (ret) - goto err; - IOCTL_RETURN(0, &info); - } - - case SNDCTL_DSP_GETOPTR: - case SNDCTL_DSP_GETIPTR: { - struct count_info info; - - op = cmd == SNDCTL_DSP_GETOPTR ? OSSP_DSP_GET_OPTR - : OSSP_DSP_GET_IPTR; - PREP_UARG(NULL, &info); - ret = exec_simple_cmd(&dsps->os, op, NULL, &info); - if (ret) - goto err; - IOCTL_RETURN(0, &info); - } - - case SNDCTL_DSP_GETODELAY: - PREP_UARG(NULL, &i); - i = 0; - ret = exec_simple_cmd(&dsps->os, OSSP_DSP_GET_ODELAY, NULL, &i); - IOCTL_RETURN(ret, &i); /* always copy out result, 0 on err */ - - case SOUND_PCM_WRITE_FILTER: - case SOUND_PCM_READ_FILTER: - ret = -EIO; - goto err; - - case SNDCTL_DSP_MAPINBUF: - case SNDCTL_DSP_MAPOUTBUF: - ret = -EINVAL; - goto err; - - case SNDCTL_DSP_SETSYNCRO: - case SNDCTL_DSP_SETDUPLEX: - case SNDCTL_DSP_PROFILE: - IOCTL_RETURN(0, NULL); - - default: - warn_os(os, "unknown ioctl 0x%x", cmd); - ret = -EINVAL; - goto err; - } - assert(0); /* control shouldn't reach here */ -err: - fuse_reply_err(req, -ret); -} - -#ifdef OSSP_MMAP -static int dsp_mmap_dir(int prot) -{ - if (!(prot & PROT_WRITE)) - return REC; - return PLAY; -} - -static void dsp_mmap(fuse_req_t req, void *addr, size_t len, int prot, - int flags, off_t offset, struct fuse_file_info *fi, - uint64_t mh) -{ - int dir = dsp_mmap_dir(prot); - struct ossp_dsp_mmap_arg arg = { }; - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - ssize_t ret; - - os = find_os(fi->fh); - if (!os) { - fuse_reply_err(req, EBADF); - return; - } - dsps = os_to_dsps(os); - - if (!os->mmap_off || len > os->mmap_size / 2) { - fuse_reply_err(req, EINVAL); - return; - } - - pthread_mutex_lock(&os->mmap_mutex); - - ret = -EBUSY; - if (dsps->mmapped & (1 << dir)) - goto out_unlock; - - arg.dir = dir; - arg.size = len; - - ret = exec_simple_cmd(os, OSSP_DSP_MMAP, &arg, NULL); - if (ret == 0) - dsps->mmapped |= 1 << dir; - -out_unlock: - pthread_mutex_unlock(&os->mmap_mutex); - - if (ret == 0) - fuse_reply_mmap(req, os->mmap_off + dir * os->mmap_size / 2, 0); - else - fuse_reply_err(req, -ret); -} - -static void dsp_munmap(fuse_req_t req, size_t len, struct fuse_file_info *fi, - off_t offset, uint64_t mh) -{ - struct ossp_stream *os; - struct ossp_dsp_stream *dsps; - int dir, rc; - - os = find_os(fi->fh); - if (!os) - goto out; - dsps = os_to_dsps(os); - - pthread_mutex_lock(&os->mmap_mutex); - - for (dir = 0; dir < 2; dir++) - if (offset == os->mmap_off + dir * os->mmap_size / 2) - break; - if (dir == 2 || len > os->mmap_size / 2) { - warn_os(os, "invalid munmap request " - "offset=%llu len=%zu mmapped=0x%x", - (unsigned long long)offset, len, dsps->mmapped); - goto out_unlock; - } - - rc = exec_simple_cmd(os, OSSP_DSP_MUNMAP, &dir, NULL); - if (rc) - warn_ose(os, rc, "MUNMAP failed for dir=%d", dir); - - dsps->mmapped &= ~(1 << dir); - -out_unlock: - pthread_mutex_unlock(&os->mmap_mutex); -out: - fuse_reply_none(req); -} -#endif - - -/*************************************************************************** - * Notify poller - */ - -static void *notify_poller(void *arg) -{ - struct epoll_event events[1024]; - int i, nfds; - -repeat: - nfds = epoll_wait(notify_epfd, events, ARRAY_SIZE(events), -1); - for (i = 0; i < nfds; i++) { - int do_notify = 0; - struct ossp_stream *os; - struct ossp_notify notify; - ssize_t ret; - - os = find_os_by_notify_rx(events[i].data.fd); - if (!os) { - err("can't find stream for notify_rx fd %d", - events[i].data.fd); - epoll_ctl(notify_epfd, EPOLL_CTL_DEL, events[i].data.fd, - NULL); - /* we don't know what's going on, don't close the fd */ - continue; - } - - while ((ret = read(os->notify_rx, - ¬ify, sizeof(notify))) > 0) { - if (os->dead) - continue; - if (ret != sizeof(notify)) { - warn_os(os, "short read on notify_rx (%zu, " - "expected %zu), killing the stream", - ret, sizeof(notify)); - os->dead = 1; - break; - } - if (notify.magic != OSSP_NOTIFY_MAGIC) { - warn_os(os, "invalid magic on notification, " - "killing the stream"); - os->dead = 1; - break; - } - - if (notify.opcode >= OSSP_NR_NOTIFY_OPCODES) - goto unknown; - - dbg1_os(os, "NOTIFY %s", ossp_notify_str[notify.opcode]); - - switch (notify.opcode) { - case OSSP_NOTIFY_POLL: - do_notify = 1; - break; - case OSSP_NOTIFY_OBITUARY: - os->dead = 1; - break; - case OSSP_NOTIFY_VOLCHG: - pthread_mutex_lock(&mixer_mutex); - os->mixer->modify_counter++; - pthread_mutex_unlock(&mixer_mutex); - break; - default: - unknown: - warn_os(os, "unknown notification %d", - notify.opcode); - } - } - if (ret == 0) - os->dead = 1; - else if (ret < 0 && errno != EAGAIN) { - warn_ose(os, -errno, "read fail on notify fd"); - os->dead = 1; - } - - if (!do_notify && !os->dead) - continue; - - pthread_mutex_lock(&mutex); - - if (os->ph) { - fuse_lowlevel_notify_poll(os->ph); - fuse_pollhandle_destroy(os->ph); - os->ph = NULL; - } - - if (os->dead) { - dbg0_os(os, "removing %d from notify poll list", - os->notify_rx); - epoll_ctl(notify_epfd, EPOLL_CTL_DEL, os->notify_rx, - NULL); - close(os->notify_rx); - os->notify_rx = -1; - pthread_cond_broadcast(¬ify_poller_kill_wait); - } - - pthread_mutex_unlock(&mutex); - } - goto repeat; -} - - -/*************************************************************************** - * Slave corpse reaper - */ - -static void *slave_reaper(void *arg) -{ - struct ossp_stream *os; - int status; - pid_t pid; - - pthread_mutex_lock(&mutex); -repeat: - while (list_empty(&slave_corpse_list)) - pthread_cond_wait(&slave_reaper_wait, &mutex); - - os = list_first_entry(&slave_corpse_list, struct ossp_stream, link); - list_del_init(&os->link); - - pthread_mutex_unlock(&mutex); - - do { - pid = waitpid(os->slave_pid, &status, 0); - } while (pid < 0 && errno == EINTR); - - if (pid < 0) { - if (errno == ECHILD) - warn_ose(os, -errno, "slave %d already gone?", - os->slave_pid); - else - fatal_e(-errno, "waitpid(%d) failed", os->slave_pid); - } - - pthread_mutex_lock(&mutex); - - dbg1_os(os, "slave %d reaped", os->slave_pid); - __clear_bit(os->id, os_id_bitmap); - free(os); - - goto repeat; -} - - -/*************************************************************************** - * Stuff to bind and start everything - */ - -static void ossp_daemonize(void) -{ - int fd, pfd[2]; - pid_t pid; - ssize_t ret; - int err; - - fd = open("/dev/null", O_RDWR); - if (fd >= 0) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); - } - - if (pipe(pfd)) - fatal_e(-errno, "failed to create pipe for init wait"); - - if (fcntl(pfd[0], F_SETFD, FD_CLOEXEC) < 0 || - fcntl(pfd[1], F_SETFD, FD_CLOEXEC) < 0) - fatal_e(-errno, "failed to set CLOEXEC on init wait pipe"); - - pid = fork(); - if (pid < 0) - fatal_e(-errno, "failed to fork for daemon"); - - if (pid == 0) { - close(pfd[0]); - init_wait_fd = pfd[1]; - - /* be evil, my child */ - chdir("/"); - setsid(); - return; - } - - /* wait for init completion and pass over success indication */ - close(pfd[1]); - - do { - ret = read(pfd[0], &err, sizeof(err)); - } while (ret < 0 && errno == EINTR); - - if (ret == sizeof(err) && err == 0) - exit(0); - - fatal("daemon init failed ret=%zd err=%d", ret, err); - exit(1); -} - -static void ossp_init_done(void *userdata) -{ - /* init complete, notify parent if it's waiting */ - if (init_wait_fd >= 0) { - ssize_t ret; - int err = 0; - - ret = write(init_wait_fd, &err, sizeof(err)); - if (ret != sizeof(err)) - fatal_e(-errno, "failed to notify init completion, " - "ret=%zd", ret); - close(init_wait_fd); - init_wait_fd = -1; - } -} - -static const struct cuse_lowlevel_ops mixer_ops = { - .open = mixer_open, - .release = mixer_release, - .ioctl = mixer_ioctl, -}; - -static const struct cuse_lowlevel_ops dsp_ops = { - .init_done = ossp_init_done, - .open = dsp_open, - .release = dsp_release, - .read = dsp_read, - .write = dsp_write, - .poll = dsp_poll, - .ioctl = dsp_ioctl, -#ifdef OSSP_MMAP - .mmap = dsp_mmap, - .munmap = dsp_munmap, -#endif -}; - -static const struct cuse_lowlevel_ops adsp_ops = { - .open = adsp_open, - .release = dsp_release, - .read = dsp_read, - .write = dsp_write, - .poll = dsp_poll, - .ioctl = dsp_ioctl, -#ifdef OSSP_MMAP - .mmap = dsp_mmap, - .munmap = dsp_munmap, -#endif -}; - -static const char *usage = -"usage: osspd [options]\n" -"\n" -"options:\n" -" --help print this help message\n" -" --dsp=NAME DSP device name (default dsp)\n" -" --dsp-maj=MAJ DSP device major number (default 14)\n" -" --dsp-min=MIN DSP device minor number (default 3)\n" -" --adsp=NAME Aux DSP device name (default adsp, blank to disable)\n" -" --adsp-maj=MAJ Aux DSP device major number (default 14)\n" -" --adsp-min=MIN Aux DSP device minor number (default 12)\n" -" --mixer=NAME mixer device name (default mixer, blank to disable)\n" -" --mixer-maj=MAJ mixer device major number (default 14)\n" -" --mixer-min=MIN mixer device minor number (default 0)\n" -" --max=MAX maximum number of open streams (default 256)\n" -" --umax=MAX maximum number of open streams per UID (default --max)\n" -" --exit-on-idle exit if idle\n" -" --dsp-slave=PATH DSP slave (default ossp-padsp in the same dir)\n" -" --log=LEVEL log level (0..6)\n" -" --timestamp timestamp log messages\n" -" -v increase verbosity, can be specified multiple times\n" -" -f Run in foreground (don't daemonize)\n" -"\n"; - -struct ossp_param { - char *dsp_name; - unsigned dsp_major; - unsigned dsp_minor; - char *adsp_name; - unsigned adsp_major; - unsigned adsp_minor; - char *mixer_name; - unsigned mixer_major; - unsigned mixer_minor; - unsigned max_streams; - unsigned umax_streams; - char *dsp_slave_path; - unsigned log_level; - int exit_on_idle; - int timestamp; - int fg; - int help; -}; - -#define OSSP_OPT(t, p) { t, offsetof(struct ossp_param, p), 1 } - -static const struct fuse_opt ossp_opts[] = { - OSSP_OPT("--dsp=%s", dsp_name), - OSSP_OPT("--dsp-maj=%u", dsp_major), - OSSP_OPT("--dsp-min=%u", dsp_minor), - OSSP_OPT("--adsp=%s", adsp_name), - OSSP_OPT("--adsp-maj=%u", adsp_major), - OSSP_OPT("--adsp-min=%u", adsp_minor), - OSSP_OPT("--mixer=%s", mixer_name), - OSSP_OPT("--mixer-maj=%u", mixer_major), - OSSP_OPT("--mixer-min=%u", mixer_minor), - OSSP_OPT("--max=%u", max_streams), - OSSP_OPT("--umax=%u", umax_streams), - OSSP_OPT("--exit-on-idle", exit_on_idle), - OSSP_OPT("--dsp-slave=%s", dsp_slave_path), - OSSP_OPT("--timestamp", timestamp), - OSSP_OPT("--log=%u", log_level), - OSSP_OPT("-f", fg), - FUSE_OPT_KEY("-h", 0), - FUSE_OPT_KEY("--help", 0), - FUSE_OPT_KEY("-v", 1), - FUSE_OPT_END -}; - -static struct fuse_session *setup_ossp_cuse(const struct cuse_lowlevel_ops *ops, - const char *name, int major, - int minor, int argc, char **argv) -{ - char name_buf[128]; - const char *bufp = name_buf; - struct cuse_info ci = { .dev_major = major, .dev_minor = minor, - .dev_info_argc = 1, .dev_info_argv = &bufp, - .flags = CUSE_UNRESTRICTED_IOCTL }; - struct fuse_session *se; - int fd; - - snprintf(name_buf, sizeof(name_buf), "DEVNAME=%s", name); - - se = cuse_lowlevel_setup(argc, argv, &ci, ops, NULL, NULL); - if (!se) { - err("failed to setup %s CUSE", name); - return NULL; - } - - fd = fuse_chan_fd(fuse_session_next_chan(se, NULL)); - if ( -#ifdef OSSP_MMAP - fd != fuse_mmap_fd(se) && -#endif - fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { - err_e(-errno, "failed to set CLOEXEC on %s CUSE fd", name); - cuse_lowlevel_teardown(se); - return NULL; - } - - return se; -} - -static void *cuse_worker(void *arg) -{ - struct fuse_session *se = arg; - int rc; - - rc = fuse_session_loop_mt(se); - cuse_lowlevel_teardown(se); - - return (void *)(unsigned long)rc; -} - -static int process_arg(void *data, const char *arg, int key, - struct fuse_args *outargs) -{ - struct ossp_param *param = data; - - switch (key) { - case 0: - fprintf(stderr, usage); - param->help = 1; - return 0; - case 1: - param->log_level++; - return 0; - } - return 1; -} - -int main(int argc, char **argv) -{ - static struct ossp_param param = { - .dsp_name = DFL_DSP_NAME, - .dsp_major = DFL_DSP_MAJOR, .dsp_minor = DFL_DSP_MINOR, - .adsp_name = DFL_ADSP_NAME, - .adsp_major = DFL_ADSP_MAJOR, .adsp_minor = DFL_ADSP_MINOR, - .mixer_name = DFL_MIXER_NAME, - .mixer_major = DFL_MIXER_MAJOR, .mixer_minor = DFL_MIXER_MINOR, - .max_streams = DFL_MAX_STREAMS, - }; - struct fuse_args args = FUSE_ARGS_INIT(argc, argv); - char path_buf[PATH_MAX], *dir; - char adsp_buf[64] = "", mixer_buf[64] = ""; - struct sigaction sa; - struct stat stat_buf; - ssize_t ret; - unsigned u; - - snprintf(ossp_log_name, sizeof(ossp_log_name), "osspd"); - param.log_level = ossp_log_level; - - if (fuse_opt_parse(&args, ¶m, ossp_opts, process_arg)) - fatal("failed to parse arguments"); - - if (param.help) - return 0; - - max_streams = param.max_streams; - hashtbl_size = max_streams / 2 + 13; - - umax_streams = max_streams; - if (param.umax_streams) - umax_streams = param.umax_streams; - if (param.log_level > OSSP_LOG_MAX) - param.log_level = OSSP_LOG_MAX; - if (!param.fg) - param.log_level = -param.log_level; - ossp_log_level = param.log_level; - ossp_log_timestamp = param.timestamp; - - if (!param.fg) - ossp_daemonize(); - - /* daemonization already handled, prevent forking inside FUSE */ - fuse_opt_add_arg(&args, "-f"); - - info("OSS Proxy v%s (C) 2008-2010 by Tejun Heo ", - OSSP_VERSION); - - /* ignore stupid SIGPIPEs */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL)) - fatal_e(-errno, "failed to ignore SIGPIPE"); - -//#ifdef GIOVANNI - /* determine slave path and check for availability */ - ret = readlink("/proc/self/exe", path_buf, PATH_MAX - 1); - if (ret < 0) - fatal_e(-errno, "failed to determine executable path"); - path_buf[ret] = '\0'; - dir = dirname(path_buf); - - if (param.dsp_slave_path) { - strncpy(dsp_slave_path, param.dsp_slave_path, PATH_MAX - 1); - dsp_slave_path[PATH_MAX - 1] = '\0'; - } else { - ret = snprintf(dsp_slave_path, PATH_MAX, "%s/%s", - dir, "ossp-padsp"); - if (ret >= PATH_MAX) - fatal("dsp slave pathname too long"); - } - - if (stat(dsp_slave_path, &stat_buf)) - fatal_e(-errno, "failed to stat %s", dsp_slave_path); - if (!S_ISREG(stat_buf.st_mode) || !(stat_buf.st_mode & 0444)) - fatal("%s is not executable", dsp_slave_path); - -//#endif// GIOVANNI - /* allocate tables */ - os_id_bitmap = calloc(BITS_TO_LONGS(max_streams), sizeof(long)); - mixer_tbl = calloc(hashtbl_size, sizeof(mixer_tbl[0])); - os_tbl = calloc(hashtbl_size, sizeof(os_tbl[0])); - os_pgrp_tbl = calloc(hashtbl_size, sizeof(os_pgrp_tbl[0])); - os_notify_tbl = calloc(hashtbl_size, sizeof(os_notify_tbl[0])); - if (!os_id_bitmap || !mixer_tbl || !os_tbl || !os_pgrp_tbl || - !os_notify_tbl) - fatal("failed to allocate stream hash tables"); - for (u = 0; u < hashtbl_size; u++) { - INIT_LIST_HEAD(&mixer_tbl[u]); - INIT_LIST_HEAD(&os_tbl[u]); - INIT_LIST_HEAD(&os_pgrp_tbl[u]); - INIT_LIST_HEAD(&os_notify_tbl[u]); - } - __set_bit(0, os_id_bitmap); /* don't use id 0 */ - - /* create mixer delayed reference worker */ - ret = -pthread_create(&mixer_delayed_put_thread, NULL, - mixer_delayed_put_worker, NULL); - if (ret) - fatal_e(ret, "failed to create mixer delayed put worker"); - - /* if exit_on_idle, touch mixer for pgrp0 */ - exit_on_idle = param.exit_on_idle; - if (exit_on_idle) { - struct ossp_mixer *mixer; - - mixer = get_mixer(0); - if (!mixer) - fatal("failed to touch idle mixer"); - put_mixer(mixer); - } - - /* create notify epoll and kick off watcher thread */ - notify_epfd = epoll_create(max_streams); - if (notify_epfd < 0) - fatal_e(-errno, "failed to create notify epoll"); - if (fcntl(notify_epfd, F_SETFD, FD_CLOEXEC) < 0) - fatal_e(-errno, "failed to set CLOEXEC on notify epfd"); - - ret = -pthread_create(¬ify_poller_thread, NULL, notify_poller, NULL); - if (ret) - fatal_e(ret, "failed to create notify poller thread"); - - /* create reaper for slave corpses */ - ret = -pthread_create(&slave_reaper_thread, NULL, slave_reaper, NULL); - if (ret) - fatal_e(ret, "failed to create slave reaper thread"); - -#ifdef GIOVANNI - /* we're set, let's setup fuse structures */ - if (strlen(param.mixer_name)) - mixer_se = setup_ossp_cuse(&mixer_ops, param.mixer_name, - param.mixer_major, param.mixer_minor, - args.argc, args.argv); - if (strlen(param.adsp_name)) - adsp_se = setup_ossp_cuse(&dsp_ops, param.adsp_name, - param.adsp_major, param.adsp_minor, - args.argc, args.argv); - -#endif// GIOVANNI - dsp_se = setup_ossp_cuse(&dsp_ops, param.dsp_name, - param.dsp_major, param.dsp_minor, - args.argc, args.argv); - if (!dsp_se) - fatal("can't create dsp, giving up"); - -#ifdef GIOVANNI - if (mixer_se) - snprintf(mixer_buf, sizeof(mixer_buf), ", %s (%d:%d)", - param.mixer_name, param.mixer_major, param.mixer_minor); - if (adsp_se) - snprintf(adsp_buf, sizeof(adsp_buf), ", %s (%d:%d)", - param.adsp_name, param.adsp_major, param.adsp_minor); - -#endif// GIOVANNI - info("Creating %s (%d:%d)%s%s", param.dsp_name, param.dsp_major, - param.dsp_minor, adsp_buf, mixer_buf); - -#ifdef GIOVANNI - /* start threads for mixer and adsp */ - if (mixer_se) { - ret = -pthread_create(&cuse_mixer_thread, NULL, - cuse_worker, mixer_se); - if (ret) - err_e(ret, "failed to create mixer worker"); - } - if (adsp_se) { - ret = -pthread_create(&cuse_adsp_thread, NULL, - cuse_worker, adsp_se); - if (ret) - err_e(ret, "failed to create adsp worker"); - } -#endif// GIOVANNI - - /* run CUSE for /dev/dsp in the main thread */ - ret = (ssize_t)cuse_worker(dsp_se); - if (ret < 0) - fatal("dsp worker failed"); - return 0; -} diff --git a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c index 391a23caaf..4f5f129344 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen_protocol.c +++ b/src/mod/endpoints/mod_skypopen/skypopen_protocol.c @@ -1739,19 +1739,23 @@ void *skypopen_do_skypeapi_thread_func(void *obj) if (session) { switch_channel_t *channel = switch_core_session_get_channel(session); + if(channel){ - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); + switch_mutex_lock(tech_pvt->flag_mutex); + switch_clear_flag(tech_pvt, TFLAG_IO); + switch_clear_flag(tech_pvt, TFLAG_VOICE); + if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { + switch_clear_flag(tech_pvt, TFLAG_PROGRESS); + } + switch_mutex_unlock(tech_pvt->flag_mutex); + + + switch_core_session_rwunlock(session); + WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename); + switch_channel_hangup(channel, SWITCH_CAUSE_CRASH); + } else { + WARNINGA("NO CHANNEL ?\n", SKYPOPEN_P_LOG); } - switch_mutex_unlock(tech_pvt->flag_mutex); - - - switch_core_session_rwunlock(session); - WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename); - switch_channel_hangup(channel, SWITCH_CAUSE_CRASH); } WARNINGA("Removing skype interface %s\n", SKYPOPEN_P_LOG, interfacename); @@ -1772,19 +1776,23 @@ void *skypopen_do_skypeapi_thread_func(void *obj) switch_channel_t *channel = switch_core_session_get_channel(session); - switch_mutex_lock(tech_pvt->flag_mutex); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { - switch_clear_flag(tech_pvt, TFLAG_PROGRESS); + if(channel){ + switch_mutex_lock(tech_pvt->flag_mutex); + switch_clear_flag(tech_pvt, TFLAG_IO); + switch_clear_flag(tech_pvt, TFLAG_VOICE); + if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) { + switch_clear_flag(tech_pvt, TFLAG_PROGRESS); + } + switch_mutex_unlock(tech_pvt->flag_mutex); + + + switch_core_session_rwunlock(session); + WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename); + switch_channel_hangup(channel, SWITCH_CAUSE_CRASH); + + } else { + WARNINGA("NO CHANNEL ?\n", SKYPOPEN_P_LOG); } - switch_mutex_unlock(tech_pvt->flag_mutex); - - - switch_core_session_rwunlock(session); - WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename); - switch_channel_hangup(channel, SWITCH_CAUSE_CRASH); - //skypopen_sleep(500000); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index bcc8f75692..c9ea6790b7 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -766,7 +766,6 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw { private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); switch_channel_t *channel = switch_core_session_get_channel(session); - int payload = 0; switch_assert(tech_pvt != NULL); @@ -810,8 +809,6 @@ static switch_status_t sofia_read_video_frame(switch_core_session_t *session, sw return status; } - payload = tech_pvt->video_read_frame.payload; - if (tech_pvt->video_read_frame.datalen > 0) { break; } @@ -867,7 +864,6 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f { private_object_t *tech_pvt = switch_core_session_get_private(session); switch_channel_t *channel = switch_core_session_get_channel(session); - int payload = 0; uint32_t sanity = 1000; switch_rtcp_frame_t rtcp_frame; @@ -979,8 +975,6 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f return SWITCH_STATUS_SUCCESS; } - payload = tech_pvt->read_frame.payload; - if (switch_rtp_has_dtmf(tech_pvt->rtp_session)) { switch_dtmf_t dtmf = { 0 }; switch_rtp_dequeue_dtmf(tech_pvt->rtp_session, &dtmf); @@ -1247,6 +1241,7 @@ static void start_udptl(private_object_t *tech_pvt, switch_t38_options_t *t38_op switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session); const char *err, *val; + sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE); switch_rtp_udptl_mode(tech_pvt->rtp_session); if (!t38_options || !t38_options->remote_ip) { @@ -1533,8 +1528,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } if (sofia_test_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE)) { - switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); - switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_NOBLOCK); + if (!switch_rtp_test_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_UDPTL) && + !switch_rtp_test_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) { + switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); + switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_NOBLOCK); + } sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE); } @@ -1859,13 +1857,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi const char *name = msg->string_array_arg[0], *number = msg->string_array_arg[1]; char *arg = NULL; char *argv[2] = { 0 }; - int argc; + //int argc; if (zstr(name) && !zstr(msg->string_arg)) { arg = strdup(msg->string_arg); switch_assert(arg); - argc = switch_separate_string(arg, '|', argv, (sizeof(argv) / sizeof(argv[0]))); + switch_separate_string(arg, '|', argv, (sizeof(argv) / sizeof(argv[0]))); name = argv[0]; number = argv[1]; @@ -2159,6 +2157,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (t38_options) { sofia_glue_set_image_sdp(tech_pvt, t38_options, 0); if (switch_rtp_ready(tech_pvt->rtp_session)) { + sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE); switch_rtp_udptl_mode(tech_pvt->rtp_session); } } @@ -4910,7 +4909,7 @@ static switch_status_t list_profile_gateway(const char *line, const char *cursor switch_console_callback_match_t *my_matches = NULL; switch_status_t status = SWITCH_STATUS_FALSE; char *dup = NULL; - int argc; + //int argc; char *argv[4] = { 0 }; if (zstr(line)) { @@ -4918,7 +4917,7 @@ static switch_status_t list_profile_gateway(const char *line, const char *cursor } dup = strdup(line); - argc = switch_split(dup, ' ', argv); + switch_split(dup, ' ', argv); if (zstr(argv[2]) || !strcmp(argv[2], " ")) { goto end; @@ -4962,7 +4961,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_find_local_ip(mod_sofia_globals.guess_ip, sizeof(mod_sofia_globals.guess_ip), &mod_sofia_globals.guess_mask, AF_INET); in.s_addr = mod_sofia_globals.guess_mask; switch_set_string(mod_sofia_globals.guess_mask_str, inet_ntoa(in)); - gethostname(mod_sofia_globals.hostname, sizeof(mod_sofia_globals.hostname)); + + strcpy(mod_sofia_globals.hostname, switch_core_get_switchname()); switch_core_hash_init(&mod_sofia_globals.profile_hash, mod_sofia_globals.pool); diff --git a/src/mod/endpoints/mod_sofia/sip-dig.c b/src/mod/endpoints/mod_sofia/sip-dig.c index d0c9aa6aff..556abae96d 100644 --- a/src/mod/endpoints/mod_sofia/sip-dig.c +++ b/src/mod/endpoints/mod_sofia/sip-dig.c @@ -210,17 +210,14 @@ void _usage(int exitcode, switch_stream_handle_t *stream) switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) { - int exitcode = 0; int o_sctp = 1, o_tls_sctp = 1, o_verbatim = 1; int family = 0, multiple = 0; - char const *dnsserver = NULL; char const *string; url_t *uri = NULL; char const *host; char const *port; char *transport = NULL, tport[32]; - int argc; char *argv_[25] = { 0 }; char *mycmd = NULL; char **argv; @@ -239,7 +236,7 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor mycmd = strdup(cmd); - argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv_) / sizeof(argv_[0])) - 1); + switch_separate_string(mycmd, ' ', argv, (sizeof(argv_) / sizeof(argv_[0])) - 1); argv = argv_; @@ -321,10 +318,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor if (!family) dig->ip4 = 1, dig->ip6 = 2; - if (argv[1] && argv[1][0] == '@') - dnsserver = argv++[1] + 1; - - if (!argv[1]) {usage(2);} @@ -360,7 +353,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor if (!uri || (uri->url_type != url_sip && uri->url_type != url_sips)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid uri\n", string); - exitcode = 1; continue; } @@ -387,7 +379,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor if (!host_is_domain(host)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid host\n", string); - exitcode = 1; continue; } @@ -402,7 +393,6 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor continue /* resolved a/aaaa */; stream->write_function(stream, "-ERR: %s: not found\n", string); - exitcode = 1; } if (xml) { diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2bf27d5ba8..be24a00d98 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -519,6 +519,14 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, cause = sofia_glue_sip_cause_to_freeswitch(status); } + if (sip->sip_content_type && sip->sip_content_type->c_type) { + switch_channel_set_variable(channel, "sip_bye_content_type", sip->sip_content_type->c_type); + } + + if (sip->sip_payload && sip->sip_payload->pl_data) { + switch_channel_set_variable(channel, "sip_bye_payload", sip->sip_payload->pl_data); + } + switch_snprintf(st, sizeof(st), "%d", status); switch_channel_set_variable(channel, "sip_term_status", st); switch_snprintf(st, sizeof(st), "sip:%d", status); @@ -1457,7 +1465,7 @@ switch_thread_t *launch_sofia_worker_thread(sofia_profile_t *profile) void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj) { sofia_profile_t *profile = (sofia_profile_t *) obj; - switch_memory_pool_t *pool; + //switch_memory_pool_t *pool; sip_alias_node_t *node; switch_event_t *s_event; int use_100rel = !sofia_test_pflag(profile, PFLAG_DISABLE_100REL); @@ -1717,7 +1725,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void su_home_unref(profile->home); su_root_destroy(profile->s_root); - pool = profile->pool; + //pool = profile->pool; sofia_glue_del_profile(profile); switch_core_hash_destroy(&profile->chat_hash); @@ -4506,6 +4514,7 @@ 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)) { + sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE); switch_rtp_udptl_mode(tech_pvt->rtp_session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n"); } @@ -4790,7 +4799,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (status == 183 && !r_sdp) { if ((channel && switch_true(switch_channel_get_variable(channel, "sip_ignore_183nosdp"))) || sofia_test_pflag(profile, PFLAG_IGNORE_183NOSDP)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", switch_channel_get_name(channel)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Ignoring 183 w/o sdp\n", channel ? switch_channel_get_name(channel) : "None"); goto done; } status = 180; @@ -5550,13 +5559,6 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces) const void *var; void *val; sofia_profile_t *profile; - switch_xml_t xml_root; - const char *err; - - if ((xml_root = switch_xml_open_root(1, &err))) { - switch_xml_free(xml_root); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Reload XML [%s]\n", err); - } switch_mutex_lock(mod_sofia_globals.hash_mutex); if (mod_sofia_globals.profile_hash) { @@ -5581,7 +5583,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t { /* Incoming refer */ sip_from_t const *from; - sip_to_t const *to; + //sip_to_t const *to; sip_refer_to_t const *refer_to; private_object_t *tech_pvt = switch_core_session_get_private(session); char *etmp = NULL, *exten = NULL; @@ -5604,7 +5606,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t } from = sip->sip_from; - to = sip->sip_to; + //to = sip->sip_to; home = su_home_new(sizeof(*home)); switch_assert(home != NULL); @@ -6374,7 +6376,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ const char *displayname = NULL; const char *destination_number = NULL; const char *from_user = NULL, *from_host = NULL; - const char *referred_by_user = NULL, *referred_by_host = NULL; + const char *referred_by_user = NULL;//, *referred_by_host = NULL; const char *context = NULL; const char *dialplan = NULL; char network_ip[80]; @@ -6905,7 +6907,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (sip->sip_referred_by) { referred_by_user = sip->sip_referred_by->b_url->url_user; - referred_by_host = sip->sip_referred_by->b_url->url_host; + //referred_by_host = sip->sip_referred_by->b_url->url_host; channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by); check_decode(referred_by_user, session); @@ -7047,8 +7049,9 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if (!gateway && gw_param_name) { - gateway = sofia_reg_find_gateway(gw_param_name); - extension = gateway->real_extension; + if ((gateway = sofia_reg_find_gateway(gw_param_name))) { + extension = gateway->real_extension; + } } if (gateway) { @@ -7149,7 +7152,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ const char *data = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_DATA_VARIABLE); if (app && data && !strcasecmp(app, "conference")) { - destination_number = switch_core_session_sprintf(b_session, "answer,conference:%s", data); + destination_number = switch_core_session_sprintf(session, "answer,conference:%s", data); dialplan = "inline"; } else { if (switch_core_session_check_interface(b_session, sofia_endpoint_interface)) { @@ -7157,8 +7160,6 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if ((uuid = switch_channel_get_variable(b_channel, SWITCH_SIGNAL_BOND_VARIABLE))) { - switch_channel_set_variable(b_channel, "presence_call_info", NULL); - switch_channel_set_variable(b_channel, "presence_call_info_full", NULL); one_leg = 0; } else { uuid = switch_core_session_get_uuid(b_session); @@ -7187,7 +7188,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (!one_leg && (!b_tech_pvt || !sofia_test_flag(b_tech_pvt, TFLAG_SIP_HOLD)) && (!c_tech_pvt || !sofia_test_flag(c_tech_pvt, TFLAG_SIP_HOLD))) { - char *ext = switch_core_session_sprintf(b_session, "answer,conference:%s@sla+flags{mintwo}", uuid); + char *ext = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo}", uuid); switch_channel_set_flag(c_channel, CF_REDIRECT); switch_ivr_session_transfer(b_session, ext, "inline", NULL); @@ -7199,16 +7200,17 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if (do_conf) { - destination_number = switch_core_session_sprintf(b_session, "answer,conference:%s@sla+flags{mintwo}", uuid); + destination_number = switch_core_session_sprintf(session, "answer,conference:%s@sla+flags{mintwo}", uuid); } else { if (one_leg && c_app) { if (c_data) { - destination_number = switch_core_session_sprintf(b_session, "answer,%s:%s", c_app, c_data); + destination_number = switch_core_session_sprintf(session, "answer,%s:%s", c_app, c_data); } else { - destination_number = switch_core_session_sprintf(b_session, "answer,%s", c_app); + destination_number = switch_core_session_sprintf(session, "answer,%s", c_app); } } else { - destination_number = switch_core_session_sprintf(b_session, "answer,intercept:%s", uuid); + switch_channel_mark_hold(b_channel, SWITCH_FALSE); + destination_number = switch_core_session_sprintf(session, "answer,intercept:%s", uuid); } } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 66bf8ea644..2724e5e562 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -187,7 +187,7 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, switch_port_t port, - int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int verbose_sdp) + int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int verbose_sdp, int secure) { int i = 0; int rate; @@ -195,7 +195,7 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, int ptime = 0, noptime = 0; switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP", - port, (!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE)) ? "S" : ""); + port, secure ? "S" : ""); @@ -312,6 +312,11 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", tech_pvt->te, tech_pvt->te); } + if (secure) { + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=crypto:%s\n", tech_pvt->local_crypto_key); + //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); + } + if (!cng_type) { //switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d CN/8000\n", cng_type); //} else { @@ -333,7 +338,6 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, if (sr) { switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\n", sr); } - } void sofia_glue_check_dtmf_type(private_object_t *tech_pvt) @@ -529,7 +533,11 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 if (sr) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=%s\n", sr); } - + + if (!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE)) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=crypto:%s\n", tech_pvt->local_crypto_key); + //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); + } } else if (tech_pvt->num_codecs) { int i; @@ -545,7 +553,15 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 } if (!switch_true(switch_channel_get_variable(tech_pvt->channel, "sdp_m_per_ptime"))) { - generate_m(tech_pvt, buf, sizeof(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp); + char *bp = buf; + + if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) { + generate_m(tech_pvt, buf, sizeof(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1); + bp = (buf + strlen(buf)); + } + + generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, 0, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0); + } else { for (i = 0; i < tech_pvt->num_codecs; i++) { @@ -558,8 +574,15 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 this_ptime = imp->microseconds_per_packet / 1000; if (cur_ptime != this_ptime) { - cur_ptime = this_ptime; - generate_m(tech_pvt, buf, sizeof(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp); + char *bp = buf; + cur_ptime = this_ptime; + + if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) { + generate_m(tech_pvt, buf, sizeof(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1); + bp = (buf + strlen(buf)); + } + + generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 0); } } @@ -567,11 +590,6 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 } - if (!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE)) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=crypto:%s\n", tech_pvt->local_crypto_key); - //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); - } - if (sofia_test_flag(tech_pvt, TFLAG_VIDEO)) { if (!tech_pvt->local_sdp_video_port) { sofia_glue_tech_choose_video_port(tech_pvt, 0); @@ -1261,7 +1279,9 @@ int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip) { switch_assert(network_ip); - return (profile->extsipip && !switch_check_network_list_ip(network_ip, profile->local_network)); + return (profile->extsipip && + !switch_check_network_list_ip(network_ip, "loopback.auto") && + !switch_check_network_list_ip(network_ip, profile->local_network)); } int sofia_glue_transport_has_tls(const sofia_transport_t tp) @@ -2110,8 +2130,9 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (!from_display && !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) { from_str = switch_core_session_sprintf(session, "<%s>", use_from_str); } else { - from_str = switch_core_session_sprintf(session, "\"%s\" <%s>", from_display ? from_display : - tech_pvt->caller_profile->caller_id_name, use_from_str); + char *name = switch_core_session_strdup(session, from_display ? from_display : tech_pvt->caller_profile->caller_id_name); + check_decode(name, session); + from_str = switch_core_session_sprintf(session, "\"%s\" <%s>", name, use_from_str); } if (!(call_id = switch_channel_get_variable(channel, "sip_invite_call_id"))) { @@ -2150,6 +2171,15 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (!strncasecmp(url_str, "sips:", 5)) { s = url_str + 5; } + + /* tel: patch from jaybinks, added by MC + It compiles but I don't have a way to test it + */ + if (!strncasecmp(url_str, "tel:", 4)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), + SWITCH_LOG_ERROR, "URL Error! tel: uri's not supported at this time\n"); + return SWITCH_STATUS_FALSE; + } if (!s) { s = url_str; } @@ -2533,6 +2563,7 @@ static void set_stats(switch_rtp_t *rtp_session, private_object_t *tech_pvt, con add_stat(stats->inbound.dtmf_packet_count, "in_dtmf_packet_count"); add_stat(stats->inbound.cng_packet_count, "in_cng_packet_count"); add_stat(stats->inbound.flush_packet_count, "in_flush_packet_count"); + add_stat(stats->inbound.largest_jb_size, "in_largest_jb_size"); add_stat(stats->outbound.raw_bytes, "out_raw_bytes"); add_stat(stats->outbound.media_bytes, "out_media_bytes"); @@ -2643,9 +2674,7 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); return SWITCH_STATUS_FALSE; } else { - int ms; tech_pvt->video_read_frame.rate = tech_pvt->video_rm_rate; - ms = tech_pvt->video_write_codec.implementation->microseconds_per_packet / 1000; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->video_rm_encoding, tech_pvt->video_rm_rate, tech_pvt->video_codec_ms); tech_pvt->video_read_frame.codec = &tech_pvt->video_read_codec; @@ -2670,7 +2699,6 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) { - int ms; switch_status_t status = SWITCH_STATUS_SUCCESS; int resetting = 0; @@ -2763,7 +2791,6 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) } tech_pvt->read_frame.rate = tech_pvt->rm_rate; - ms = tech_pvt->write_codec.implementation->microseconds_per_packet / 1000; if (!switch_core_codec_ready(&tech_pvt->read_codec)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -2846,7 +2873,6 @@ switch_status_t sofia_glue_build_crypto(private_object_t *tech_pvt, int index, s switch_status_t sofia_glue_add_crypto(private_object_t *tech_pvt, const char *key_str, switch_rtp_crypto_direction_t direction) { unsigned char key[SWITCH_RTP_MAX_CRYPTO_LEN]; - int index; switch_rtp_crypto_key_type_t type; char *p; @@ -2855,8 +2881,6 @@ switch_status_t sofia_glue_add_crypto(private_object_t *tech_pvt, const char *ke goto bad; } - index = atoi(key_str); - p = strchr(key_str, ' '); if (p && *p && *(p + 1)) { @@ -2903,7 +2927,6 @@ switch_status_t sofia_glue_add_crypto(private_object_t *tech_pvt, const char *ke switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_flag_t myflags) { - int bw, ms; const char *err = NULL; const char *val = NULL; switch_rtp_flag_t flags; @@ -2944,9 +2967,6 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f goto end; } - bw = tech_pvt->read_impl.bits_per_second; - ms = tech_pvt->read_impl.microseconds_per_packet; - if (myflags) { flags = myflags; } else if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && @@ -2998,6 +3018,21 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f 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)); + if (switch_rtp_ready(tech_pvt->rtp_session)) { + if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "%s Set audio receive payload in Re-INVITE for non-matching dynamic PT to %u\n", + switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt); + + switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "%s Setting audio receive payload in Re-INVITE to %u\n", + switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt); + switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->agreed_pt); + } + + } goto video; } else { 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", @@ -3425,9 +3460,9 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && !((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) { - flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE); + flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE); } else { - flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE); + flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE); } if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) { @@ -4076,7 +4111,7 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) 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; + int ptime = 0, dptime = 0; if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { return; @@ -4097,8 +4132,6 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) if (!strcasecmp(attr->a_name, "ptime")) { dptime = atoi(attr->a_value); - } else if (!strcasecmp(attr->a_name, "maxptime")) { - dmaxptime = atoi(attr->a_value); } } @@ -4106,7 +4139,7 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) for (m = sdp->sdp_media; m; m = m->m_next) { ptime = dptime; - maxptime = dmaxptime; + //maxptime = dmaxptime; if (m->m_proto == sdp_proto_rtp) { sdp_rtpmap_t *map; @@ -4114,7 +4147,7 @@ void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) 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); + //maxptime = atoi(attr->a_value); } } @@ -4784,7 +4817,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } else if (m->m_type == sdp_media_video && m->m_port) { sdp_rtpmap_t *map; const char *rm_encoding; - int framerate = 0; const switch_codec_implementation_t *mimp = NULL; int vmatch = 0, i; switch_channel_set_variable(tech_pvt->channel, "video_possible", "true"); @@ -4804,7 +4836,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s for (attr = m->m_attributes; attr; attr = attr->a_next) { if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) { - framerate = atoi(attr->a_value); + //framerate = atoi(attr->a_value); } if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) { switch_channel_set_variable(tech_pvt->channel, "sip_remote_video_rtcp_port", attr->a_value); @@ -6234,7 +6266,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use contact = sofia_glue_get_url_from_contact((char *) o_contact, 1); if (!zstr(network_ip) && sofia_glue_check_nat(profile, network_ip)) { char *ptr = NULL; - const char *transport_str = NULL; + //const char *transport_str = NULL; id = switch_mprintf("sip:%s@%s", user, profile->extsipip); @@ -6242,7 +6274,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) { sofia_transport_t transport = sofia_glue_str2transport(ptr); - transport_str = sofia_glue_transport2str(transport); + //transport_str = sofia_glue_transport2str(transport); switch (transport) { case SOFIA_TRANSPORT_TCP: contact_str = profile->tcp_public_contact; @@ -6450,7 +6482,7 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str) char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np) { char *contact_str = NULL; - const char *contact_host, *contact_user; + const char *contact_host;//, *contact_user; sip_contact_t const *contact; char *port; const char *display = "\"user\""; @@ -6478,7 +6510,7 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sof port = (char *) contact->m_url->url_port; contact_host = sip->sip_contact->m_url->url_host; - contact_user = sip->sip_contact->m_url->url_user; + //contact_user = sip->sip_contact->m_url->url_user; display = contact->m_display; diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index cbc45024e1..3259808d4d 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -208,10 +208,10 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) { char *ptr = NULL; - const char *transport_str = NULL; + //const char *transport_str = NULL; if ((ptr = sofia_glue_find_parameter(dst->contact, "transport="))) { sofia_transport_t transport = sofia_glue_str2transport(ptr); - transport_str = sofia_glue_transport2str(transport); + //transport_str = sofia_glue_transport2str(transport); switch (transport) { case SOFIA_TRANSPORT_TCP: contact_str = profile->tcp_public_contact; @@ -1417,6 +1417,11 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * } if (!(nh = nua_handle_by_call_id(profile->nua, call_id))) { + + if (mod_sofia_globals.debug_presence > 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find handle for call id %s\n", call_id); + } + goto end; } @@ -1468,12 +1473,18 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * const char *astate = switch_str_nil(switch_event_get_header(helper->event, "astate")); const char *answer_state = switch_str_nil(switch_event_get_header(helper->event, "answer-state")); const char *dft_state; - const char *from_id = switch_str_nil(switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number")); + const char *from_id; const char *to_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_to_user")); const char *from_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_from_user")); char *clean_to_user = NULL; char *clean_from_user = NULL; int force_status = 0; + + if (!strcasecmp(direction, "inbound")) { + from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Destination-Number")); + } else { + from_id = switch_str_nil(switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number")); + } #if 0 char *buf; switch_event_serialize(helper->event, &buf, SWITCH_FALSE); @@ -2059,7 +2070,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, tagi_t tags[]) { - long exp_abs, exp_delta; + long exp_delta; char exp_delta_str[30] = ""; sip_to_t const *to; const char *from_user = NULL, *from_host = NULL; @@ -2080,7 +2091,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, int sent_reply = 0; sip_contact_t const *contact; const char *ipv6; - const char *contact_host, *contact_user; + const char *contact_user; sofia_nat_parse_t np = { { 0 } }; if (!sip) { @@ -2095,7 +2106,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, return; } - contact_host = sip->sip_contact->m_url->url_host; + //contact_host = sip->sip_contact->m_url->url_host; contact_user = sip->sip_contact->m_url->url_user; tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END()); @@ -2142,10 +2153,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, } } - if (exp_delta) { - exp_abs = (long) switch_epoch_time_now(NULL) + exp_delta; - } else { - exp_abs = 0; + if (!exp_delta) { sub_state = nua_substate_terminated; } @@ -2178,58 +2186,79 @@ void sofia_presence_handle_sip_i_subscribe(int status, sip->sip_expires->ex_delta = 31536000; } - if (sofia_test_pflag(profile, PFLAG_MULTIREG)) { - sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' " - "or (proto='%q' and sip_user='%q' and sip_host='%q' " - "and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q' " - "and contact='%q')", - call_id, proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname, contact_str); - - } else { - sql = switch_mprintf("delete from sip_subscriptions where " - "proto='%q' and sip_user='%q' and sip_host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q'", - proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname); - } - - switch_mutex_lock(profile->ireg_mutex); - switch_assert(sql != NULL); - sofia_glue_actually_execute_sql(profile, sql, NULL); - switch_safe_free(sql); - - if (sub_state == nua_substate_terminated) { - sstr = switch_mprintf("terminated"); - } else { - sip_accept_t *ap = sip->sip_accept; - char accept[256] = ""; - full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent); - while (ap) { - switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : ""); - ap = ap->ac_next; - } - - sql = switch_mprintf("insert into sip_subscriptions " - "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from," - "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip) " - "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q')", - proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host, - event, contact_str, call_id, full_from, full_via, - //sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1, + + if ((sub_state == nua_substate_active) && (switch_stristr("dialog", (const char *) event))) { + + sstr = switch_mprintf("active;expires=%ld", exp_delta); + + sql = switch_mprintf("update sip_subscriptions " + "set expires=%ld " + "where call_id='%q' and event='dialog' and hostname='%q' ", (long) switch_epoch_time_now(NULL) + (exp_delta * 2), - full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip); - - switch_assert(sql != NULL); + call_id, + mod_sofia_globals.hostname); + if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n", - profile->name, from_user, from_host, to_user, to_host, sql); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "re-subscribe with dialog detected, sql: %s\n", sql); + } + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } else { + if (sofia_test_pflag(profile, PFLAG_MULTIREG)) { + sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' " + "or (proto='%q' and sip_user='%q' and sip_host='%q' " + "and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q' " + "and contact='%q')", + call_id, proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname, contact_str); + + } else { + sql = switch_mprintf("delete from sip_subscriptions where " + "proto='%q' and sip_user='%q' and sip_host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q'", + proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname); } + switch_mutex_lock(profile->ireg_mutex); + switch_assert(sql != NULL); + sofia_glue_actually_execute_sql(profile, sql, NULL); + switch_safe_free(sql); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - sstr = switch_mprintf("active;expires=%ld", exp_delta); + if (sub_state == nua_substate_terminated) { + sstr = switch_mprintf("terminated"); + } else { + sip_accept_t *ap = sip->sip_accept; + char accept[256] = ""; + full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent); + while (ap) { + switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : ""); + ap = ap->ac_next; + } + + sql = switch_mprintf("insert into sip_subscriptions " + "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from," + "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip) " + "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q')", + proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host, + event, contact_str, call_id, full_from, full_via, + //sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1, + (long) switch_epoch_time_now(NULL) + (exp_delta * 2), + full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip); + + switch_assert(sql != NULL); + + if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n", + profile->name, from_user, from_host, to_user, to_host, sql); + } + + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + sstr = switch_mprintf("active;expires=%ld", exp_delta); } switch_mutex_unlock(profile->ireg_mutex); + } if (status < 200) { char *sticky = NULL; @@ -2773,9 +2802,7 @@ void sofia_presence_handle_sip_i_message(int status, sip_to_t const *to = sip->sip_to; const char *to_user = NULL; const char *to_host = NULL; - sip_subject_t const *sip_subject = sip->sip_subject; sip_payload_t *payload = sip->sip_payload; - const char *subject = "n/a"; char *msg = NULL; if (sip->sip_content_type && sip->sip_content_type->c_subtype) { @@ -2802,14 +2829,9 @@ void sofia_presence_handle_sip_i_message(int status, msg = payload->pl_data; } - if (sip_subject) { - subject = sip_subject->g_value; - } - if (nh) { char hash_key[512]; private_object_t *tech_pvt; - switch_channel_t *channel; switch_event_t *event; char *to_addr; char *from_addr; @@ -2840,7 +2862,6 @@ void sofia_presence_handle_sip_i_message(int status, } if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT) && (tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) { - channel = switch_core_session_get_channel(tech_pvt->session); if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index cac1d2f051..9130ceb569 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -852,7 +852,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand const char *reg_host = profile->reg_db_domain; const char *sub_host = profile->sub_domain; char contact_str[1024] = ""; - int nat_hack = 0; uint8_t multi_reg = 0, multi_reg_contact = 0, avoid_multi_reg = 0; uint8_t stale = 0, forbidden = 0; auth_res_t auth_res; @@ -863,7 +862,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand char network_ip[80]; char network_port_c[6]; char url_ip[80]; - char *register_gateway = NULL; int network_port; const char *reg_desc = "Registered"; const char *call_id = NULL; @@ -1094,8 +1092,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand avoid_multi_reg = 1; } - register_gateway = switch_event_get_header(*v_event, "sip-register-gateway"); - /* Allow us to force the SIP user to be something specific - needed if * we - for example - want to be able to ensure that the username a UA can * be contacted at is the same one that they used for authentication. @@ -1166,7 +1162,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand reg_desc = "Registered(AUTO-NAT)"; exptime = 30; } - nat_hack = 1; } else { char *p; switch_copy_string(contact_str, v_contact_str, sizeof(contact_str)); diff --git a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c index c139c053b1..4ea128dd31 100644 --- a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c +++ b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c @@ -94,7 +94,6 @@ static void do_rotate(cdr_fd_t *fd) char date[80] = ""; switch_size_t retsize; char *p; - size_t len; close(fd->fd); fd->fd = -1; @@ -103,7 +102,7 @@ static void do_rotate(cdr_fd_t *fd) switch_time_exp_lt(&tm, switch_micro_time_now()); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm); - len = strlen(fd->path) + strlen(date) + 2; + p = switch_mprintf("%s.%s", fd->path, date); assert(p); switch_file_rename(fd->path, p, globals.pool); diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 51194f4b14..7f2a7e8b3c 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -20,6 +20,8 @@ * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. + * Portions created by Seventh Signal Ltd. & Co. KG and its employees are Copyright (C) + * Seventh Signal Ltd. & Co. KG, All Rights Reserverd. * * Contributor(s): * Michal Bielicki @@ -158,7 +160,6 @@ static void do_rotate(cdr_fd_t *fd) char date[80] = ""; switch_size_t retsize; char *p; - size_t len; close(fd->fd); fd->fd = -1; @@ -167,7 +168,6 @@ static void do_rotate(cdr_fd_t *fd) switch_time_exp_lt(&tm, switch_micro_time_now()); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm); - len = strlen(fd->path) + strlen(date) + 2; p = switch_mprintf("%s.%s", fd->path, date); assert(p); switch_file_rename(fd->path, p, globals.pool); diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index 9a286d454f..abdb8101f6 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -20,6 +20,8 @@ * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. + * Portions created by Seventh Signal Ltd. & Co. KG and its employees are Copyright (C) + * Seventh Signal Ltd. & Co. KG, All Rights Reserverd. * * Contributor(s): * Daniel Swarbrick diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 900b9655ff..9a09e802c3 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -1106,7 +1106,7 @@ static int config(void) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid encoding strategy '%s' specified\n", val); } - } else if (!strcasecmp(var, "apply-inbound-acl")) { + } else if (!strcasecmp(var, "apply-inbound-acl") && ! zstr(val)) { if (prefs.acl_count < MAX_ACL) { prefs.acl[prefs.acl_count++] = strdup(val); } else { diff --git a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c index 5c4d11e807..2c0b927c0f 100644 --- a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c +++ b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c @@ -51,7 +51,6 @@ static struct { char *address; char *bindings; uint32_t key_count; - char hostname[80]; switch_port_t port; switch_sockaddr_t *addr; switch_socket_t *udp_socket; @@ -282,7 +281,7 @@ static void event_handler(switch_event_t *event) case SWITCH_EVENT_LOG: return; default: - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", globals.hostname); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", switch_core_get_switchname()); if (switch_event_serialize(event, &packet, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { size_t len; char *buf; @@ -377,7 +376,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_event_multicast_load) switch_core_hash_init(&globals.event_hash, module_pool); switch_core_hash_init(&globals.peer_hash, module_pool); - gethostname(globals.hostname, sizeof(globals.hostname)); globals.key_count = 0; if (load_config() != SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index f6a02623a7..4fbdcc8b96 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -990,19 +990,19 @@ SWITCH_STANDARD_API(event_sink_function) stream->write_function(stream, "\n"); while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) { - char *etype; + //char *etype; pevent = (switch_event_t *) pop; if (listener->format == EVENT_FORMAT_PLAIN) { - etype = "plain"; + //etype = "plain"; switch_event_serialize(pevent, &listener->ebuf, SWITCH_TRUE); stream->write_function(stream, "\n%s", listener->ebuf); } else if (listener->format == EVENT_FORMAT_JSON) { - etype = "json"; + //etype = "json"; switch_event_serialize_json(pevent, &listener->ebuf); } else { switch_xml_t xml; - etype = "xml"; + //etype = "xml"; if ((xml = switch_event_xmlize(pevent, SWITCH_VA_NONE))) { listener->ebuf = switch_xml_toxml(xml, SWITCH_FALSE); diff --git a/src/mod/event_handlers/mod_event_zmq/Makefile b/src/mod/event_handlers/mod_event_zmq/Makefile index 46d03f4bea..a724a63d1e 100644 --- a/src/mod/event_handlers/mod_event_zmq/Makefile +++ b/src/mod/event_handlers/mod_event_zmq/Makefile @@ -1,6 +1,6 @@ BASE=../../../.. -ZMQ=zeromq-2.1.3 +ZMQ=zeromq-2.1.4 ZMQ_BASEURL=http://download.zeromq.org diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c index 440cbf90a7..d42914d061 100644 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c +++ b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c @@ -24,6 +24,7 @@ * Contributor(s): * * Chris Parker + * Mathieu Rene * * * mod_radius_cdr.c -- RADIUS CDR Module @@ -145,13 +146,14 @@ static switch_status_t my_on_routing(switch_core_session_t *session) switch_time_t callanswerdate = 0; switch_time_t callenddate = 0; switch_time_t calltransferdate = 0; + const char *signal_bond = NULL; char *uuid_str; switch_time_exp_t tm; char buffer[32]; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_routing\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_routing\n"); if (globals.shutdown) { return SWITCH_STATUS_FALSE; @@ -160,7 +162,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) if (channel) { const char *disable_flag = switch_channel_get_variable(channel, "disable_radius_start"); if (switch_true(disable_flag)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Start\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Start\n"); return SWITCH_STATUS_SUCCESS; } } @@ -170,14 +172,14 @@ static switch_status_t my_on_routing(switch_core_session_t *session) rad_config = my_radius_init(); if (rad_config == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, Start packet not logged.\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, Start packet not logged.\n"); goto end; } if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { uuid_str = switch_core_session_get_uuid(session); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n"); goto end; } @@ -185,13 +187,13 @@ static switch_status_t my_on_routing(switch_core_session_t *session) /* Set Status Type */ if (rc_avpair_add(rad_config, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed setting Acct-Status-Type: Start\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed setting Acct-Status-Type: Start\n"); rc_destroy(rad_config); goto end; } if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_ID, uuid_str, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed adding Acct-Session-ID: %s\n", uuid_str); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed adding Acct-Session-ID: %s\n", uuid_str); rc_destroy(rad_config); goto end; } @@ -205,11 +207,19 @@ static switch_status_t my_on_routing(switch_core_session_t *session) /* cause = switch_channel_get_cause(channel); if (rc_avpair_add(rad_config, &send, PW_FS_HANGUPCAUSE, &cause, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause); rc_destroy(rad_config); return SWITCH_STATUS_TERM; } */ + + if ((signal_bond = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && !zstr(signal_bond)) { + if (rc_avpair_add(rad_config, &send, PW_FS_OTHER_LEG_ID, (void*) signal_bond, -1, PW_FS_PEC) == NULL) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Failed adding Freeswitch-Other-Leg-Id: %s\n", uuid_str); + rc_destroy(rad_config); + goto end; + } + } profile = switch_channel_get_caller_profile(channel); @@ -222,35 +232,35 @@ static switch_status_t my_on_routing(switch_core_session_t *session) if (profile->username) { if (rc_avpair_add(rad_config, &send, PW_USER_NAME, (void *) profile->username, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username); rc_destroy(rad_config); goto end; } } if (profile->caller_id_number) { if (rc_avpair_add(rad_config, &send, PW_FS_SRC, (void *) profile->caller_id_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); rc_destroy(rad_config); goto end; } } if (profile->caller_id_name) { if (rc_avpair_add(rad_config, &send, PW_FS_CLID, (void *) profile->caller_id_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); rc_destroy(rad_config); goto end; } } if (profile->destination_number) { if (rc_avpair_add(rad_config, &send, PW_FS_DST, (void *) profile->destination_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); rc_destroy(rad_config); goto end; } } if (profile->dialplan) { if (rc_avpair_add(rad_config, &send, PW_FS_DIALPLAN, (void *) profile->dialplan, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); rc_destroy(rad_config); goto end; } @@ -259,42 +269,42 @@ static switch_status_t my_on_routing(switch_core_session_t *session) inet_pton(AF_INET, (void *) profile->network_addr, &framed_addr); framed_addr = htonl(framed_addr); if (rc_avpair_add(rad_config, &send, PW_FRAMED_IP_ADDRESS, &framed_addr, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr); rc_destroy(rad_config); goto end; } } if (profile->rdnis) { if (rc_avpair_add(rad_config, &send, PW_FS_RDNIS, (void *) profile->rdnis, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); rc_destroy(rad_config); goto end; } } if (profile->context) { if (rc_avpair_add(rad_config, &send, PW_FS_CONTEXT, (void *) profile->context, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); rc_destroy(rad_config); goto end; } } if (profile->ani) { if (rc_avpair_add(rad_config, &send, PW_FS_ANI, (void *) profile->ani, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); rc_destroy(rad_config); goto end; } } if (profile->aniii) { if (rc_avpair_add(rad_config, &send, PW_FS_ANIII, (void *) profile->aniii, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); rc_destroy(rad_config); goto end; } } if (profile->source) { if (rc_avpair_add(rad_config, &send, PW_FS_SOURCE, (void *) profile->source, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); rc_destroy(rad_config); goto end; } @@ -305,7 +315,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLSTARTDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer); rc_destroy(rad_config); goto end; } @@ -317,7 +327,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLANSWERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer); rc_destroy(rad_config); goto end; } @@ -329,7 +339,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLTRANSFERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer); rc_destroy(rad_config); goto end; } @@ -341,7 +351,7 @@ static switch_status_t my_on_routing(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLENDDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer); rc_destroy(rad_config); goto end; } @@ -350,21 +360,21 @@ static switch_status_t my_on_routing(switch_core_session_t *session) if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) { if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP, (void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source); rc_destroy(rad_config); goto end; } } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "profile == NULL\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "profile == NULL\n"); } } if (rc_acct(rad_config, client_port, send) == OK_RC) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] RADIUS Accounting OK\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] RADIUS Accounting OK\n"); retval = SWITCH_STATUS_SUCCESS; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] RADIUS Accounting Failed\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] RADIUS Accounting Failed\n"); retval = SWITCH_STATUS_TERM; } rc_avpair_free(send); @@ -404,26 +414,26 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) if (channel) { const char *disable_flag = switch_channel_get_variable(channel, "disable_radius_stop"); if (switch_true(disable_flag)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Stop\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Not Sending RADIUS Stop\n"); return SWITCH_STATUS_SUCCESS; } } switch_thread_rwlock_rdlock(globals.rwlock); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_reporting\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Entering my_on_reporting\n"); rad_config = my_radius_init(); if (rad_config == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, session not logged.\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing radius, session not logged.\n"); goto end; } if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) { uuid_str = switch_core_session_get_uuid(session); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "[mod_radius_cdr] Error Generating Data!\n"); goto end; } @@ -431,13 +441,13 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) /* Set Status Type */ if (rc_avpair_add(rad_config, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); rc_destroy(rad_config); goto end; } if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_ID, uuid_str, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-ID: %s\n", uuid_str); rc_destroy(rad_config); goto end; } @@ -450,7 +460,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) cause = switch_channel_get_cause(channel); if (rc_avpair_add(rad_config, &send, PW_FS_HANGUPCAUSE, &cause, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Hangupcause: %d\n", cause); rc_destroy(rad_config); goto end; } @@ -459,7 +469,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) if (profile) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Calculating billable time\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Calculating billable time\n"); /* calculate billable time */ callstartdate = profile->times->created; @@ -480,39 +490,39 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) } billsec = (billusec / 1000000); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[mod_radius_cdr] Finished calculating billable time\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "[mod_radius_cdr] Finished calculating billable time\n"); if (profile->username) { if (rc_avpair_add(rad_config, &send, PW_USER_NAME, (void *) profile->username, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding User-Name: %s\n", profile->username); rc_destroy(rad_config); goto end; } } if (profile->caller_id_number) { if (rc_avpair_add(rad_config, &send, PW_FS_SRC, (void *) profile->caller_id_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Src: %s\n", profile->caller_id_number); rc_destroy(rad_config); goto end; } } if (profile->caller_id_name) { if (rc_avpair_add(rad_config, &send, PW_FS_CLID, (void *) profile->caller_id_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-CLID: %s\n", profile->caller_id_name); rc_destroy(rad_config); goto end; } } if (profile->destination_number) { if (rc_avpair_add(rad_config, &send, PW_FS_DST, (void *) profile->destination_number, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dst: %s\n", profile->destination_number); rc_destroy(rad_config); goto end; } } if (profile->dialplan) { if (rc_avpair_add(rad_config, &send, PW_FS_DIALPLAN, (void *) profile->dialplan, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Dialplan: %s\n", profile->dialplan); rc_destroy(rad_config); goto end; } @@ -521,42 +531,42 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) inet_pton(AF_INET, (void *) profile->network_addr, &framed_addr); framed_addr = htonl(framed_addr); if (rc_avpair_add(rad_config, &send, PW_FRAMED_IP_ADDRESS, &framed_addr, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Framed-IP-Address: %s\n", profile->network_addr); rc_destroy(rad_config); goto end; } } if (profile->rdnis) { if (rc_avpair_add(rad_config, &send, PW_FS_RDNIS, (void *) profile->rdnis, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-RDNIS: %s\n", profile->rdnis); rc_destroy(rad_config); goto end; } } if (profile->context) { if (rc_avpair_add(rad_config, &send, PW_FS_CONTEXT, (void *) profile->context, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Context: %s\n", profile->context); rc_destroy(rad_config); goto end; } } if (profile->ani) { if (rc_avpair_add(rad_config, &send, PW_FS_ANI, (void *) profile->ani, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANI: %s\n", profile->ani); rc_destroy(rad_config); goto end; } } if (profile->aniii) { if (rc_avpair_add(rad_config, &send, PW_FS_ANIII, (void *) profile->aniii, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-ANIII: %s\n", profile->aniii); rc_destroy(rad_config); goto end; } } if (profile->source) { if (rc_avpair_add(rad_config, &send, PW_FS_SOURCE, (void *) profile->source, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Source: %s\n", profile->source); rc_destroy(rad_config); goto end; } @@ -564,13 +574,13 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) if (profile->caller_extension && profile->caller_extension->last_application && profile->caller_extension->last_application->application_name) { if (rc_avpair_add(rad_config, &send, PW_FS_LASTAPP, (void *) profile->caller_extension->last_application->application_name, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Lastapp: %s\n", profile->source); rc_destroy(rad_config); goto end; } } if (rc_avpair_add(rad_config, &send, PW_FS_BILLUSEC, &billusec, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Billusec: %u\n", (uint32_t) billusec); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Billusec: %u\n", (uint32_t) billusec); rc_destroy(rad_config); goto end; } @@ -581,7 +591,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLSTARTDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callstartdate: %s\n", buffer); rc_destroy(rad_config); goto end; } @@ -593,7 +603,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLANSWERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callanswerdate: %s\n", buffer); rc_destroy(rad_config); goto end; } @@ -605,7 +615,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLTRANSFERDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Calltransferdate: %s\n", buffer); rc_destroy(rad_config); goto end; } @@ -617,27 +627,38 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_gmtoff / 3600, tm.tm_gmtoff % 3600); if (rc_avpair_add(rad_config, &send, PW_FS_CALLENDDATE, &buffer, -1, PW_FS_PEC) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Callenddate: %s\n", buffer); rc_destroy(rad_config); goto end; } } if (rc_avpair_add(rad_config, &send, PW_ACCT_SESSION_TIME, &billsec, -1, 0) == NULL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed adding Acct-Session-Time: %u\n", billsec); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Acct-Session-Time: %u\n", billsec); rc_destroy(rad_config); goto end; } + + { + const char *direction_str = profile->direction == SWITCH_CALL_DIRECTION_INBOUND ? "inbound" : "outbound"; + + if (rc_avpair_add(rad_config, &send, PW_FS_DIRECTION, (void *) direction_str, -1, PW_FS_PEC) == NULL) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "failed adding Freeswitch-Direction: %s\n", direction_str); + rc_destroy(rad_config); + goto end; + } + } + } else { /* no profile, can't create data to send */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "profile == NULL\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "profile == NULL\n"); } } if (rc_acct(rad_config, client_port, send) == OK_RC) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RADIUS Accounting OK\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RADIUS Accounting OK\n"); retval = SWITCH_STATUS_SUCCESS; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RADIUS Accounting Failed\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RADIUS Accounting Failed\n"); retval = SWITCH_STATUS_TERM; } rc_avpair_free(send); diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h index e4e5a38afc..a3effad005 100644 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h +++ b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.h @@ -58,6 +58,8 @@ #define PW_FS_CALLANSWERDATE 21 #define PW_FS_CALLTRANSFERDATE 22 #define PW_FS_CALLENDDATE 23 +#define PW_FS_DIRECTION 24 +#define PW_FS_OTHER_LEG_ID 25 #endif diff --git a/src/mod/event_handlers/mod_radius_cdr/radius/dictionary b/src/mod/event_handlers/mod_radius_cdr/radius/dictionary index 8c04c6dd93..c126e685d4 100644 --- a/src/mod/event_handlers/mod_radius_cdr/radius/dictionary +++ b/src/mod/event_handlers/mod_radius_cdr/radius/dictionary @@ -276,6 +276,8 @@ ATTRIBUTE Freeswitch-Callstartdate 20 string Freeswitch ATTRIBUTE Freeswitch-Callanswerdate 21 string Freeswitch ATTRIBUTE Freeswitch-Calltransferdate 22 string Freeswitch ATTRIBUTE Freeswitch-Callenddate 23 string Freeswitch +ATTRIBUTE Freeswitch-Direction 24 string Freeswitch +ATTRIBUTE Freeswitch-Other-Leg-Id 25 string Freeswitch # # Freeswitch-Hangupcause diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB index 84485269f9..68d83fe433 100644 --- a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB +++ b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB @@ -1,3 +1,34 @@ + +-- FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application +-- Copyright (C) 2005-2011, 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 / Soft-Switch Application +-- +-- 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. +-- Portions created by Seventh Signal Ltd. & Co. KG and its employees are Copyright (C) +-- Seventh Signal Ltd. & Co. KG, All Rights Reserverd. +-- +-- Contributor(s): +-- Daniel Swarbrick +-- Stefan Knoblich +-- +-- MIB Definition for mod_snmp + FREESWITCH-MIB DEFINITIONS ::= BEGIN IMPORTS diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c index d415d4fe1c..059646bc19 100644 --- a/src/mod/event_handlers/mod_snmp/mod_snmp.c +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -20,6 +20,8 @@ * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. + * Portions created by Seventh Signal Ltd. & Co. KG and its employees are Copyright (C) + * Seventh Signal Ltd. & Co. KG, All Rights Reserverd. * * Contributor(s): * Daniel Swarbrick diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c index 871fb5ad75..69f135d6bd 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.c +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -20,6 +20,8 @@ * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. + * Portions created by Seventh Signal Ltd. & Co. KG and its employees are Copyright (C) + * Seventh Signal Ltd. & Co. KG, All Rights Reserverd. * * Contributor(s): * Daniel Swarbrick @@ -138,7 +140,7 @@ int channelList_load(netsnmp_cache *cache, void *vmagic) idx = 1; - sprintf(sql, "SELECT * FROM channels WHERE hostname='%s' ORDER BY created_epoch", switch_core_get_hostname()); + sprintf(sql, "SELECT * FROM channels WHERE hostname='%s' ORDER BY created_epoch", switch_core_get_switchname()); switch_cache_db_execute_sql_callback(dbh, sql, channelList_callback, NULL, NULL); switch_cache_db_release_db_handle(&dbh); @@ -235,14 +237,13 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio case SS_CURRENT_CALLS: { switch_cache_db_handle_t *dbh; - char sql[1024] = "", hostname[256] = ""; + char sql[1024] = ""; if (switch_core_db_handle(&dbh) != SWITCH_STATUS_SUCCESS) { return SNMP_ERR_GENERR; } - gethostname(hostname, sizeof(hostname)); - sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", hostname); + sprintf(sql, "SELECT COUNT(*) FROM calls WHERE hostname='%s'", switch_core_get_switchname()); switch_cache_db_execute_sql_callback(dbh, sql, sql_count_callback, &int_val, NULL); snmp_set_var_typed_integer(requests->requestvb, ASN_GAUGE, int_val); switch_cache_db_release_db_handle(&dbh); diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h index 5da87a6c4e..ba3c523d49 100644 --- a/src/mod/event_handlers/mod_snmp/subagent.h +++ b/src/mod/event_handlers/mod_snmp/subagent.h @@ -1,3 +1,36 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, 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 / Soft-Switch Application + * + * 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. + * Portions created by Seventh Signal Ltd. & Co. KG and its employees are Copyright (C) + * Seventh Signal Ltd. & Co. KG, All Rights Reserverd. + * + * Contributor(s): + * Daniel Swarbrick + * Stefan Knoblich + * + * subagent.h -- SNMP Agent Definitions + * + */ + #ifndef subagent_H #define subagent_H diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index ea94bd1cd6..4f36e20128 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -758,7 +758,7 @@ SWITCH_STANDARD_API(start_local_stream_function) char *mycmd = NULL, *argv[8] = { 0 }; char *local_stream_name = NULL, *path = NULL, *timer_name = NULL; uint32_t prebuf = 1; - int rate = 8000, shuffle = 1, interval = 20; + int rate = 8000, interval = 20; uint8_t channels = 1; int argc = 0; char *cf = "local_stream.conf"; @@ -790,7 +790,7 @@ SWITCH_STANDARD_API(start_local_stream_function) } } - shuffle = argv[3] ? switch_true(argv[3]) : 1; + //shuffle = argv[3] ? switch_true(argv[3]) : 1; prebuf = argv[4] ? atoi(argv[4]) : DEFAULT_PREBUFFER_SIZE; if (argv[5]) { @@ -833,8 +833,8 @@ SWITCH_STANDARD_API(start_local_stream_function) if (tmp == 8000 || tmp == 16000 || tmp == 32000) { rate = tmp; } - } else if (!strcasecmp(var, "shuffle")) { - shuffle = switch_true(val); + //} else if (!strcasecmp(var, "shuffle")) { + //shuffle = switch_true(val); } else if (!strcasecmp(var, "prebuf")) { tmp = atoi(val); if (tmp > 0) { diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 377cfe520c..a4134db943 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #define OUTSCALE 8192 * 2 #define MP3_SCACHE 16384 * 2 @@ -1480,7 +1480,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_shout_load) supported_formats[0] = "shout"; supported_formats[1] = "mp3"; - curl_global_init(CURL_GLOBAL_ALL); + switch_curl_init(); /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -1507,7 +1507,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_shout_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_shout_shutdown) { - curl_global_cleanup(); + switch_curl_destroy(); mpg123_exit(); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c b/src/mod/formats/mod_sndfile/mod_sndfile.c index d2c53f0ba1..5b011dccb2 100644 --- a/src/mod/formats/mod_sndfile/mod_sndfile.c +++ b/src/mod/formats/mod_sndfile/mod_sndfile.c @@ -339,7 +339,6 @@ static char **supported_formats; static switch_status_t setup_formats(void) { SF_FORMAT_INFO info; - SF_INFO sfinfo; char buffer[128]; int format, major_count, subtype_count, m, s; int len, x, skip; @@ -358,7 +357,7 @@ static switch_status_t setup_formats(void) sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof(int)); sf_command(NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &subtype_count, sizeof(int)); - sfinfo.channels = 1; + //sfinfo.channels = 1; len = ((major_count + (exlen + 2)) * sizeof(char *)); supported_formats = switch_core_permanent_alloc(len); @@ -402,7 +401,7 @@ static switch_status_t setup_formats(void) info.format = s; sf_command(NULL, SFC_GET_FORMAT_SUBTYPE, &info, sizeof(info)); format = (format & SF_FORMAT_TYPEMASK) | info.format; - sfinfo.format = format; + //sfinfo.format = format; /* if (sf_format_check(&sfinfo)) { switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, " %s\n", info.name); diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 7bc3d50b8a..0b0a17a225 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -123,7 +123,6 @@ void Session::check_hangup_hook() void Session::do_hangup_hook() { if (hh && !mark) { - const char *err = NULL; int arg_count = 2; mark++; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index e08ed5c253..a0bf23dbfb 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -1121,6 +1121,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("execute_on_tone_detect"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -4263,6 +4273,35 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_say_args_t_gender_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_args_t_ext_set(void * jarg1, char * jarg2) { + switch_say_args_t *arg1 = (switch_say_args_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_say_args_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->ext = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->ext, (const char *)arg2); + } else { + arg1->ext = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_args_t_ext_get(void * jarg1) { + char * jresult ; + switch_say_args_t *arg1 = (switch_say_args_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_args_t *)jarg1; + result = (char *) ((arg1)->ext); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_say_args_t() { void * jresult ; switch_say_args_t *result = 0 ; @@ -7218,6 +7257,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_hostname() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_switchname() { + char * jresult ; + char *result = 0 ; + + result = (char *)switch_core_get_switchname(); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_set_variable(char * jarg1, char * jarg2) { char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; @@ -10331,6 +10380,11 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute_trans(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_set_signal_handlers() { + switch_core_set_signal_handlers(); +} + + SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_debug_level() { unsigned long jresult ; uint32_t result; @@ -10436,6 +10490,79 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_expire_registration(int jarg1) { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_get_variable(void * jarg1, char * jarg2) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (char *)switch_say_file_handle_get_variable(arg1,(char const *)arg2); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_get_path(void * jarg1) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + result = (char *)switch_say_file_handle_get_path(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_detach_path(void * jarg1) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + result = (char *)switch_say_file_handle_detach_path(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_file_handle_destroy(void * jarg1) { + switch_say_file_handle_t **arg1 = (switch_say_file_handle_t **) 0 ; + + arg1 = (switch_say_file_handle_t **)jarg1; + switch_say_file_handle_destroy(arg1); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_say_file_handle_create(void * jarg1, char * jarg2, void * jarg3) { + int jresult ; + switch_say_file_handle_t **arg1 = (switch_say_file_handle_t **) 0 ; + char *arg2 = (char *) 0 ; + switch_event_t **arg3 = (switch_event_t **) 0 ; + switch_status_t result; + + arg1 = (switch_say_file_handle_t **)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_event_t **)jarg3; + result = (switch_status_t)switch_say_file_handle_create(arg1,(char const *)arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_file(void * jarg1, char * jarg2) { + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + void *arg3 = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + arg2 = (char *)jarg2; + switch_say_file(arg1,(char const *)arg2,arg3); +} + + 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 ; @@ -11988,6 +12115,42 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_frame_free(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_number(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_bool_t result; + + arg1 = (char *)jarg1; + result = (switch_bool_t)switch_is_number((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_true(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_true((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_false(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_false((char const *)arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_resolve_host(char * jarg1, char * jarg2, unsigned long jarg3) { int jresult ; char *arg1 = (char *) 0 ; @@ -12246,6 +12409,18 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_string(char * jarg1) { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_name_string(char * jarg1) { + char * jresult ; + char *arg1 = (char *) 0 ; + char *result = 0 ; + + arg1 = (char *)jarg1; + result = (char *)switch_clean_name_string(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_safe_strdup(char * jarg1) { char * jresult ; char *arg1 = (char *) 0 ; @@ -12344,18 +12519,6 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_switch_separate_string_string(char * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_number(char * jarg1) { - int jresult ; - char *arg1 = (char *) 0 ; - switch_bool_t result; - - arg1 = (char *)jarg1; - result = (switch_bool_t)switch_is_number((char const *)arg1); - jresult = result; - return jresult; -} - - SWIGEXPORT char * SWIGSTDCALL CSharp_switch_strip_spaces(char * jarg1, int jarg2) { char * jresult ; char *arg1 = (char *) 0 ; @@ -19356,6 +19519,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_say_interface_say_function_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_interface_say_string_function_set(void * jarg1, void * jarg2) { + switch_say_interface *arg1 = (switch_say_interface *) 0 ; + switch_say_string_callback_t arg2 = (switch_say_string_callback_t) 0 ; + + arg1 = (switch_say_interface *)jarg1; + arg2 = (switch_say_string_callback_t)jarg2; + if (arg1) (arg1)->say_string_function = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_say_interface_say_string_function_get(void * jarg1) { + void * jresult ; + switch_say_interface *arg1 = (switch_say_interface *) 0 ; + switch_say_string_callback_t result; + + arg1 = (switch_say_interface *)jarg1; + result = (switch_say_string_callback_t) ((arg1)->say_string_function); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_interface_rwlock_set(void * jarg1, void * jarg2) { switch_say_interface *arg1 = (switch_say_interface *) 0 ; switch_thread_rwlock_t *arg2 = (switch_thread_rwlock_t *) 0 ; @@ -22463,6 +22648,34 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_timetable_resurrected_get(vo } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_bridged_set(void * jarg1, void * jarg2) { + switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_channel_timetable *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->bridged = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_timetable_bridged_get(void * jarg1) { + void * jresult ; + switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; + switch_time_t result; + + arg1 = (switch_channel_timetable *)jarg1; + result = ((arg1)->bridged); + jresult = new switch_time_t((const switch_time_t &)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_next_set(void * jarg1, void * jarg2) { switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; switch_channel_timetable *arg2 = (switch_channel_timetable *) 0 ; @@ -23842,6 +24055,14 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_test_app_flag_key(char * jarg1, } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_bridge_time(void * jarg1) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + switch_channel_set_bridge_time(arg1); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_hangup_time(void * jarg1) { switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -23972,6 +24193,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_mark_hold(void * jarg1, int ja } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_execute_on(void * jarg1, char * jarg2) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_channel_execute_on(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) { int jresult ; switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; @@ -25072,7 +25307,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_json(void * jarg1, char * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6, int jarg7) { int jresult ; char *arg1 = (char *) 0 ; char arg2 ; @@ -25080,6 +25315,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha char arg4 ; switch_event_t **arg5 = (switch_event_t **) 0 ; char **arg6 = (char **) 0 ; + switch_bool_t arg7 ; switch_status_t result; arg1 = (char *)jarg1; @@ -25088,7 +25324,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha arg4 = (char)jarg4; arg5 = (switch_event_t **)jarg5; arg6 = (char **)jarg6; - result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6); + arg7 = (switch_bool_t)jarg7; + result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = result; return jresult; } @@ -27618,6 +27855,34 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_say(void * jarg1, char * jarg2, cha } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_say_string(void * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8, void * jarg9) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + char *arg7 = (char *) 0 ; + char *arg8 = (char *) 0 ; + char **arg9 = (char **) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + arg8 = (char *)jarg8; + arg9 = (char **)jarg9; + result = (switch_status_t)switch_ivr_say_string(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,arg9); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_get_say_method_by_name(char * jarg1) { int jresult ; char *arg1 = (char *) 0 ; @@ -29723,6 +29988,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_is_switch_xml_root_t_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_xml_refs_set(void * jarg1, unsigned long jarg2) { + switch_xml *arg1 = (switch_xml *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_xml *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->refs = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_xml_refs_get(void * jarg1) { + unsigned long jresult ; + switch_xml *arg1 = (switch_xml *) 0 ; + uint32_t result; + + arg1 = (switch_xml *)jarg1; + result = (uint32_t) ((arg1)->refs); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_xml() { void * jresult ; switch_xml *result = 0 ; @@ -30443,6 +30730,30 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_std_datetime_check(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_locate_language(void * jarg1, void * jarg2, void * jarg3, void * jarg4, void * jarg5, void * jarg6, char * jarg7) { + int jresult ; + switch_xml_t *arg1 = (switch_xml_t *) 0 ; + switch_xml_t *arg2 = (switch_xml_t *) 0 ; + switch_event_t *arg3 = (switch_event_t *) 0 ; + switch_xml_t *arg4 = (switch_xml_t *) 0 ; + switch_xml_t *arg5 = (switch_xml_t *) 0 ; + switch_xml_t *arg6 = (switch_xml_t *) 0 ; + char *arg7 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_xml_t *)jarg1; + arg2 = (switch_xml_t *)jarg2; + arg3 = (switch_event_t *)jarg3; + arg4 = (switch_xml_t *)jarg4; + arg5 = (switch_xml_t *)jarg5; + arg6 = (switch_xml_t *)jarg6; + arg7 = (char *)jarg7; + result = (switch_status_t)switch_xml_locate_language(arg1,arg2,arg3,arg4,arg5,arg6,(char const *)arg7); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_io_event_hook_outgoing_channel_outgoing_channel_set(void * jarg1, void * jarg2) { switch_io_event_hook_outgoing_channel *arg1 = (switch_io_event_hook_outgoing_channel *) 0 ; switch_outgoing_channel_hook_t arg2 = (switch_outgoing_channel_hook_t) 0 ; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index b3ce7997b9..d1c0dfcb31 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -1191,6 +1191,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "execute_on_tone_detect"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -3012,6 +3023,35 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_numbers_t_flush_packet_count_get } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_numbers_t_largest_jb_size_set(void * jarg1, void * jarg2) { + switch_rtp_numbers_t *arg1 = (switch_rtp_numbers_t *) 0 ; + switch_size_t arg2 ; + switch_size_t *argp2 ; + + arg1 = (switch_rtp_numbers_t *)jarg1; + argp2 = (switch_size_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->largest_jb_size = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_numbers_t_largest_jb_size_get(void * jarg1) { + void * jresult ; + switch_rtp_numbers_t *arg1 = (switch_rtp_numbers_t *) 0 ; + switch_size_t result; + + arg1 = (switch_rtp_numbers_t *)jarg1; + result = ((arg1)->largest_jb_size); + jresult = new switch_size_t((switch_size_t &)result); + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_rtp_numbers_t() { void * jresult ; switch_rtp_numbers_t *result = 0 ; @@ -4486,6 +4526,35 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_say_args_t_gender_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_args_t_ext_set(void * jarg1, char * jarg2) { + switch_say_args_t *arg1 = (switch_say_args_t *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_say_args_t *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->ext = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->ext, (const char *)arg2); + } else { + arg1->ext = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_args_t_ext_get(void * jarg1) { + char * jresult ; + switch_say_args_t *arg1 = (switch_say_args_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_args_t *)jarg1; + result = (char *) ((arg1)->ext); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_say_args_t() { void * jresult ; switch_say_args_t *result = 0 ; @@ -7509,6 +7578,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_hostname() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_switchname() { + char * jresult ; + char *result = 0 ; + + result = (char *)switch_core_get_switchname(); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_set_variable(char * jarg1, char * jarg2) { char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; @@ -10631,6 +10710,11 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_persistant_execute_trans(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_set_signal_handlers() { + switch_core_set_signal_handlers(); +} + + SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_debug_level() { unsigned long jresult ; uint32_t result; @@ -10736,6 +10820,79 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_expire_registration(int jarg1) { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_get_variable(void * jarg1, char * jarg2) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + arg2 = (char *)jarg2; + result = (char *)switch_say_file_handle_get_variable(arg1,(char const *)arg2); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_get_path(void * jarg1) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + result = (char *)switch_say_file_handle_get_path(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_say_file_handle_detach_path(void * jarg1) { + char * jresult ; + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + result = (char *)switch_say_file_handle_detach_path(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_file_handle_destroy(void * jarg1) { + switch_say_file_handle_t **arg1 = (switch_say_file_handle_t **) 0 ; + + arg1 = (switch_say_file_handle_t **)jarg1; + switch_say_file_handle_destroy(arg1); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_say_file_handle_create(void * jarg1, char * jarg2, void * jarg3) { + int jresult ; + switch_say_file_handle_t **arg1 = (switch_say_file_handle_t **) 0 ; + char *arg2 = (char *) 0 ; + switch_event_t **arg3 = (switch_event_t **) 0 ; + switch_status_t result; + + arg1 = (switch_say_file_handle_t **)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_event_t **)jarg3; + result = (switch_status_t)switch_say_file_handle_create(arg1,(char const *)arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_file(void * jarg1, char * jarg2) { + switch_say_file_handle_t *arg1 = (switch_say_file_handle_t *) 0 ; + char *arg2 = (char *) 0 ; + void *arg3 = 0 ; + + arg1 = (switch_say_file_handle_t *)jarg1; + arg2 = (char *)jarg2; + switch_say_file(arg1,(char const *)arg2,arg3); +} + + 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 ; @@ -12312,6 +12469,42 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_frame_free(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_number(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_bool_t result; + + arg1 = (char *)jarg1; + result = (switch_bool_t)switch_is_number((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_true(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_true((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_false(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_false((char const *)arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_resolve_host(char * jarg1, char * jarg2, unsigned long jarg3) { int jresult ; char *arg1 = (char *) 0 ; @@ -12570,6 +12763,18 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_string(char * jarg1) { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_clean_name_string(char * jarg1) { + char * jresult ; + char *arg1 = (char *) 0 ; + char *result = 0 ; + + arg1 = (char *)jarg1; + result = (char *)switch_clean_name_string(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_safe_strdup(char * jarg1) { char * jresult ; char *arg1 = (char *) 0 ; @@ -12668,18 +12873,6 @@ SWIGEXPORT unsigned int SWIGSTDCALL CSharp_switch_separate_string_string(char * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_number(char * jarg1) { - int jresult ; - char *arg1 = (char *) 0 ; - switch_bool_t result; - - arg1 = (char *)jarg1; - result = (switch_bool_t)switch_is_number((char const *)arg1); - jresult = result; - return jresult; -} - - SWIGEXPORT char * SWIGSTDCALL CSharp_switch_strip_spaces(char * jarg1, int jarg2) { char * jresult ; char *arg1 = (char *) 0 ; @@ -19902,6 +20095,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_say_interface_say_function_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_interface_say_string_function_set(void * jarg1, void * jarg2) { + switch_say_interface *arg1 = (switch_say_interface *) 0 ; + switch_say_string_callback_t arg2 = (switch_say_string_callback_t) 0 ; + + arg1 = (switch_say_interface *)jarg1; + arg2 = (switch_say_string_callback_t)jarg2; + if (arg1) (arg1)->say_string_function = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_say_interface_say_string_function_get(void * jarg1) { + void * jresult ; + switch_say_interface *arg1 = (switch_say_interface *) 0 ; + switch_say_string_callback_t result; + + arg1 = (switch_say_interface *)jarg1; + result = (switch_say_string_callback_t) ((arg1)->say_string_function); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_say_interface_rwlock_set(void * jarg1, void * jarg2) { switch_say_interface *arg1 = (switch_say_interface *) 0 ; switch_thread_rwlock_t *arg2 = (switch_thread_rwlock_t *) 0 ; @@ -23124,6 +23340,35 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_timetable_resurrected_get(vo } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_bridged_set(void * jarg1, void * jarg2) { + switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_channel_timetable *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->bridged = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_timetable_bridged_get(void * jarg1) { + void * jresult ; + switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; + switch_time_t result; + + arg1 = (switch_channel_timetable *)jarg1; + result = ((arg1)->bridged); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_next_set(void * jarg1, void * jarg2) { switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; switch_channel_timetable *arg2 = (switch_channel_timetable *) 0 ; @@ -24505,6 +24750,14 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_test_app_flag_key(char * jarg1, } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_bridge_time(void * jarg1) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + switch_channel_set_bridge_time(arg1); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_hangup_time(void * jarg1) { switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -24635,6 +24888,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_mark_hold(void * jarg1, int ja } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_execute_on(void * jarg1, char * jarg2) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_channel_execute_on(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) { int jresult ; switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; @@ -25748,7 +26015,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_json(void * jarg1, char * } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, char jarg2, char jarg3, char jarg4, void * jarg5, void * jarg6, int jarg7) { int jresult ; char *arg1 = (char *) 0 ; char arg2 ; @@ -25756,6 +26023,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha char arg4 ; switch_event_t **arg5 = (switch_event_t **) 0 ; char **arg6 = (char **) 0 ; + switch_bool_t arg7 ; switch_status_t result; arg1 = (char *)jarg1; @@ -25764,7 +26032,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_brackets(char * jarg1, cha arg4 = (char)jarg4; arg5 = (switch_event_t **)jarg5; arg6 = (char **)jarg6; - result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6); + arg7 = (switch_bool_t)jarg7; + result = (switch_status_t)switch_event_create_brackets(arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = result; return jresult; } @@ -28318,6 +28587,34 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_say(void * jarg1, char * jarg2, cha } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_say_string(void * jarg1, char * jarg2, char * jarg3, char * jarg4, char * jarg5, char * jarg6, char * jarg7, char * jarg8, void * jarg9) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + char *arg7 = (char *) 0 ; + char *arg8 = (char *) 0 ; + char **arg9 = (char **) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (char *)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (char *)jarg7; + arg8 = (char *)jarg8; + arg9 = (char **)jarg9; + result = (switch_status_t)switch_ivr_say_string(arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,(char const *)arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,arg9); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_get_say_method_by_name(char * jarg1) { int jresult ; char *arg1 = (char *) 0 ; @@ -30441,6 +30738,29 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_is_switch_xml_root_t_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_xml_refs_set(void * jarg1, unsigned long jarg2) { + switch_xml *arg1 = (switch_xml *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_xml *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->refs = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_xml_refs_get(void * jarg1) { + unsigned long jresult ; + switch_xml *arg1 = (switch_xml *) 0 ; + uint32_t result; + + arg1 = (switch_xml *)jarg1; + result = (uint32_t) ((arg1)->refs); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_xml() { void * jresult ; switch_xml *result = 0 ; @@ -31162,6 +31482,30 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_std_datetime_check(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_locate_language(void * jarg1, void * jarg2, void * jarg3, void * jarg4, void * jarg5, void * jarg6, char * jarg7) { + int jresult ; + switch_xml_t *arg1 = (switch_xml_t *) 0 ; + switch_xml_t *arg2 = (switch_xml_t *) 0 ; + switch_event_t *arg3 = (switch_event_t *) 0 ; + switch_xml_t *arg4 = (switch_xml_t *) 0 ; + switch_xml_t *arg5 = (switch_xml_t *) 0 ; + switch_xml_t *arg6 = (switch_xml_t *) 0 ; + char *arg7 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_xml_t *)jarg1; + arg2 = (switch_xml_t *)jarg2; + arg3 = (switch_event_t *)jarg3; + arg4 = (switch_xml_t *)jarg4; + arg5 = (switch_xml_t *)jarg5; + arg6 = (switch_xml_t *)jarg6; + arg7 = (char *)jarg7; + result = (switch_status_t)switch_xml_locate_language(arg1,arg2,arg3,arg4,arg5,arg6,(char const *)arg7); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_io_event_hook_outgoing_channel_outgoing_channel_set(void * jarg1, void * jarg2) { switch_io_event_hook_outgoing_channel *arg1 = (switch_io_event_hook_outgoing_channel *) 0 ; switch_outgoing_channel_hook_t arg2 = (switch_outgoing_channel_hook_t) 0 ; diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 42ae909ebf..9a1f30fd9b 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -1409,6 +1409,11 @@ public class freeswitch { return ret; } + public static string switch_core_get_switchname() { + string ret = freeswitchPINVOKE.switch_core_get_switchname(); + return ret; + } + public static void switch_core_set_variable(string varname, string value) { freeswitchPINVOKE.switch_core_set_variable(varname, value); } @@ -2422,6 +2427,10 @@ public class freeswitch { return ret; } + public static void switch_core_set_signal_handlers() { + freeswitchPINVOKE.switch_core_set_signal_handlers(); + } + public static uint switch_core_debug_level() { uint ret = freeswitchPINVOKE.switch_core_debug_level(); return ret; @@ -2461,6 +2470,34 @@ public class freeswitch { return ret; } + public static string switch_say_file_handle_get_variable(SWIGTYPE_p_switch_say_file_handle sh, string var) { + string ret = freeswitchPINVOKE.switch_say_file_handle_get_variable(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh), var); + return ret; + } + + public static string switch_say_file_handle_get_path(SWIGTYPE_p_switch_say_file_handle sh) { + string ret = freeswitchPINVOKE.switch_say_file_handle_get_path(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh)); + return ret; + } + + public static string switch_say_file_handle_detach_path(SWIGTYPE_p_switch_say_file_handle sh) { + string ret = freeswitchPINVOKE.switch_say_file_handle_detach_path(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh)); + return ret; + } + + public static void switch_say_file_handle_destroy(SWIGTYPE_p_p_switch_say_file_handle sh) { + freeswitchPINVOKE.switch_say_file_handle_destroy(SWIGTYPE_p_p_switch_say_file_handle.getCPtr(sh)); + } + + public static switch_status_t switch_say_file_handle_create(SWIGTYPE_p_p_switch_say_file_handle sh, string ext, SWIGTYPE_p_p_switch_event var_event) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_say_file_handle_create(SWIGTYPE_p_p_switch_say_file_handle.getCPtr(sh), ext, SWIGTYPE_p_p_switch_event.getCPtr(var_event)); + return ret; + } + + public static void switch_say_file(SWIGTYPE_p_switch_say_file_handle sh, string fmt) { + freeswitchPINVOKE.switch_say_file(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh), fmt); + } + 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; @@ -2840,6 +2877,21 @@ public class freeswitch { return ret; } + public static switch_bool_t switch_is_number(string str) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_is_number(str); + return ret; + } + + public static int switch_true(string expr) { + int ret = freeswitchPINVOKE.switch_true(expr); + return ret; + } + + public static int switch_false(string expr) { + int ret = freeswitchPINVOKE.switch_false(expr); + return ret; + } + public static switch_status_t switch_resolve_host(string host, string buf, uint buflen) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_resolve_host(host, buf, buflen); return ret; @@ -2923,6 +2975,11 @@ public class freeswitch { return ret; } + public static string switch_clean_name_string(string s) { + string ret = freeswitchPINVOKE.switch_clean_name_string(s); + return ret; + } + public static string switch_safe_strdup(string it) { string ret = freeswitchPINVOKE.switch_safe_strdup(it); return ret; @@ -2958,11 +3015,6 @@ public class freeswitch { return ret; } - public static switch_bool_t switch_is_number(string str) { - switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_is_number(str); - return ret; - } - public static string switch_strip_spaces(string str, switch_bool_t dup) { string ret = freeswitchPINVOKE.switch_strip_spaces(str, (int)dup); return ret; @@ -3670,6 +3722,10 @@ public class freeswitch { return ret; } + public static void switch_channel_set_bridge_time(SWIGTYPE_p_switch_channel channel) { + freeswitchPINVOKE.switch_channel_set_bridge_time(SWIGTYPE_p_switch_channel.getCPtr(channel)); + } + public static void switch_channel_set_hangup_time(SWIGTYPE_p_switch_channel channel) { freeswitchPINVOKE.switch_channel_set_hangup_time(SWIGTYPE_p_switch_channel.getCPtr(channel)); } @@ -3723,6 +3779,11 @@ public class freeswitch { freeswitchPINVOKE.switch_channel_mark_hold(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)on); } + public static switch_status_t switch_channel_execute_on(SWIGTYPE_p_switch_channel channel, string variable_prefix) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_execute_on(SWIGTYPE_p_switch_channel.getCPtr(channel), variable_prefix); + return ret; + } + public static switch_status_t switch_buffer_create(SWIGTYPE_p_apr_pool_t pool, SWIGTYPE_p_p_switch_buffer buffer, SWIGTYPE_p_switch_size_t max_len) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_buffer_create(SWIGTYPE_p_apr_pool_t.getCPtr(pool), SWIGTYPE_p_p_switch_buffer.getCPtr(buffer), SWIGTYPE_p_switch_size_t.getCPtr(max_len)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -3943,8 +4004,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data); + public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data, (int)dup); return ret; } @@ -4519,6 +4580,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_say_string(SWIGTYPE_p_switch_core_session session, string lang, string ext, string tosay, string module_name, string say_type, string say_method, string say_gender, ref string rstr) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_say_string(SWIGTYPE_p_switch_core_session.getCPtr(session), lang, ext, tosay, module_name, say_type, say_method, say_gender, ref rstr); + return ret; + } + public static switch_say_method_t switch_ivr_get_say_method_by_name(string name) { switch_say_method_t ret = (switch_say_method_t)freeswitchPINVOKE.switch_ivr_get_say_method_by_name(name); return ret; @@ -5246,6 +5312,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_xml_locate_language(SWIGTYPE_p_p_switch_xml root, SWIGTYPE_p_p_switch_xml node, switch_event arg2, SWIGTYPE_p_p_switch_xml language, SWIGTYPE_p_p_switch_xml phrases, SWIGTYPE_p_p_switch_xml macros, string str_language) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_locate_language(SWIGTYPE_p_p_switch_xml.getCPtr(root), SWIGTYPE_p_p_switch_xml.getCPtr(node), switch_event.getCPtr(arg2), SWIGTYPE_p_p_switch_xml.getCPtr(language), SWIGTYPE_p_p_switch_xml.getCPtr(phrases), SWIGTYPE_p_p_switch_xml.getCPtr(macros), str_language); + return ret; + } + public static switch_status_t switch_core_event_hook_add_outgoing_channel(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_f_p_switch_core_session_p_switch_event_p_switch_caller_profile_p_switch_core_session_unsigned_long__switch_status_t outgoing_channel) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_event_hook_add_outgoing_channel(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_f_p_switch_core_session_p_switch_event_p_switch_caller_profile_p_switch_core_session_unsigned_long__switch_status_t.getCPtr(outgoing_channel)); return ret; @@ -5535,6 +5606,7 @@ public class freeswitch { public static readonly string SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get(); + public static readonly string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); public static readonly string SWITCH_CALL_TIMEOUT_VARIABLE = freeswitchPINVOKE.SWITCH_CALL_TIMEOUT_VARIABLE_get(); public static readonly string SWITCH_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_HOLDING_UUID_VARIABLE_get(); public static readonly string SWITCH_SOFT_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_SOFT_HOLDING_UUID_VARIABLE_get(); @@ -6086,6 +6158,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get")] public static extern string SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get")] + public static extern string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get")] public static extern string SWITCH_CALL_TIMEOUT_VARIABLE_get(); @@ -6920,6 +6995,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_gender_get")] public static extern int switch_say_args_t_gender_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_ext_set")] + public static extern void switch_say_args_t_ext_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_ext_get")] + public static extern string switch_say_args_t_ext_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_say_args_t")] public static extern IntPtr new_switch_say_args_t(); @@ -7640,6 +7721,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_hostname")] public static extern string switch_core_get_hostname(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_switchname")] + public static extern string switch_core_get_switchname(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_variable")] public static extern void switch_core_set_variable(string jarg1, string jarg2); @@ -8336,6 +8420,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute_trans")] public static extern int switch_cache_db_persistant_execute_trans(HandleRef jarg1, string jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_signal_handlers")] + public static extern void switch_core_set_signal_handlers(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_debug_level")] public static extern uint switch_core_debug_level(); @@ -8360,6 +8447,24 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_expire_registration")] public static extern int switch_core_expire_registration(int jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_get_variable")] + public static extern string switch_say_file_handle_get_variable(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_get_path")] + public static extern string switch_say_file_handle_get_path(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_detach_path")] + public static extern string switch_say_file_handle_detach_path(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_destroy")] + public static extern void switch_say_file_handle_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_create")] + public static extern int switch_say_file_handle_create(HandleRef jarg1, string jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file")] + public static extern void switch_say_file(HandleRef jarg1, string 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); @@ -8720,6 +8825,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_free")] public static extern int switch_frame_free(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_is_number")] + public static extern int switch_is_number(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_true")] + public static extern int switch_true(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_false")] + public static extern int switch_false(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_resolve_host")] public static extern int switch_resolve_host(string jarg1, string jarg2, uint jarg3); @@ -8768,6 +8882,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_string")] public static extern string switch_clean_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_name_string")] + public static extern string switch_clean_name_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_safe_strdup")] public static extern string switch_safe_strdup(string jarg1); @@ -8789,9 +8906,6 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_separate_string_string")] public static extern uint switch_separate_string_string(string jarg1, string jarg2, ref string jarg3, uint jarg4); - [DllImport("mod_managed", EntryPoint="CSharp_switch_is_number")] - public static extern int switch_is_number(string jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_strip_spaces")] public static extern string switch_strip_spaces(string jarg1, int jarg2); @@ -10550,6 +10664,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_function_get")] public static extern IntPtr switch_say_interface_say_function_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_string_function_set")] + public static extern void switch_say_interface_say_string_function_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_string_function_get")] + public static extern IntPtr switch_say_interface_say_string_function_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_rwlock_set")] public static extern void switch_say_interface_rwlock_set(HandleRef jarg1, HandleRef jarg2); @@ -11366,6 +11486,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_resurrected_get")] public static extern IntPtr switch_channel_timetable_resurrected_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_bridged_set")] + public static extern void switch_channel_timetable_bridged_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_bridged_get")] + public static extern IntPtr switch_channel_timetable_bridged_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_next_set")] public static extern void switch_channel_timetable_next_set(HandleRef jarg1, HandleRef jarg2); @@ -11675,6 +11801,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_app_flag_key")] public static extern int switch_channel_test_app_flag_key(string jarg1, HandleRef jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_bridge_time")] + public static extern void switch_channel_set_bridge_time(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_hangup_time")] public static extern void switch_channel_set_hangup_time(HandleRef jarg1); @@ -11708,6 +11837,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_mark_hold")] public static extern void switch_channel_mark_hold(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_execute_on")] + public static extern int switch_channel_execute_on(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")] public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -11949,7 +12081,7 @@ class freeswitchPINVOKE { public static extern int switch_event_create_json(HandleRef jarg1, string jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_brackets")] - public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6); + public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_running")] public static extern int switch_event_running(); @@ -12455,6 +12587,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_say")] public static extern int switch_ivr_say(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_say_string")] + public static extern int switch_ivr_say_string(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8, ref string jarg9); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_get_say_method_by_name")] public static extern int switch_ivr_get_say_method_by_name(string jarg1); @@ -12938,6 +13073,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_is_switch_xml_root_t_get")] public static extern int switch_xml_is_switch_xml_root_t_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_refs_set")] + public static extern void switch_xml_refs_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_refs_get")] + public static extern uint switch_xml_refs_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_xml")] public static extern IntPtr new_switch_xml(); @@ -13085,6 +13226,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_std_datetime_check")] public static extern int switch_xml_std_datetime_check(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_locate_language")] + public static extern int switch_xml_locate_language(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, HandleRef jarg5, HandleRef jarg6, string jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_event_hook_outgoing_channel_outgoing_channel_set")] public static extern void switch_io_event_hook_outgoing_channel_outgoing_channel_set(HandleRef jarg1, HandleRef jarg2); @@ -15309,6 +15453,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__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.1 + * + * 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_core_session_p_char_p_switch_say_args_t_p_switch_input_args_t__switch_status_t { private HandleRef swigCPtr; @@ -17889,6 +18063,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_say_file_handle { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_say_file_handle(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_say_file_handle() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_say_file_handle 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.1 + * + * 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_xml { private HandleRef swigCPtr; @@ -18909,6 +19113,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_say_file_handle { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_say_file_handle(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_say_file_handle() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_say_file_handle 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.1 + * + * 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_size_t { private HandleRef swigCPtr; @@ -21911,6 +22145,18 @@ public class switch_channel_timetable : IDisposable { } } + public SWIGTYPE_p_switch_time_t bridged { + set { + freeswitchPINVOKE.switch_channel_timetable_bridged_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_channel_timetable_bridged_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + public switch_channel_timetable next { set { freeswitchPINVOKE.switch_channel_timetable_next_set(swigCPtr, switch_channel_timetable.getCPtr(value)); @@ -23123,7 +23369,8 @@ namespace FreeSWITCH.Native { SCF_VERBOSE_EVENTS = (1 << 11), SCF_USE_WIN32_MONOTONIC = (1 << 12), SCF_AUTO_SCHEMAS = (1 << 13), - SCF_MINIMAL = (1 << 14) + SCF_MINIMAL = (1 << 14), + SCF_USE_NAT_MAPPING = (1 << 15) } } @@ -28791,7 +29038,7 @@ namespace FreeSWITCH.Native { SWITCH_RTP_FLAG_NOBLOCK = (1 << 0), SWITCH_RTP_FLAG_IO = (1 << 1), SWITCH_RTP_FLAG_USE_TIMER = (1 << 2), - SWITCH_RTP_FLAG_TIMER_RECLOCK = (1 << 3), + SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 3), SWITCH_RTP_FLAG_SECURE_SEND = (1 << 4), SWITCH_RTP_FLAG_SECURE_RECV = (1 << 5), SWITCH_RTP_FLAG_AUTOADJ = (1 << 6), @@ -28818,8 +29065,7 @@ namespace FreeSWITCH.Native { SWITCH_RTP_FLAG_DEBUG_RTP_READ = (1 << 27), SWITCH_RTP_FLAG_DEBUG_RTP_WRITE = (1 << 28), SWITCH_RTP_FLAG_VIDEO = (1 << 29), - SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30), - SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 31) + SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30) } } @@ -29291,6 +29537,16 @@ public class switch_say_args_t : IDisposable { } } + public string ext { + set { + freeswitchPINVOKE.switch_say_args_t_ext_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_say_args_t_ext_get(swigCPtr); + return ret; + } + } + public switch_say_args_t() : this(freeswitchPINVOKE.new_switch_say_args_t(), true) { } @@ -29378,6 +29634,17 @@ public class switch_say_interface : IDisposable { } } + public SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t say_string_function { + set { + freeswitchPINVOKE.switch_say_interface_say_string_function_set(swigCPtr, SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_say_interface_say_string_function_get(swigCPtr); + SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t(cPtr, false); + return ret; + } + } + public SWIGTYPE_p_switch_thread_rwlock_t rwlock { set { freeswitchPINVOKE.switch_say_interface_rwlock_set(swigCPtr, SWIGTYPE_p_switch_thread_rwlock_t.getCPtr(value)); @@ -31672,6 +31939,16 @@ public class switch_xml : IDisposable { } } + public uint refs { + set { + freeswitchPINVOKE.switch_xml_refs_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_xml_refs_get(swigCPtr); + return ret; + } + } + public switch_xml() : this(freeswitchPINVOKE.new_switch_xml(), true) { } diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 08e2e08e13..d06e9881d4 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -1399,6 +1399,11 @@ public class freeswitch { return ret; } + public static string switch_core_get_switchname() { + string ret = freeswitchPINVOKE.switch_core_get_switchname(); + return ret; + } + public static void switch_core_set_variable(string varname, string value) { freeswitchPINVOKE.switch_core_set_variable(varname, value); } @@ -2412,6 +2417,10 @@ public class freeswitch { return ret; } + public static void switch_core_set_signal_handlers() { + freeswitchPINVOKE.switch_core_set_signal_handlers(); + } + public static uint switch_core_debug_level() { uint ret = freeswitchPINVOKE.switch_core_debug_level(); return ret; @@ -2451,6 +2460,34 @@ public class freeswitch { return ret; } + public static string switch_say_file_handle_get_variable(SWIGTYPE_p_switch_say_file_handle sh, string var) { + string ret = freeswitchPINVOKE.switch_say_file_handle_get_variable(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh), var); + return ret; + } + + public static string switch_say_file_handle_get_path(SWIGTYPE_p_switch_say_file_handle sh) { + string ret = freeswitchPINVOKE.switch_say_file_handle_get_path(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh)); + return ret; + } + + public static string switch_say_file_handle_detach_path(SWIGTYPE_p_switch_say_file_handle sh) { + string ret = freeswitchPINVOKE.switch_say_file_handle_detach_path(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh)); + return ret; + } + + public static void switch_say_file_handle_destroy(SWIGTYPE_p_p_switch_say_file_handle sh) { + freeswitchPINVOKE.switch_say_file_handle_destroy(SWIGTYPE_p_p_switch_say_file_handle.getCPtr(sh)); + } + + public static switch_status_t switch_say_file_handle_create(SWIGTYPE_p_p_switch_say_file_handle sh, string ext, SWIGTYPE_p_p_switch_event var_event) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_say_file_handle_create(SWIGTYPE_p_p_switch_say_file_handle.getCPtr(sh), ext, SWIGTYPE_p_p_switch_event.getCPtr(var_event)); + return ret; + } + + public static void switch_say_file(SWIGTYPE_p_switch_say_file_handle sh, string fmt) { + freeswitchPINVOKE.switch_say_file(SWIGTYPE_p_switch_say_file_handle.getCPtr(sh), fmt); + } + 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; @@ -2830,6 +2867,21 @@ public class freeswitch { return ret; } + public static switch_bool_t switch_is_number(string str) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_is_number(str); + return ret; + } + + public static int switch_true(string expr) { + int ret = freeswitchPINVOKE.switch_true(expr); + return ret; + } + + public static int switch_false(string expr) { + int ret = freeswitchPINVOKE.switch_false(expr); + return ret; + } + public static switch_status_t switch_resolve_host(string host, string buf, uint buflen) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_resolve_host(host, buf, buflen); return ret; @@ -2913,6 +2965,11 @@ public class freeswitch { return ret; } + public static string switch_clean_name_string(string s) { + string ret = freeswitchPINVOKE.switch_clean_name_string(s); + return ret; + } + public static string switch_safe_strdup(string it) { string ret = freeswitchPINVOKE.switch_safe_strdup(it); return ret; @@ -2948,11 +3005,6 @@ public class freeswitch { return ret; } - public static switch_bool_t switch_is_number(string str) { - switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_is_number(str); - return ret; - } - public static string switch_strip_spaces(string str, switch_bool_t dup) { string ret = freeswitchPINVOKE.switch_strip_spaces(str, (int)dup); return ret; @@ -3660,6 +3712,10 @@ public class freeswitch { return ret; } + public static void switch_channel_set_bridge_time(SWIGTYPE_p_switch_channel channel) { + freeswitchPINVOKE.switch_channel_set_bridge_time(SWIGTYPE_p_switch_channel.getCPtr(channel)); + } + public static void switch_channel_set_hangup_time(SWIGTYPE_p_switch_channel channel) { freeswitchPINVOKE.switch_channel_set_hangup_time(SWIGTYPE_p_switch_channel.getCPtr(channel)); } @@ -3713,6 +3769,11 @@ public class freeswitch { freeswitchPINVOKE.switch_channel_mark_hold(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)on); } + public static switch_status_t switch_channel_execute_on(SWIGTYPE_p_switch_channel channel, string variable_prefix) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_execute_on(SWIGTYPE_p_switch_channel.getCPtr(channel), variable_prefix); + return ret; + } + public static switch_status_t switch_buffer_create(SWIGTYPE_p_apr_pool_t pool, SWIGTYPE_p_p_switch_buffer buffer, SWIGTYPE_p_switch_size_t max_len) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_buffer_create(SWIGTYPE_p_apr_pool_t.getCPtr(pool), SWIGTYPE_p_p_switch_buffer.getCPtr(buffer), SWIGTYPE_p_switch_size_t.getCPtr(max_len)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -3933,8 +3994,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data); + public static switch_status_t switch_event_create_brackets(string data, char a, char b, char c, SWIGTYPE_p_p_switch_event arg4, ref string new_data, switch_bool_t dup) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_brackets(data, a, b, c, SWIGTYPE_p_p_switch_event.getCPtr(arg4), ref new_data, (int)dup); return ret; } @@ -4509,6 +4570,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_say_string(SWIGTYPE_p_switch_core_session session, string lang, string ext, string tosay, string module_name, string say_type, string say_method, string say_gender, ref string rstr) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_say_string(SWIGTYPE_p_switch_core_session.getCPtr(session), lang, ext, tosay, module_name, say_type, say_method, say_gender, ref rstr); + return ret; + } + public static switch_say_method_t switch_ivr_get_say_method_by_name(string name) { switch_say_method_t ret = (switch_say_method_t)freeswitchPINVOKE.switch_ivr_get_say_method_by_name(name); return ret; @@ -5236,6 +5302,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_xml_locate_language(SWIGTYPE_p_p_switch_xml root, SWIGTYPE_p_p_switch_xml node, switch_event arg2, SWIGTYPE_p_p_switch_xml language, SWIGTYPE_p_p_switch_xml phrases, SWIGTYPE_p_p_switch_xml macros, string str_language) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_locate_language(SWIGTYPE_p_p_switch_xml.getCPtr(root), SWIGTYPE_p_p_switch_xml.getCPtr(node), switch_event.getCPtr(arg2), SWIGTYPE_p_p_switch_xml.getCPtr(language), SWIGTYPE_p_p_switch_xml.getCPtr(phrases), SWIGTYPE_p_p_switch_xml.getCPtr(macros), str_language); + return ret; + } + public static switch_status_t switch_core_event_hook_add_outgoing_channel(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_f_p_switch_core_session_p_switch_event_p_switch_caller_profile_p_switch_core_session_unsigned_long__switch_status_t outgoing_channel) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_event_hook_add_outgoing_channel(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_f_p_switch_core_session_p_switch_event_p_switch_caller_profile_p_switch_core_session_unsigned_long__switch_status_t.getCPtr(outgoing_channel)); return ret; @@ -5525,6 +5596,7 @@ public class freeswitch { public static readonly string SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE_get(); public static readonly string SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get(); + public static readonly string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE = freeswitchPINVOKE.SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); public static readonly string SWITCH_CALL_TIMEOUT_VARIABLE = freeswitchPINVOKE.SWITCH_CALL_TIMEOUT_VARIABLE_get(); public static readonly string SWITCH_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_HOLDING_UUID_VARIABLE_get(); public static readonly string SWITCH_SOFT_HOLDING_UUID_VARIABLE = freeswitchPINVOKE.SWITCH_SOFT_HOLDING_UUID_VARIABLE_get(); @@ -6072,6 +6144,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get")] public static extern string SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get")] + public static extern string SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CALL_TIMEOUT_VARIABLE_get")] public static extern string SWITCH_CALL_TIMEOUT_VARIABLE_get(); @@ -6522,6 +6597,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_numbers_t_flush_packet_count_get")] public static extern IntPtr switch_rtp_numbers_t_flush_packet_count_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_numbers_t_largest_jb_size_set")] + public static extern void switch_rtp_numbers_t_largest_jb_size_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_numbers_t_largest_jb_size_get")] + public static extern IntPtr switch_rtp_numbers_t_largest_jb_size_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_rtp_numbers_t")] public static extern IntPtr new_switch_rtp_numbers_t(); @@ -6906,6 +6987,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_gender_get")] public static extern int switch_say_args_t_gender_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_ext_set")] + public static extern void switch_say_args_t_ext_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_args_t_ext_get")] + public static extern string switch_say_args_t_ext_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_say_args_t")] public static extern IntPtr new_switch_say_args_t(); @@ -7626,6 +7713,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_hostname")] public static extern string switch_core_get_hostname(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_switchname")] + public static extern string switch_core_get_switchname(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_variable")] public static extern void switch_core_set_variable(string jarg1, string jarg2); @@ -8322,6 +8412,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_persistant_execute_trans")] public static extern int switch_cache_db_persistant_execute_trans(HandleRef jarg1, string jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_signal_handlers")] + public static extern void switch_core_set_signal_handlers(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_debug_level")] public static extern uint switch_core_debug_level(); @@ -8346,6 +8439,24 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_expire_registration")] public static extern int switch_core_expire_registration(int jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_get_variable")] + public static extern string switch_say_file_handle_get_variable(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_get_path")] + public static extern string switch_say_file_handle_get_path(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_detach_path")] + public static extern string switch_say_file_handle_detach_path(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_destroy")] + public static extern void switch_say_file_handle_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file_handle_create")] + public static extern int switch_say_file_handle_create(HandleRef jarg1, string jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_file")] + public static extern void switch_say_file(HandleRef jarg1, string 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); @@ -8706,6 +8817,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_free")] public static extern int switch_frame_free(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_is_number")] + public static extern int switch_is_number(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_true")] + public static extern int switch_true(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_false")] + public static extern int switch_false(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_resolve_host")] public static extern int switch_resolve_host(string jarg1, string jarg2, uint jarg3); @@ -8754,6 +8874,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_string")] public static extern string switch_clean_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_clean_name_string")] + public static extern string switch_clean_name_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_safe_strdup")] public static extern string switch_safe_strdup(string jarg1); @@ -8775,9 +8898,6 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_separate_string_string")] public static extern uint switch_separate_string_string(string jarg1, string jarg2, ref string jarg3, uint jarg4); - [DllImport("mod_managed", EntryPoint="CSharp_switch_is_number")] - public static extern int switch_is_number(string jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_strip_spaces")] public static extern string switch_strip_spaces(string jarg1, int jarg2); @@ -10536,6 +10656,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_function_get")] public static extern IntPtr switch_say_interface_say_function_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_string_function_set")] + public static extern void switch_say_interface_say_string_function_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_say_string_function_get")] + public static extern IntPtr switch_say_interface_say_string_function_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_say_interface_rwlock_set")] public static extern void switch_say_interface_rwlock_set(HandleRef jarg1, HandleRef jarg2); @@ -11352,6 +11478,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_resurrected_get")] public static extern IntPtr switch_channel_timetable_resurrected_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_bridged_set")] + public static extern void switch_channel_timetable_bridged_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_bridged_get")] + public static extern IntPtr switch_channel_timetable_bridged_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_next_set")] public static extern void switch_channel_timetable_next_set(HandleRef jarg1, HandleRef jarg2); @@ -11661,6 +11793,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_app_flag_key")] public static extern int switch_channel_test_app_flag_key(string jarg1, HandleRef jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_bridge_time")] + public static extern void switch_channel_set_bridge_time(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_hangup_time")] public static extern void switch_channel_set_hangup_time(HandleRef jarg1); @@ -11694,6 +11829,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_mark_hold")] public static extern void switch_channel_mark_hold(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_execute_on")] + public static extern int switch_channel_execute_on(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")] public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -11935,7 +12073,7 @@ class freeswitchPINVOKE { public static extern int switch_event_create_json(HandleRef jarg1, string jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_brackets")] - public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6); + public static extern int switch_event_create_brackets(string jarg1, char jarg2, char jarg3, char jarg4, HandleRef jarg5, ref string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_switch_event_running")] public static extern int switch_event_running(); @@ -12441,6 +12579,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_say")] public static extern int switch_ivr_say(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_say_string")] + public static extern int switch_ivr_say_string(HandleRef jarg1, string jarg2, string jarg3, string jarg4, string jarg5, string jarg6, string jarg7, string jarg8, ref string jarg9); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_get_say_method_by_name")] public static extern int switch_ivr_get_say_method_by_name(string jarg1); @@ -12924,6 +13065,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_is_switch_xml_root_t_get")] public static extern int switch_xml_is_switch_xml_root_t_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_refs_set")] + public static extern void switch_xml_refs_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_refs_get")] + public static extern uint switch_xml_refs_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_xml")] public static extern IntPtr new_switch_xml(); @@ -13071,6 +13218,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_std_datetime_check")] public static extern int switch_xml_std_datetime_check(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_locate_language")] + public static extern int switch_xml_locate_language(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, HandleRef jarg5, HandleRef jarg6, string jarg7); + [DllImport("mod_managed", EntryPoint="CSharp_switch_io_event_hook_outgoing_channel_outgoing_channel_set")] public static extern void switch_io_event_hook_outgoing_channel_outgoing_channel_set(HandleRef jarg1, HandleRef jarg2); @@ -15285,6 +15435,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__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_core_session_p_char_p_switch_say_args_t_p_switch_input_args_t__switch_status_t { private HandleRef swigCPtr; @@ -17835,6 +18015,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_say_file_handle { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_say_file_handle(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_say_file_handle() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_say_file_handle 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_xml_binding { private HandleRef swigCPtr; @@ -18885,6 +19095,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_say_file_handle { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_say_file_handle(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_say_file_handle() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_say_file_handle 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_size_t { private HandleRef swigCPtr; @@ -21857,6 +22097,18 @@ public class switch_channel_timetable : IDisposable { } } + public SWIGTYPE_p_switch_time_t bridged { + set { + freeswitchPINVOKE.switch_channel_timetable_bridged_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_channel_timetable_bridged_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + public switch_channel_timetable next { set { freeswitchPINVOKE.switch_channel_timetable_next_set(swigCPtr, switch_channel_timetable.getCPtr(value)); @@ -23051,7 +23303,8 @@ namespace FreeSWITCH.Native { SCF_VERBOSE_EVENTS = (1 << 11), SCF_USE_WIN32_MONOTONIC = (1 << 12), SCF_AUTO_SCHEMAS = (1 << 13), - SCF_MINIMAL = (1 << 14) + SCF_MINIMAL = (1 << 14), + SCF_USE_NAT_MAPPING = (1 << 15) } } @@ -28641,7 +28894,7 @@ namespace FreeSWITCH.Native { SWITCH_RTP_FLAG_NOBLOCK = (1 << 0), SWITCH_RTP_FLAG_IO = (1 << 1), SWITCH_RTP_FLAG_USE_TIMER = (1 << 2), - SWITCH_RTP_FLAG_TIMER_RECLOCK = (1 << 3), + SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 3), SWITCH_RTP_FLAG_SECURE_SEND = (1 << 4), SWITCH_RTP_FLAG_SECURE_RECV = (1 << 5), SWITCH_RTP_FLAG_AUTOADJ = (1 << 6), @@ -28668,8 +28921,7 @@ namespace FreeSWITCH.Native { SWITCH_RTP_FLAG_DEBUG_RTP_READ = (1 << 27), SWITCH_RTP_FLAG_DEBUG_RTP_WRITE = (1 << 28), SWITCH_RTP_FLAG_VIDEO = (1 << 29), - SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30), - SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 31) + SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30) } } @@ -28976,6 +29228,18 @@ public class switch_rtp_numbers_t : IDisposable { } } + public SWIGTYPE_p_switch_size_t largest_jb_size { + set { + freeswitchPINVOKE.switch_rtp_numbers_t_largest_jb_size_set(swigCPtr, SWIGTYPE_p_switch_size_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_rtp_numbers_t_largest_jb_size_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + public switch_rtp_numbers_t() : this(freeswitchPINVOKE.new_switch_rtp_numbers_t(), true) { } @@ -29133,6 +29397,16 @@ public class switch_say_args_t : IDisposable { } } + public string ext { + set { + freeswitchPINVOKE.switch_say_args_t_ext_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_say_args_t_ext_get(swigCPtr); + return ret; + } + } + public switch_say_args_t() : this(freeswitchPINVOKE.new_switch_say_args_t(), true) { } @@ -29218,6 +29492,17 @@ public class switch_say_interface : IDisposable { } } + public SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t say_string_function { + set { + freeswitchPINVOKE.switch_say_interface_say_string_function_set(swigCPtr, SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_say_interface_say_string_function_get(swigCPtr); + SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session_p_char_p_switch_say_args_t_p_p_char__switch_status_t(cPtr, false); + return ret; + } + } + public SWIGTYPE_p_switch_thread_rwlock_t rwlock { set { freeswitchPINVOKE.switch_say_interface_rwlock_set(swigCPtr, SWIGTYPE_p_switch_thread_rwlock_t.getCPtr(value)); @@ -31490,6 +31775,16 @@ public class switch_xml : IDisposable { } } + public uint refs { + set { + freeswitchPINVOKE.switch_xml_refs_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_xml_refs_get(swigCPtr); + return ret; + } + } + public switch_xml() : this(freeswitchPINVOKE.new_switch_xml(), true) { } diff --git a/src/mod/languages/mod_python/mod_python.c b/src/mod/languages/mod_python/mod_python.c index bcaebd8856..78caf3b04f 100644 --- a/src/mod/languages/mod_python/mod_python.c +++ b/src/mod/languages/mod_python/mod_python.c @@ -77,13 +77,11 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi char *dupargs = NULL; char *argv[2] = { 0 }; int argc; - int lead = 0; char *script = NULL; PyObject *module = NULL, *sp = NULL, *stp = NULL, *eve = NULL; PyObject *function = NULL; PyObject *arg = NULL; PyObject *result = NULL; - switch_channel_t *channel = NULL; char *p; if (str) { @@ -105,8 +103,6 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi script = strdup(switch_str_nil(argv[0])); - lead = 1; - if ((p = strstr(script, "::"))) { *p = '\0'; p += 2; @@ -157,7 +153,6 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi } if (session) { - channel = switch_core_session_get_channel(session); sp = mod_python_conjure_session(module, session); } diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 1a57f5f2ae..a09cfdf02a 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -35,7 +35,7 @@ #include "mod_spidermonkey.h" #ifdef HAVE_CURL -#include +#include #endif static int foo = 0; static jsval check_hangup_hook(struct js_session *jss, jsval * rp); @@ -766,11 +766,8 @@ static JSBool dtmf_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * { switch_dtmf_t *dtmf; int32 duration = switch_core_default_dtmf_duration(0); - char *ename; - if (argc > 0) { - ename = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); - } else { + if (argc <= 0) { eval_some_js("~throw new Error(\"Invalid Args\");", cx, obj, rval); return JS_FALSE; } @@ -1911,7 +1908,6 @@ static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval * char *tts_name = NULL; char *voice_name = NULL; char *text = NULL; - switch_codec_t *codec; void *bp = NULL; int len = 0; struct input_callback_state cb_state = { 0 }; @@ -1979,7 +1975,6 @@ static JSBool session_speak(JSContext * cx, JSObject * obj, uintN argc, jsval * } } - codec = switch_core_session_get_read_codec(jss->session); cb_state.ret = BOOLEAN_TO_JSVAL(JS_FALSE); cb_state.saveDepth = JS_SuspendRequest(cx); args.input_callback = dtmf_func; @@ -2281,13 +2276,12 @@ static JSBool session_detach(JSContext * cx, JSObject * obj, uintN argc, jsval * static JSBool session_execute(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { JSBool retval = JS_FALSE; - switch_channel_t *channel; + struct js_session *jss = JS_GetPrivate(cx, obj); jsval ret = JS_TRUE; METHOD_SANITY_CHECK(); - channel = switch_core_session_get_channel(jss->session); /* you can execute some apps before you answer CHANNEL_SANITY_CHECK(); */ if (argc > 0) { @@ -2557,7 +2551,6 @@ static JSBool js_fetchurl_file(JSContext * cx, JSObject * obj, uintN argc, jsval url = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); filename = JS_GetStringBytes(JS_ValueToString(cx, argv[1])); - curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); if (!strncasecmp(url, "https", 5)) { curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); @@ -2606,7 +2599,6 @@ static JSBool js_fetchurl(JSContext * cx, JSObject * obj, uintN argc, jsval * ar JS_ValueToInt32(cx, argv[1], &buffer_size); } - curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); if (!strncasecmp(url, "https", 5)) { curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0); @@ -3498,7 +3490,6 @@ static JSBool js_bridge(JSContext * cx, JSObject * obj, uintN argc, jsval * argv struct js_session *jss_a = NULL, *jss_b = NULL; JSObject *session_obj_a = NULL, *session_obj_b = NULL; void *bp = NULL; - int len = 0; switch_input_callback_function_t dtmf_func = NULL; struct input_callback_state cb_state = { 0 }; JSFunction *function; @@ -3548,7 +3539,6 @@ static JSBool js_bridge(JSContext * cx, JSObject * obj, uintN argc, jsval * argv cb_state.session_state = jss_a; dtmf_func = js_collect_input_callback; bp = &cb_state; - len = sizeof(cb_state); } } @@ -3811,7 +3801,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load) SWITCH_ADD_APP(app_interface, "javascript", "Launch JS ivr", "Run a javascript ivr on a channel", js_dp_function, "