diff --git a/Freeswitch.2008.sln b/Freeswitch.2008.sln index d87a7ecfa7..27c94a2dc4 100644 --- a/Freeswitch.2008.sln +++ b/Freeswitch.2008.sln @@ -1277,11 +1277,9 @@ Global {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|Win32.ActiveCfg = Debug|Win32 {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|Win32.Build.0 = Debug|Win32 {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|x64.ActiveCfg = Debug|x64 - {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|x64.Build.0 = Debug|x64 {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|Win32.ActiveCfg = Release|Win32 {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|Win32.Build.0 = Release|Win32 {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64.ActiveCfg = Release|x64 - {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64.Build.0 = Release|x64 {692F6330-4D87-4C82-81DF-40DB5892636E}.All|Win32.ActiveCfg = Release|x64 {692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.ActiveCfg = Release|x64 {692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.Build.0 = Release|x64 @@ -1593,22 +1591,18 @@ Global {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|Win32.ActiveCfg = Debug|Win32 {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|Win32.Build.0 = Debug|Win32 {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|x64.ActiveCfg = Debug|x64 - {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|x64.Build.0 = Debug|x64 {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|Win32.ActiveCfg = Release|Win32 {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|Win32.Build.0 = Release|Win32 {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|x64.ActiveCfg = Release|x64 - {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|x64.Build.0 = Release|x64 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|Win32.ActiveCfg = Release|x64 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|x64.ActiveCfg = Release|x64 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|x64.Build.0 = Release|x64 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|Win32.ActiveCfg = Debug|Win32 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|Win32.Build.0 = Debug|Win32 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|x64.ActiveCfg = Debug|x64 - {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|x64.Build.0 = Debug|x64 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|Win32.ActiveCfg = Release|Win32 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|Win32.Build.0 = Release|Win32 {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|x64.ActiveCfg = Release|x64 - {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|x64.Build.0 = Release|x64 {4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|Win32.ActiveCfg = Release|x64 {4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|x64.ActiveCfg = Release|x64 {4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|x64.Build.0 = Release|x64 @@ -1637,11 +1631,9 @@ Global {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|Win32.ActiveCfg = Debug|Win32 {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|Win32.Build.0 = Debug|Win32 {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|x64.ActiveCfg = Debug|x64 - {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|x64.Build.0 = Debug|x64 {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|Win32.ActiveCfg = Release|Win32 {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|Win32.Build.0 = Release|Win32 {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|x64.ActiveCfg = Release|x64 - {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|x64.Build.0 = Release|x64 {AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|Win32.ActiveCfg = Release|x64 {AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|x64.ActiveCfg = Release|x64 {AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|x64.Build.0 = Release|x64 @@ -1736,11 +1728,9 @@ Global {028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|Win32.ActiveCfg = Debug|Win32 {028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|Win32.Build.0 = Debug|Win32 {028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|x64.ActiveCfg = Debug|x64 - {028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|x64.Build.0 = Debug|x64 {028C7278-05D7-4E18-82FE-BE231B844F41}.Release|Win32.ActiveCfg = Release|Win32 {028C7278-05D7-4E18-82FE-BE231B844F41}.Release|Win32.Build.0 = Release|Win32 {028C7278-05D7-4E18-82FE-BE231B844F41}.Release|x64.ActiveCfg = Release|x64 - {028C7278-05D7-4E18-82FE-BE231B844F41}.Release|x64.Build.0 = Release|x64 {D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|Win32.ActiveCfg = Release|x64 {D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|x64.ActiveCfg = Release|x64 {D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|x64.Build.0 = Release|x64 @@ -1901,11 +1891,9 @@ Global {36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|Win32.ActiveCfg = Debug|Win32 {36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|Win32.Build.0 = Debug|Win32 {36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|x64.ActiveCfg = Debug|x64 - {36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|x64.Build.0 = Debug|x64 {36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|Win32.ActiveCfg = Release|Win32 {36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|Win32.Build.0 = Release|Win32 {36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|x64.ActiveCfg = Release|x64 - {36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|x64.Build.0 = Release|x64 {7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|Win32.ActiveCfg = Release|x64 {7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|x64.ActiveCfg = Release|x64 {7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|x64.Build.0 = Release|x64 diff --git a/Makefile.am b/Makefile.am index a26346277a..ad04fde392 100644 --- a/Makefile.am +++ b/Makefile.am @@ -267,7 +267,7 @@ src/include/switch_swigable_cpp.h: $(switch_srcdir)/src/include/switch_cpp.h ## ## Applications ## -bin_PROGRAMS = freeswitch fs_cli fs_ivrd +bin_PROGRAMS = freeswitch fs_cli fs_ivrd tone2wav ## ## fs_cli () @@ -281,6 +281,14 @@ fs_cli_CFLAGS += -DHAVE_EDITLINE -I$(switch_srcdir)/libs/libedit/src fs_cli_LDADD = libs/libedit/src/.libs/libedit.a endif +## +## tone2wav () +## +tone2wav_SOURCES = src/tone2wav.c +tone2wav_CFLAGS = $(AM_CFLAGS) +tone2wav_LDFLAGS = $(AM_LDFLAGS) $(CORE_LIBS) +tone2wav_LDADD = libfreeswitch.la + ## ## fs_ivrd () ## diff --git a/bootstrap.sh b/bootstrap.sh index 0ea5cd43d4..4e65c5ca15 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -16,7 +16,7 @@ done BASEDIR=`pwd`; LIBDIR=${BASEDIR}/libs; SUBDIRS="ilbc curl iksemel js js/nsprpub libdingaling libedit libsndfile pcre sofia-sip \ - speex sqlite srtp openzap freetdm spandsp libg722_1 portaudio unimrcp tiff-3.8.2 broadvoice silk"; + speex sqlite srtp openzap freetdm spandsp libg722_1 portaudio unimrcp tiff-3.8.2 broadvoice silk libcodec2"; if [ ! -f modules.conf ]; then cp build/modules.conf.in modules.conf diff --git a/build/modules.conf.in b/build/modules.conf.in index 7730cf2a94..67e1fe62ae 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -39,6 +39,7 @@ codecs/mod_g723_1 codecs/mod_amr #codecs/mod_amrwb #codecs/mod_silk +#codecs/mod_codec2 codecs/mod_g729 codecs/mod_h26x codecs/mod_bv diff --git a/conf/autoload_configs/callcenter.conf.xml b/conf/autoload_configs/callcenter.conf.xml index e764d17f15..117839146c 100644 --- a/conf/autoload_configs/callcenter.conf.xml +++ b/conf/autoload_configs/callcenter.conf.xml @@ -22,15 +22,15 @@ </queues> -<!-- WARNING : Configuring XML Agents will updated into the DB upon restart --> -<!-- WARNING : Configuring XML Tiers will reset the provided level and position if provided.--> -<!-- WARNING : Agents and Tiers XML config shouldn't be used in a multi FS shared DB setup(Not currently supported anyway) --> +<!-- WARNING: Configuration of XML Agents will be updated into the DB upon restart. --> +<!-- WARNING: Configuration of XML Tiers will reset the level and position if those were supplied. --> +<!-- WARNING: Agents and Tiers XML config shouldn't be used in a multi FS shared DB setup (Not currently supported anyway) --> <agents> <!--<agent name="1000@default" type="callback" contact="[call_timeout=10]user/1000@default" status="Available" max-no-answer="3" wrap-up-time="10" reject-delay-time="10" busy-delay-time="60" />--> </agents> <tiers> - <!-- if no level or position is provided, they will default to 0. You should do this to keep db value on restart --> - <!-- <tier agent="1000@default" queue="support@default" level="0" position="1"/> --> + <!-- If no level or position is provided, they will default to 1. You should do this to keep db value on restart. --> + <!-- <tier agent="1000@default" queue="support@default" level="1" position="1"/> --> </tiers> </configuration> diff --git a/conf/autoload_configs/sangoma_codec.conf.xml b/conf/autoload_configs/sangoma_codec.conf.xml index da4b8ed643..05d70de0a7 100644 --- a/conf/autoload_configs/sangoma_codec.conf.xml +++ b/conf/autoload_configs/sangoma_codec.conf.xml @@ -8,25 +8,29 @@ <param name="register" value="all"/> --> - <!-- List of codecs to not register with FreeSWITCH, by default this is empty, + <!-- + List of codecs to not register with FreeSWITCH, by default this is empty, but you may want to not load PCMU and PCMA or may be others to not use your vocallo resources in codecs that are done well and fast in software. <param name="noregister" value="PCMU,PCMA"/> --> + + <!-- + Transcoding SOAP server URL. If you are installing the soap server (sngtc_server) + in the same box where FreeSWITCH, do not use this value, the default URL + that is hard-coded will work out of the box for local installations. + If you modify this value, you must configure your SOAP server (/etc/sngtc/sngtc_server.conf.xml) + to listen for HTTP requests on the same IP/port that you specify here. + <param name="soapserver" value="http://192.168.1.100:8080"/> + --> + + <!-- + RTP IP to use + By default, this module asks FreeSWITCH for the local ip address. However if you want to use a specific + IP address you can set it here. + <param name="rtpip" value="192.168.1.1"/> + --> </settings> - <vocallos> - - <!-- The name of the vocallo is the ethernet device name as displayed by ifconfig --> - <vocallo name="eth5"> - <!-- Starting UDP port for the vocallo --> - <param name="baseudp" value="5000"/> - <!-- Starting IP address to use for the vocallo modules --> - <param name="vocalloaddr" value="10.1.1.100"/> - </vocallo> - - </vocallos> - - </configuration> diff --git a/conf/dialplan/default.xml b/conf/dialplan/default.xml index 8abb8d8348..8bdcfa0da2 100644 --- a/conf/dialplan/default.xml +++ b/conf/dialplan/default.xml @@ -240,7 +240,7 @@ <!-- dial the extension (1000-1019) for 30 seconds and go to voicemail if the call fails (continue_on_fail=true), otherwise hang up after a successful - bridge (hangup_after-bridge=true) + bridge (hangup_after_bridge=true) --> <extension name="Local_Extension"> <condition field="destination_number" expression="^(10[01][0-9])$"> @@ -250,6 +250,7 @@ <action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/> <action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/> <action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/> + <action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/> <action application="set" data="ringback=${us-ring}"/> <action application="set" data="transfer_ringback=$${hold_music}"/> <action application="set" data="call_timeout=30"/> @@ -262,7 +263,7 @@ <action application="set" data="called_party_callgroup=${user_data(${dialed_extension}@${domain_name} var callgroup)}"/> <!--<action application="export" data="nolocal:sip_secure_media=${user_data(${dialed_extension}@${domain_name} var sip_secure_media)}"/>--> <action application="hash" data="insert/${domain_name}-last_dial/${called_party_callgroup}/${uuid}"/> - <action application="bridge" data="user/${dialed_extension}@${domain_name}"/> + <action application="bridge" data="{sip_invite_domain=$${domain}}user/${dialed_extension}@${domain_name}"/> <action application="answer"/> <action application="sleep" data="1000"/> <action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/> diff --git a/conf/dialplan/features.xml b/conf/dialplan/features.xml index 901b3091b7..b85cadc5f7 100644 --- a/conf/dialplan/features.xml +++ b/conf/dialplan/features.xml @@ -11,6 +11,14 @@ </condition> </extension> + <extension name="att_xfer"> + <condition field="destination_number" expression="^att_xfer$"> + <action application="read" data="3 4 'tone_stream://%(10000,0,350,440)' digits 30000 #"/> + <action application="set" data="origination_cancel_key=#"/> + <action application="att_xfer" data="user/${digits}@$${domain}"/> + </condition> + </extension> + <extension name="is_transfer"> <condition field="destination_number" expression="^is_transfer$"/> <condition field="${digits}" expression="^(\d+)$"> diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml index e4af5cc772..50833bfbec 100644 --- a/conf/sip_profiles/internal.xml +++ b/conf/sip_profiles/internal.xml @@ -116,7 +116,7 @@ <!-- used to share presence info across sofia profiles --> <!-- Name of the db to use for this profile --> <!--<param name="dbname" value="share_presence"/>--> - <!--<param name="presence-hosts" value="$${domain}"/>--> + <param name="presence-hosts" value="$${domain},$${local_ip_v4}"/> <!-- ************************************************* --> <!-- This setting is for AAL2 bitpacking on G726 --> @@ -226,6 +226,8 @@ <!--all inbound reg will stored in the db using this domain --> <param name="force-register-db-domain" value="$${domain}"/> + <!--<param name="delete-subs-on-register" value="false"/>--> + <!-- enable rtcp on every channel also can be done per leg basis with rtcp_audio_interval_msec variable set to passthru to pass it across a call--> <!--<param name="rtcp-audio-interval-msec" value="5000"/>--> <!--<param name="rtcp-video-interval-msec" value="5000"/>--> diff --git a/configure.in b/configure.in index e8b462f54a..de7261266e 100644 --- a/configure.in +++ b/configure.in @@ -904,6 +904,7 @@ AC_CONFIG_FILES([Makefile src/mod/applications/mod_expr/Makefile src/mod/applications/mod_fax/Makefile src/mod/applications/mod_spandsp/Makefile + src/mod/applications/mod_osp/Makefile src/mod/applications/mod_stress/Makefile src/mod/applications/mod_hash/Makefile src/mod/endpoints/mod_portaudio/Makefile @@ -998,6 +999,7 @@ AC_CONFIG_SUBDIRS([libs/spandsp]) AC_CONFIG_SUBDIRS([libs/broadvoice]) AC_CONFIG_SUBDIRS([libs/libg722_1]) AC_CONFIG_SUBDIRS([libs/silk]) +AC_CONFIG_SUBDIRS([libs/libcodec2]) case $host in *-openbsd*) diff --git a/debian/changelog b/debian/changelog index 2aa9e75555..7f4e8d7749 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +freeswitch (1.0.6-1ubuntu1) maverick; urgency=low + + [ Gabriel Gunderson ] + * upgrade: Added mod_callcenter and pulled out Python into its own + package. + + [ Mathieu Parent ] + * Updated Uploaders list + * Updated Standards-Version to 3.9.1 + + -- Mathieu Parent <sathieu@debian.org> Thu, 23 Sep 2010 15:34:00 +0200 + freeswitch (1.0.4-1ubuntu2) karmic; urgency=low * upgrade: Add more verbosity when building to make it easier to find build diff --git a/debian/control b/debian/control index 8e52e3d6c1..92b4e6ada5 100644 --- a/debian/control +++ b/debian/control @@ -1,10 +1,11 @@ Source: freeswitch Section: comm Priority: extra -Maintainer: Michal Bielicki <michal.bielicki@voiceworks.pl> -Build-Depends: debhelper (>= 5), fakeroot, wget, automake (>=1.9), autoconf, libtool, unixodbc-dev, libasound2-dev, libcurl3-openssl-dev|libcurl4-openssl-dev, libssl-dev, ncurses-dev, libogg-dev, libvorbis-dev, libperl-dev, libgdbm-dev, libdb-dev, libgnutls-dev, libtiff4-dev, python, libx11-dev, uuid-dev +Maintainer: FreeSWITCH developers <freeswitch-dev@lists.freeswitch.org> +Uploaders: Michal Bielicki <michal.bielicki@voiceworks.pl>, Gabriel Gunderson <gabe@gundy.org>, William King <quentusrex@gmail.com>, Mathieu Parent <sathieu@debian.org> +Build-Depends: debhelper (>= 5), fakeroot, wget, automake (>=1.9), autoconf, libtool, unixodbc-dev, libasound2-dev, libcurl3-openssl-dev|libcurl4-openssl-dev, libssl-dev, ncurses-dev, libogg-dev, libvorbis-dev, libperl-dev, libgdbm-dev, libdb-dev, libgnutls-dev, libtiff4-dev, python-dev, libx11-dev, uuid-dev Homepage: http://freeswitch.org/ -Standards-Version: 3.8.4 +Standards-Version: 3.9.1 Vcs-Svn: http://svn.freeswitch.org/svn/freeswitch/trunk/ Vcs-Browser: http://fisheye.freeswitch.org/browse/FreeSWITCH @@ -86,6 +87,18 @@ Description: Lua engine for FreeSWITCH . This package contains the mod_lua language module. +Package: freeswitch-python +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, freeswitch +Description: Python engine for FreeSWITCH + FreeSWITCH is an open source telephony platform designed to facilitate the + creation of voice and chat driven products scaling from a soft-phone up to a + soft-switch. It can be used as a simple switching engine, a PBX, a media + gateway or a media server to host IVR applications using simple scripts or XML + to control the callflow. + . + This package contains the mod_python language module. + Package: freeswitch-codec-passthru-g7231 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, freeswitch diff --git a/debian/freeswitch.conffiles b/debian/freeswitch.conffiles index 342ec5fc02..a6f9ce380f 100644 --- a/debian/freeswitch.conffiles +++ b/debian/freeswitch.conffiles @@ -1,5 +1,6 @@ /opt/freeswitch/conf/autoload_configs/acl.conf.xml /opt/freeswitch/conf/autoload_configs/alsa.conf.xml +/opt/freeswitch/conf/autoload_configs/callcenter.conf.xml /opt/freeswitch/conf/autoload_configs/cdr_csv.conf.xml /opt/freeswitch/conf/autoload_configs/cidlookup.conf.xml /opt/freeswitch/conf/autoload_configs/conference.conf.xml @@ -26,7 +27,6 @@ /opt/freeswitch/conf/autoload_configs/pocketsphinx.conf.xml /opt/freeswitch/conf/autoload_configs/portaudio.conf.xml /opt/freeswitch/conf/autoload_configs/post_load_modules.conf.xml -/opt/freeswitch/conf/autoload_configs/python.conf.xml /opt/freeswitch/conf/autoload_configs/rss.conf.xml /opt/freeswitch/conf/autoload_configs/shout.conf.xml /opt/freeswitch/conf/autoload_configs/skinny.conf.xml @@ -43,7 +43,6 @@ /opt/freeswitch/conf/autoload_configs/zeroconf.conf.xml /opt/freeswitch/conf/dialplan/default/00_pizza_demo.xml /opt/freeswitch/conf/dialplan/default/01_example.com.xml -/opt/freeswitch/conf/dialplan/default/99999_enum.xml /opt/freeswitch/conf/dialplan/default.xml /opt/freeswitch/conf/dialplan/features.xml /opt/freeswitch/conf/dialplan/public/00_inbound_did.xml diff --git a/debian/freeswitch.install b/debian/freeswitch.install index 0bf0c156e7..087d167859 100644 --- a/debian/freeswitch.install +++ b/debian/freeswitch.install @@ -6,6 +6,7 @@ opt/freeswitch/bin/gentls_cert opt/freeswitch/bin/scripts/* opt/freeswitch/conf/autoload_configs/acl.conf.xml opt/freeswitch/conf/autoload_configs/alsa.conf.xml +opt/freeswitch/conf/autoload_configs/callcenter.conf.xml opt/freeswitch/conf/autoload_configs/cdr_csv.conf.xml opt/freeswitch/conf/autoload_configs/cidlookup.conf.xml opt/freeswitch/conf/autoload_configs/conference.conf.xml @@ -34,7 +35,6 @@ opt/freeswitch/conf/autoload_configs/openzap.conf.xml opt/freeswitch/conf/autoload_configs/pocketsphinx.conf.xml opt/freeswitch/conf/autoload_configs/portaudio.conf.xml opt/freeswitch/conf/autoload_configs/post_load_modules.conf.xml -opt/freeswitch/conf/autoload_configs/python.conf.xml opt/freeswitch/conf/autoload_configs/rss.conf.xml opt/freeswitch/conf/autoload_configs/shout.conf.xml opt/freeswitch/conf/autoload_configs/skinny.conf.xml @@ -51,7 +51,6 @@ opt/freeswitch/conf/autoload_configs/xml_rpc.conf.xml opt/freeswitch/conf/autoload_configs/zeroconf.conf.xml opt/freeswitch/conf/dialplan/default/00_pizza_demo.xml opt/freeswitch/conf/dialplan/default/01_example.com.xml -opt/freeswitch/conf/dialplan/default/99999_enum.xml opt/freeswitch/conf/dialplan/default.xml opt/freeswitch/conf/dialplan/features.xml opt/freeswitch/conf/dialplan/public/00_inbound_did.xml @@ -113,6 +112,7 @@ opt/freeswitch/conf/zt.conf opt/freeswitch/htdocs/* opt/freeswitch/lib/libfreeswitch*.so* opt/freeswitch/lib/libopenzap*.so* +opt/freeswitch/mod/mod_callcenter.so* opt/freeswitch/mod/mod_cdr_csv.so* opt/freeswitch/mod/mod_celt.so* opt/freeswitch/mod/mod_cidlookup.so* diff --git a/debian/rules b/debian/rules index 05ab4c1bc4..114ad64f34 100755 --- a/debian/rules +++ b/debian/rules @@ -13,7 +13,7 @@ export APPLICATIONS_MODULES=applications/mod_cluechoo applications/mod_commands applications/mod_hash applications/mod_db applications/mod_valet_parking applications/mod_voicemail applications/mod_rss \ applications/mod_spandsp applications/mod_cidlookup applications/mod_curl applications/mod_easyroute \ applications/mod_lcr applications/mod_nibblebill applications/mod_snom \ - applications/mod_spy applications/mod_vmd applications/mod_directory + applications/mod_spy applications/mod_vmd applications/mod_directory applications/mod_callcenter export ASR_TTS_MODULES=asr_tts/mod_tts_commandline export CODECS_MODULES=codecs/mod_ilbc codecs/mod_h26x codecs/mod_speex codecs/mod_siren codecs/mod_celt export DIALPLANS_MODULES=dialplans/mod_dialplan_asterisk dialplans/mod_dialplan_directory dialplans/mod_dialplan_xml @@ -24,11 +24,11 @@ export ENDPOINTS_MODULES=endpoints/mod_dingaling endpoints/mod_portaudio endpoin endpoints/mod_skinny export EVENT_HANDLERS_MODULES=event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_cdr_csv export FORMATS_MODULES=formats/mod_local_stream formats/mod_native_file formats/mod_sndfile formats/mod_tone_stream formats/mod_shout -export LANGUAGES_MODULES=languages/mod_spidermonkey languages/mod_perl languages/mod_lua +export LANGUAGES_MODULES=languages/mod_spidermonkey languages/mod_perl languages/mod_lua languages/mod_python export LOGGERS_MODULES=loggers/mod_console loggers/mod_logfile loggers/mod_syslog export SAY_MODULES=say/mod_say_en say/mod_say_it say/mod_say_de say/mod_say_fr say/mod_say_es say/mod_say_nl say/mod_say_ru export TIMERS_MODULES= -export DISABLED_MODULES=applications/mod_memcache applications/mod_soundtouch directories/mod_ldap languages/mod_java languages/mod_python \ +export DISABLED_MODULES=applications/mod_memcache applications/mod_soundtouch directories/mod_ldap languages/mod_java \ asr_tts/mod_cepstral asr_tts/mod_lumenvox endpoints/mod_wanpipe \ event_handlers/mod_event_test event_handlers/mod_radius_cdr event_handlers/mod_zeroconf export XML_INT_MODULES=xml_int/mod_xml_rpc xml_int/mod_xml_curl xml_int/mod_xml_cdr diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml index 65c394cfc8..d519350d35 100644 --- a/docs/phrase/phrase_en.xml +++ b/docs/phrase/phrase_en.xml @@ -395,6 +395,8 @@ <prompt phrase="Congratulations, you pressed star. This does not mean you ARE a star. It simply means that you can press buttons and probably have fingers." filename="ivr-congratulations_you_pressed_star.wav"/> <prompt phrase="All of our engineers are busy assisting other sales guys with demonstrating how cool the CudaTel is. Please stay on the line and your call will be answered in the order it was received." filename="ivr-engineers_busy_assisting_other_sales.wav"/> <prompt phrase="" filename="ivr-.wav"/> + <prompt phrase="You are already muted." filename="conf-you_are_already_muted.wav"/> + <prompt phrase="You are now bi-directionally muted." filename="conf-you_are_now_bidirectionally_muted.wav"/> </ivr> <misc> diff --git a/freeswitch.spec b/freeswitch.spec index 76f9df4fb9..52e6226830 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -1,5 +1,5 @@ -############################################################################################################################### -############################################################################################################################### +###################################################################################################################### +###################################################################################################################### # # spec file for package freeswitch # @@ -26,8 +26,8 @@ # # Maintainer(s): Michal Bielicki <michal.bielicki (at) ++nospam_please++ seventhsignal.de # -############################################################################################################################### -############################################################################################################################### +###################################################################################################################### +###################################################################################################################### # # disable rpath checking %define __arch_install_post /usr/lib/rpm/check-buildroot @@ -48,11 +48,11 @@ URL: http://www.freeswitch.org/ Packager: Michal Bielicki Vendor: http://www.freeswitch.org/ -############################################################################################################################### +###################################################################################################################### # -# Source files and where to get them +# Source files and where to get them # -############################################################################################################################### +###################################################################################################################### Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2 Source1: http://files.freeswitch.org/downloads/libs/celt-0.7.0.tar.gz Source2: http://files.freeswitch.org/downloads/libs/flite-1.3.99-latest.tar.gz @@ -68,11 +68,11 @@ Source11: http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz Prefix: %{prefix} -############################################################################################################################### +###################################################################################################################### # # Build Dependencies # -############################################################################################################################### +###################################################################################################################### %if 0%{?suse_version} > 100 #BuildRequires: openldap2-devel @@ -128,11 +128,11 @@ PreReq: %insserv_prereq %fillup_prereq %endif -############################################################################################################################### +###################################################################################################################### # -# Where the packages are going to be built +# Where the packages are going to be built # -############################################################################################################################### +###################################################################################################################### BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %description @@ -155,12 +155,12 @@ Our developers are heavily involved in open source and have donated code and oth other telephony projects including sipXecs, OpenSER, Asterisk, CodeWeaver and OpenPBX. -############################################################################################################################### +###################################################################################################################### # -# Sub Package definitions. Description and Runtime Requirements go here -# What goes into which package is in the files section after the whole build enchilada +# Sub Package definitions. Description and Runtime Requirements go here +# What goes into which package is in the files section after the whole build enchilada # -############################################################################################################################### +###################################################################################################################### %package devel @@ -277,11 +277,11 @@ Requires: %{name} = %{version}-%{release} %description openzap OpenZAP -############################################################################################################################### +###################################################################################################################### # -# Unpack and prepare Source archives, copy stuff around etc .. +# Unpack and prepare Source archives, copy stuff around etc .. # -############################################################################################################################### +###################################################################################################################### %prep %setup -b0 -q @@ -297,11 +297,11 @@ cp %{SOURCE9} libs/ cp %{SOURCE10} libs/ cp %{SOURCE11} libs/ -############################################################################################################################### +###################################################################################################################### # -# Start the Build process +# Start the Build process # -############################################################################################################################### +###################################################################################################################### %build %ifos linux %if 0%{?suse_version} > 1000 && 0%{?suse_version} < 1030 @@ -312,115 +312,115 @@ export QA_RPATHS=$[ 0x0001|0x0002 ] %endif %endif -############################################################################################################################### +###################################################################################################################### # -# Here the modules that will be build get defined +# Here the modules that will be build get defined # -############################################################################################################################### -############################################################################################################################### +###################################################################################################################### +###################################################################################################################### # -# Application Modules +# Application Modules # -############################################################################################################################### -APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum applications/mod_esf applications/mod_expr applications/mod_callcenter" +###################################################################################################################### +APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_callcenter applications/mod_cluechoo applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum applications/mod_esf applications/mod_expr" APPLICATION_MODULES_FM="applications/mod_fifo applications/mod_fsv applications/mod_hash applications/mod_lcr applications/mod_limit applications/mod_memcache" -APPLICATION_MODULES_NY=" applications/mod_redis applications/mod_rss applications/mod_soundtouch applications/mod_spandsp applications/mod_stress applications/mod_spy " +APPLICATION_MODULES_NY="applications/mod_nibblebill applications/mod_redis applications/mod_rss applications/mod_soundtouch applications/mod_spandsp applications/mod_stress applications/mod_spy " APPLICATION_MODULES_VZ="applications/mod_valet_parking applications/mod_vmd applications/mod_voicemail" APPLICATIONS_MODULES="$APPLICATION_MODULES_AE $APPLICATION_MODULES_FM $APPLICATION_MODULES_NY $APPLICATION_MODULES_VZ" -############################################################################################################################### +###################################################################################################################### # -# Automatic Speech Recognition and Text To Speech Modules +# Automatic Speech Recognition and Text To Speech Modules # -############################################################################################################################### +###################################################################################################################### ASR_TTS_MODULES="asr_tts/mod_pocketsphinx asr_tts/mod_flite asr_tts/mod_unimrcp" -############################################################################################################################### +###################################################################################################################### # -# Codecs +# Codecs # -############################################################################################################################### +###################################################################################################################### CODECS_MODULES="codecs/mod_ilbc codecs/mod_h26x codecs/mod_speex codecs/mod_celt codecs/mod_siren codecs/mod_bv" -############################################################################################################################### +###################################################################################################################### # -# Dialplan Modules +# Dialplan Modules # -############################################################################################################################### +###################################################################################################################### DIALPLANS_MODULES="dialplans/mod_dialplan_asterisk dialplans/mod_dialplan_directory dialplans/mod_dialplan_xml" -############################################################################################################################### +###################################################################################################################### # -# Directory Modules +# Directory Modules # -############################################################################################################################### +###################################################################################################################### DIRECTORIES_MODULES="" -############################################################################################################################### +###################################################################################################################### # -# Endpoints +# Endpoints # -############################################################################################################################### +###################################################################################################################### ENDPOINTS_MODULES="endpoints/mod_dingaling endpoints/mod_portaudio endpoints/mod_sofia ../../libs/openzap/mod_openzap endpoints/mod_loopback" -############################################################################################################################### +###################################################################################################################### # -# Event Handlers +# Event Handlers # -############################################################################################################################### +###################################################################################################################### EVENT_HANDLERS_MODULES="event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_cdr_csv" -############################################################################################################################### +###################################################################################################################### # -# File and Audio Format Handlers +# File and Audio Format Handlers # -############################################################################################################################### -FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_sndfile formats/mod_tone_stream formats/mod_shout formats/mod_file_string" -############################################################################################################################### +###################################################################################################################### +FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_sndfile formats/mod_portaudio_stream formats/mod_tone_stream formats/mod_shout formats/mod_file_string" +###################################################################################################################### # -# Embedded Languages +# Embedded Languages # -############################################################################################################################### +###################################################################################################################### LANGUAGES_MODULES="languages/mod_lua languages/mod_perl languages/mod_python languages/mod_spidermonkey" -############################################################################################################################### +###################################################################################################################### # -# Logging Modules +# Logging Modules # -############################################################################################################################### +###################################################################################################################### LOGGERS_MODULES="loggers/mod_console loggers/mod_logfile loggers/mod_syslog" -############################################################################################################################### +###################################################################################################################### # -# Passthru Codecs +# Passthru Codecs # -############################################################################################################################### +###################################################################################################################### PASSTHRU_CODEC_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_g723_1 codecs/mod_g729" -############################################################################################################################### +###################################################################################################################### # -# Phrase engine language modules +# Phrase engine language modules # -############################################################################################################################### +###################################################################################################################### SAY_MODULES="say/mod_say_de say/mod_say_en say/mod_say_fr say/mod_say_ru" -############################################################################################################################### +###################################################################################################################### # -# Timers +# Timers # -############################################################################################################################### +###################################################################################################################### TIMERS_MODULES= -############################################################################################################################### +###################################################################################################################### # -# XML Modules +# XML Modules # -############################################################################################################################### +###################################################################################################################### XML_INT_MODULES="xml_int/mod_xml_cdr xml_int/mod_xml_curl xml_int/mod_xml_rpc" -############################################################################################################################### +###################################################################################################################### # -# Create one environment variable out of all the module defs +# Create one environment variable out of all the module defs # -############################################################################################################################### +###################################################################################################################### MYMODULES="$PASSTHRU_CODEC_MODULES $APPLICATIONS_MODULES $CODECS_MODULES $DIALPLANS_MODULES $DIRECTORIES_MODULES $ENDPOINTS_MODULES $ASR_TTS_MODULES $EVENT_HANDLERS_MODULES $FORMATS_MODULES $LANGUAGES_MODULES $LOGGERS_MODULES $SAY_MODULES $TIMERS_MODULES $XML_INT_MODULES" -############################################################################################################################### +###################################################################################################################### # -# Create Modules build list and set variables +# Create Modules build list and set variables # -############################################################################################################################### +###################################################################################################################### export MODULES=$MYMODULES test ! -f modules.conf || rm -f modules.conf @@ -431,11 +431,11 @@ export DESTDIR=%{buildroot}/ export PKG_CONFIG_PATH=/usr/bin/pkg-config:$PKG_CONFIG_PATH export ACLOCAL_FLAGS="-I /usr/share/aclocal" -############################################################################################################################### +###################################################################################################################### # -# Bootstrap, Configure and Build the whole enchilada +# Bootstrap, Configure and Build the whole enchilada # -############################################################################################################################### +###################################################################################################################### if test ! -f Makefile.in then @@ -467,11 +467,11 @@ touch .noversion %{__make} -############################################################################################################################### +###################################################################################################################### # -# Install it and create some required dirs and links +# Install it and create some required dirs and links # -############################################################################################################################### +###################################################################################################################### %install %{__make} DESTDIR=%{buildroot} install @@ -502,11 +502,11 @@ touch .noversion %endif -############################################################################################################################### +###################################################################################################################### # -# Add a freeswitch user with group daemon that will own the whole enchilada +# Add a freeswitch user with group daemon that will own the whole enchilada # -############################################################################################################################### +###################################################################################################################### %pre %ifos linux if ! /usr/bin/id freeswitch &>/dev/null; then @@ -526,11 +526,11 @@ chkconfig --add freeswitch %postun -############################################################################################################################### +###################################################################################################################### # -# On uninstallation get rid of the freeswitch user +# On uninstallation get rid of the freeswitch user # -############################################################################################################################### +###################################################################################################################### %{?run_ldconfig:%run_ldconfig} if [ $1 -eq 0 ]; then userdel freeswitch || %logmsg "User \"freeswitch\" could not be deleted." @@ -540,19 +540,19 @@ fi %{__rm} -rf %{buildroot} %files -############################################################################################################################### +###################################################################################################################### # -# What to install where ... first set default permissions +# What to install where ... first set default permissions # -############################################################################################################################### +###################################################################################################################### %defattr(-,freeswitch,daemon) -############################################################################################################################### +###################################################################################################################### # -# Directories +# Directories # -############################################################################################################################### +###################################################################################################################### # -#################################### Basic Directory Structure ################################################################ +#################################### Basic Directory Structure ####################################################### # %dir %attr(0750, freeswitch, daemon) %{prefix}/conf %dir %attr(0750, freeswitch, daemon) %{prefix}/db @@ -562,7 +562,7 @@ fi %dir %attr(0750, freeswitch, daemon) %{runtimedir} %dir %attr(0750, freeswitch, daemon) %{prefix}/scripts # -#################################### Config Directory Structure ################################################################ +#################################### Config Directory Structure ####################################################### # %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/dialplan @@ -579,7 +579,7 @@ fi %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/sip_profiles/internal %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/skinny_profiles # -#################################### Grammar Directory Structure ################################################################ +#################################### Grammar Directory Structure ##################################################### # %dir %attr(0750, freeswitch, daemon) %{prefix}/grammar/model %dir %attr(0750, freeswitch, daemon) %{prefix}/grammar/model/communicator @@ -587,11 +587,11 @@ fi %ifos linux %config(noreplace) %attr(0644, freeswitch, daemon) /etc/monit.d/freeswitch.monitrc %endif -############################################################################################################################### +###################################################################################################################### # -# Config Files +# Config Files # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.tpl %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.ttml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.xml @@ -650,60 +650,59 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/xml_curl.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/xml_rpc.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/zeroconf.conf.xml -############################################################################################################################### +###################################################################################################################### # -# Dialplans +# Dialplans # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/default/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/public/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/skinny-patterns/*.xml -############################################################################################################################### +###################################################################################################################### # -# User Directories +# User Directories # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/directory/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/directory/default/* -############################################################################################################################### +###################################################################################################################### # -# IVR Menues +# IVR Menues # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/ivr_menus/*.xml -############################################################################################################################### +###################################################################################################################### # -# Sip Profiles +# Sip Profiles # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/sip_profiles/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/sip_profiles/internal/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/sip_profiles/external/*.xml -############################################################################################################################### +###################################################################################################################### # -# Other Protocol Profiles (skinny, jingle, mrcp) +# Other Protocol Profiles (skinny, jingle, mrcp) # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/skinny_profiles/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/jingle_profiles/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/mrcp_profiles/*.xml -############################################################################################################################### +###################################################################################################################### # -# Grammar Files +# Grammar Files # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/grammar/default.dic %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/grammar/model/communicator/* %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/grammar/model/wsj1/* -############################################################################################################################### +###################################################################################################################### # -# Other Fíles +# Other Fíles # -############################################################################################################################### +###################################################################################################################### %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/htdocs/* %ifos linux -#/etc/ld.so.conf.d/* /etc/rc.d/init.d/freeswitch /etc/sysconfig/freeswitch %if 0%{?suse_version} > 100 @@ -713,23 +712,25 @@ fi %ifos linux %dir %attr(0750, root, root) /etc/monit.d %endif -############################################################################################################################### +###################################################################################################################### # -# Binaries +# Binaries # -############################################################################################################################### +###################################################################################################################### %attr(0755, freeswitch, daemon) %{prefix}/bin/* %{prefix}/lib/libfreeswitch*.so* -############################################################################################################################### +###################################################################################################################### # -# Modules in Alphabetical Order, please keep them that way.. +# Modules in Alphabetical Order, please keep them that way.. # -############################################################################################################################### +###################################################################################################################### %{prefix}/mod/mod_amrwb.so* %{prefix}/mod/mod_avmd.so* %{prefix}/mod/mod_bv.so* +%{prefix}/mod/mod_callcenter.so* %{prefix}/mod/mod_cdr_csv.so* %{prefix}/mod/mod_celt.so* +%{prefix}/mod/mod_cluechoo.so* %{prefix}/mod/mod_console.so* %{prefix}/mod/mod_commands.so* %{prefix}/mod/mod_conference.so* @@ -747,7 +748,6 @@ fi %{prefix}/mod/mod_event_multicast.so* %{prefix}/mod/mod_event_socket.so* %{prefix}/mod/mod_expr.so* -%{prefix}/mod/mod_callcenter.so* %{prefix}/mod/mod_fifo.so* %{prefix}/mod/mod_file_string.so* %{prefix}/mod/mod_flite.so* @@ -762,8 +762,10 @@ fi %{prefix}/mod/mod_loopback.so* %{prefix}/mod/mod_memcache.so* %{prefix}/mod/mod_native_file.so* +%{prefix}/mod/mod_nibblebill.so* %{prefix}/mod/mod_pocketsphinx.so* %{prefix}/mod/mod_portaudio.so* +%{prefix}/mod/mod_portaudio_stream.so* %{prefix}/mod/mod_redis.so* %{prefix}/mod/mod_rss.so* %{prefix}/mod/mod_shout.so* @@ -784,13 +786,11 @@ fi %{prefix}/mod/mod_xml_cdr.so* %{prefix}/mod/mod_xml_curl.so* %{prefix}/mod/mod_xml_rpc.so* - - -############################################################################################################################### +###################################################################################################################### # -# Package for the developer +# Package for the developer # -############################################################################################################################### +###################################################################################################################### %files devel %defattr(-, freeswitch, daemon) %{prefix}/lib/*.a @@ -799,12 +799,11 @@ fi %{prefix}/mod/*.a %{prefix}/mod/*.la %{prefix}/include/*.h - -############################################################################################################################### +###################################################################################################################### # -# OpenZAP Module for TDM Interaction +# OpenZAP Module for TDM Interaction # -############################################################################################################################### +###################################################################################################################### %files openzap %defattr(-, freeswitch, daemon) %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/tones.conf @@ -817,11 +816,11 @@ fi %{prefix}/mod/mod_openzap.so* %{prefix}/mod/ozmod_*.so* -############################################################################################################################### +###################################################################################################################### # -# Passthru Codec Modules +# Passthru Codec Modules # -############################################################################################################################### +###################################################################################################################### %files codec-passthru-amrwb %defattr(-,freeswitch,daemon) %{prefix}/mod/mod_amrwb.so* @@ -838,12 +837,11 @@ fi %defattr(-,freeswitch,daemon) %{prefix}/mod/mod_g729.so* - -############################################################################################################################### +###################################################################################################################### # -# Embedded Language Modules +# Embedded Language Modules # -############################################################################################################################### +###################################################################################################################### %files spidermonkey %defattr(-,freeswitch,daemon) %{prefix}/mod/mod_spidermonkey*.so* @@ -874,11 +872,11 @@ fi %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/python.conf.xml -############################################################################################################################### +###################################################################################################################### # -# Language Modules +# Language Modules # -############################################################################################################################### +###################################################################################################################### %files lang-en %defattr(-, freeswitch, daemon) %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en @@ -922,12 +920,17 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/dir/*.xml %{prefix}/mod/mod_say_ru.so* -############################################################################################################################### +###################################################################################################################### # -# Changelog +# Changelog # -############################################################################################################################### +###################################################################################################################### %changelog +* Thu Sep 30 2010 - michal.bielicki@seventhsignal.de +- added mod_nibblebill to standard modules +* Sun Sep 26 2010 - michal.bielicki@seventhsignal.de +- added portaudio_stream module +- some more formating work * Mon Jul 19 2010 - michal.bielicki@seventhsignal.de - new hash module config file added to freeswitch.spec * Mon Jul 19 2010 - michal.bielicki@seventhsignal.de diff --git a/libs/.gitignore b/libs/.gitignore index 24e32c1954..cc42ba4fa4 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -355,6 +355,7 @@ /libsndfile/Cfg/missing /libsndfile/M4/Makefile /libsndfile/M4/Makefile.in +/libsndfile/M4/lt~obsolete.m4 /libsndfile/Makefile /libsndfile/Makefile.in /libsndfile/Octave/Makefile diff --git a/libs/apr/.update b/libs/apr/.update index 097f707e64..d5bc43d9d4 100644 --- a/libs/apr/.update +++ b/libs/apr/.update @@ -1 +1 @@ -Thu Nov 19 09:24:37 EST 2009 +Mon Sep 27 13:15:54 CDT 2010 diff --git a/libs/apr/strings/apr_snprintf.c b/libs/apr/strings/apr_snprintf.c index fe8b382d14..4f59f92c76 100644 --- a/libs/apr/strings/apr_snprintf.c +++ b/libs/apr/strings/apr_snprintf.c @@ -824,7 +824,13 @@ APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *), * Modifier check. Note that if APR_INT64_T_FMT is "d", * the first if condition is never true. */ - if ((sizeof(APR_INT64_T_FMT) == 4 && + + /* HACK BY FREESWITCH TEAM TO FIX COMPATIBILITY 2010-09-27 */ + if (*fmt == 'l' && *(fmt + 1) == 'l') { + var_type = IS_QUAD; + fmt += 2; + } + else if ((sizeof(APR_INT64_T_FMT) == 4 && fmt[0] == APR_INT64_T_FMT[0] && fmt[1] == APR_INT64_T_FMT[1]) || (sizeof(APR_INT64_T_FMT) == 3 && @@ -843,6 +849,11 @@ APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *), else if (*fmt == 'l') { var_type = IS_LONG; fmt++; + /* HACK BY FREESWITCH TEAM TO FIX COMPATIBILITY 2010-09-27 */ + if (*fmt == 'l') { + var_type = IS_QUAD; + fmt++; + } } else if (*fmt == 'h') { var_type = IS_SHORT; diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 160fe2d759..75a52d6bd2 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -36,7 +36,10 @@ #define closesocket(x) close(x) #include <fcntl.h> #else +#pragma warning (disable:6386) +/* These warnings need to be ignored warning in sdk header */ #include <Ws2tcpip.h> +#pragma warning (default:6386) #endif diff --git a/libs/esl/src/esl_config.c b/libs/esl/src/esl_config.c index 4616356f7f..2e24007799 100644 --- a/libs/esl/src/esl_config.c +++ b/libs/esl/src/esl_config.c @@ -110,7 +110,7 @@ ESL_DECLARE(int) esl_config_next_pair(esl_config_t *cfg, char **var, char **val) *var = *val = NULL; - if (!cfg->path) { + if (!cfg || !cfg->file) { return 0; } diff --git a/libs/esl/src/esl_event.c b/libs/esl/src/esl_event.c index 2e1d8a302a..db7c581ee9 100644 --- a/libs/esl/src/esl_event.c +++ b/libs/esl/src/esl_event.c @@ -513,6 +513,9 @@ ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, es char *encode_buf = NULL; /* used for url encoding of variables to make sure unsafe things stay out of the serialized copy */ int clen = 0; + if (!event || !event->headers) + return ESL_FAIL; + *str = NULL; dlen = blocksize * 2; diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 33a8b96936..d14013ab9b 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -312,7 +312,7 @@ ftmod_r2_la_LIBADD = $(MYLIB) endif dox doxygen: - cd docs && doxygen $(FT_SRCDIR)/docs/Doxygen.conf + doxygen $(FT_SRCDIR)/docs/Doxygen.conf mod_freetdm/mod_freetdm.$(DYNAMIC_LIB_EXTEN): $(MYLIB) mod_freetdm/mod_freetdm.c cd mod_freetdm && make diff --git a/libs/freetdm/README b/libs/freetdm/README index 2c2119f55b..4ca13d19c9 100644 --- a/libs/freetdm/README +++ b/libs/freetdm/README @@ -1,3 +1,3 @@ -FREETDM (WORK IN PROGRESS) +FreeTDM +http://wiki.freeswitch.org/wiki/FreeTDM -*shrug* diff --git a/libs/freetdm/conf/freetdm.conf b/libs/freetdm/conf/freetdm.conf index 1ea1a9f62a..bbaf1e3687 100644 --- a/libs/freetdm/conf/freetdm.conf +++ b/libs/freetdm/conf/freetdm.conf @@ -1,19 +1,47 @@ -[span wanpipe] -name => FreeTDM -number => 1 +; !! THIS IS A SAMPLE CONFIGURATION ONLY !! + +; refer to http://wiki.freeswitch.org/wiki/FreeTDM for further documentation + +[general] +; whether to launch a thread for CPU usage monitoring +cpu_monitor => no + +; How often (in milliseconds) monitor CPU usage +cpu_monitoring_interval => 1000 + +; At what CPU percentage raise a CPU alarm +cpu_set_alarm_threshold => 80 + +; At what CPU percentage stop the CPU alarm +cpu_reset_alarm_threshold => 70 + +; Which action to take when the CPU alarm is raised +; it can be warn and/or reject calls +; cpu_alarm_action => warn,reject +cpu_alarm_action => warn + +; spans are defined with [span <span type> <span name>] +; the span type can either be zt, wanpipe or pika +; the span name can be any unique string +[span wanpipe myWanpipe] + +; valid trunk types are: FXO, FXS, EM, E1, T1, J1, BRI, BRI_PTMP +trunk_type => FXS + +; add FXS channels from 3 to 4 at wanpipe span 1 to this freetdm span fxs-channel => 1:3-4 -[span wanpipe] +[span wanpipe myWanpipe2] +trunk_type => FXO +; This number will be used as DNIS for FXO devices fxo-channel => 1:1-2 -[span zt] -name => FreeTDM -number => 2 +[span zt myZaptelSpan] +number => 9999 fxs-channel => 1 -[span zt] -name => FreeTDM +[span zt mySecondZaptelSpan] +; This number will be used as DNIS for FXO devices number => 2 fxo-channel => 3 - diff --git a/libs/freetdm/conf/freetdm.conf.xml b/libs/freetdm/conf/freetdm.conf.xml index 69bf99a0a0..986074dffb 100644 --- a/libs/freetdm/conf/freetdm.conf.xml +++ b/libs/freetdm/conf/freetdm.conf.xml @@ -1,3 +1,5 @@ +<!-- Please refer to http://wiki.freeswitch.org/wiki/FreeTDM for further documentation --> + <configuration name="freetdm.conf" description="FreeTDM Configuration"> <settings> <param name="debug" value="0"/> @@ -5,6 +7,8 @@ <!--<param name="enable-analog-option" value="call-swap"/>--> <!--<param name="enable-analog-option" value="3-way"/>--> </settings> + + <!-- use the <pri_spans> tag for native ISDN support (most likely broken at this point, check sangoma_pri_spans or libpri_spans for alternatives) --> <pri_spans> <span name="PRI_1"> <!-- Log Levels: none, alert, crit, err, warning, notice, info, debug --> @@ -24,9 +28,11 @@ <param name="context" value="default"/> </span> </pri_spans> - <!-- one entry here per openzap span --> + + + <!-- Analog spans go here --> <analog_spans> - <span id="1"> + <span name="myAnalog"> <!--<param name="hold-music" value="$${moh_uri}"/>--> <!--<param name="enable-analog-option" value="call-swap"/>--> <!--<param name="enable-analog-option" value="3-way"/>--> @@ -42,4 +48,5 @@ <!--<param name="fail-dial-regex" value="^5"/>--> </span> </analog_spans> + </configuration> diff --git a/libs/freetdm/conf/pika.conf b/libs/freetdm/conf/pika.conf index 8cc8d9c11d..78e095205e 100644 --- a/libs/freetdm/conf/pika.conf +++ b/libs/freetdm/conf/pika.conf @@ -1,3 +1,5 @@ +; you dont need this file unless you use PIKA boards + ; each category is a config profile ; to apply the profile append it to a channel def in ; openzap.conf with @<profile_name> diff --git a/libs/freetdm/conf/tones.conf b/libs/freetdm/conf/tones.conf index 36db1d4d91..155b5fe17e 100644 --- a/libs/freetdm/conf/tones.conf +++ b/libs/freetdm/conf/tones.conf @@ -1,3 +1,5 @@ +; This file is used to generate telephony tones by FreeTDM + [us] generate-dial => v=-7;%(1000,0,350,440) detect-dial => 350,440 diff --git a/libs/freetdm/mkrelease.sh b/libs/freetdm/mkrelease.sh new file mode 100755 index 0000000000..58d176119d --- /dev/null +++ b/libs/freetdm/mkrelease.sh @@ -0,0 +1,64 @@ +#!/bin/bash +INSTALLPREFIX="/usr/local/freetdm" +VERSION="" +NODOCS="NO" + +for i in $* +do + case $i in + --version=*) + VERSION=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` + ;; + --prefix=*) + INSTALLPREFIX=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` + ;; + --nodocs) + NODOCS="YES" + ;; + *) + # unknown option + echo "Unknown option $i" + exit + ;; + esac +done + +if [ "x$VERSION" = "x" ] +then + echo "Provide a version number with --version=<version>" + exit 1 +fi + +if [ ! -d $INSTALLPREFIX ] +then + mkdir -p $INSTALLPREFIX || exit 1 +fi + +make clean +make mod_freetdm-clean +if [ $NODOCS = "NO" ] +then + make dox || exit 1 +fi + +major=$(echo "$VERSION" | cut -d. -f1) +minor=$(echo "$VERSION" | cut -d. -f2) +micro=$(echo "$VERSION" | cut -d. -f3) +release="freetdm-$VERSION" + +echo "Creating $release ($major.$minor.$micro) at $INSTALLPREFIX/$release (directory will be removed if exists already) ... press any key to continue" +read + +mkdir -p $INSTALLPREFIX/$release + +cp -r ./* $INSTALLPREFIX/$release + +find $INSTALLPREFIX/ -name .libs -exec rm -rf {} \; +find $INSTALLPREFIX/ -name .deps -exec rm -rf {} \; +find $INSTALLPREFIX/ -name *.so -exec rm -rf {} \; +find $INSTALLPREFIX/ -name *.lo -exec rm -rf {} \; + + +tar -C $INSTALLPREFIX -czf $INSTALLPREFIX/$release.tar.gz $release/ + + diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index fb85b3515c..3ad4393ab5 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1404,6 +1404,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session private_t *tech_pvt = NULL; switch_channel_t *channel = NULL; ftdm_iterator_t *iter = NULL; + ftdm_iterator_t *curr = NULL; const char *var_name = NULL; const char *var_value = NULL; uint32_t spanid, chanid; @@ -1515,13 +1516,14 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session switch_channel_set_variable_printf(channel, "freetdm_custom_call_data", "%s", channel_caller_data->raw_data); } /* Add any channel variable to the dial plan */ - iter = ftdm_channel_get_var_iterator(sigmsg->channel); - for ( ; iter; iter = ftdm_iterator_next(iter)) { - ftdm_channel_get_current_var(iter, &var_name, &var_value); + iter = ftdm_channel_get_var_iterator(sigmsg->channel, NULL); + for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) { + ftdm_channel_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); } - + ftdm_iterator_free(iter); + switch_channel_set_state(channel, CS_INIT); if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n"); @@ -2180,9 +2182,8 @@ static void ftdm_logger(const char *file, const char *func, int line, int level, if (switch_vasprintf(&data, fmt, ap) != -1) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, (char *)func, line, NULL, level, "%s", data); - free(data); } - + if (data) free(data); va_end(ap); } @@ -2371,6 +2372,121 @@ static int add_profile_parameters(switch_xml_t cfg, const char *profname, ftdm_c return paramindex; } +static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans) +{ + switch_xml_t myspan, param; + + for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { + ftdm_status_t zstatus = FTDM_FAIL; + const char *context = "default"; + const char *dialplan = "XML"; + ftdm_conf_parameter_t spanparameters[30]; + char *id = (char *) switch_xml_attr(myspan, "id"); + char *name = (char *) switch_xml_attr(myspan, "name"); + char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); + ftdm_span_t *span = NULL; + uint32_t span_id = 0; + unsigned paramindex = 0; + + if (!name && !id) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n"); + continue; + } + + if (name) { + zstatus = ftdm_span_find_by_name(name, &span); + } else { + if (switch_is_number(id)) { + span_id = atoi(id); + zstatus = ftdm_span_find(span_id, &span); + } + + if (zstatus != FTDM_SUCCESS) { + zstatus = ftdm_span_find_by_name(id, &span); + } + } + + if (zstatus != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); + continue; + } + + if (!span_id) { + span_id = ftdm_span_get_id(span); + } + + memset(spanparameters, 0, sizeof(spanparameters)); + paramindex = 0; + + if (configname) { + paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters)); + if (paramindex) { + ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id); + } + } + + /* some defaults first */ + SPAN_CONFIG[span_id].limit_backend = "hash"; + SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT; + + for (param = switch_xml_child(myspan, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + + if (ftdm_array_len(spanparameters) == paramindex) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var); + break; + } + + if (!strcasecmp(var, "context")) { + context = val; + } else if (!strcasecmp(var, "dialplan")) { + dialplan = val; + } 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); + } else if (!strcasecmp(var, "call_limit_rate")) { + int calls; + int seconds; + if (sscanf(val, "%d/%d", &calls, &seconds) != 2) { + ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var); + } else { + if (calls < 1 || seconds < 1) { + ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var); + } else { + SPAN_CONFIG[span_id].limit_calls = calls; + SPAN_CONFIG[span_id].limit_seconds = seconds; + } + } + } else if (!strcasecmp(var, "call_limit_reset_event")) { + if (!strcasecmp(val, "answer")) { + SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER; + } else { + ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var); + } + } else { + spanparameters[paramindex].var = var; + spanparameters[paramindex].val = val; + paramindex++; + } + } + + if (ftdm_configure_span_signaling(span, + "sangoma_isdn", + on_clear_channel_signal, + spanparameters) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Error configuring Sangoma ISDN FreeTDM span %d\n", span_id); + continue; + } + SPAN_CONFIG[span_id].span = span; + switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); + switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); + switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type)); + ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id); + ftdm_span_start(span); + } +} + static switch_status_t load_config(void) { const char *cf = "freetdm.conf"; @@ -2381,7 +2497,8 @@ static switch_status_t load_config(void) unsigned boosti = 0; unsigned int i = 0; ftdm_channel_t *fchan = NULL; - unsigned int chancount = 0; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; memset(boost_spans, 0, sizeof(boost_spans)); memset(&globals, 0, sizeof(globals)); @@ -2410,116 +2527,12 @@ static switch_status_t load_config(void) } } - if ((spans = switch_xml_child(cfg, "sangoma_pri_spans")) || (spans = switch_xml_child(cfg, "sangoma_bri_spans"))) { - for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) { - ftdm_status_t zstatus = FTDM_FAIL; - const char *context = "default"; - const char *dialplan = "XML"; - ftdm_conf_parameter_t spanparameters[30]; - char *id = (char *) switch_xml_attr(myspan, "id"); - char *name = (char *) switch_xml_attr(myspan, "name"); - char *configname = (char *) switch_xml_attr(myspan, "cfgprofile"); - ftdm_span_t *span = NULL; - uint32_t span_id = 0; - unsigned paramindex = 0; + if ((spans = switch_xml_child(cfg, "sangoma_pri_spans"))) { + parse_bri_pri_spans(cfg, spans); + } - if (!name && !id) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n"); - continue; - } - - if (name) { - zstatus = ftdm_span_find_by_name(name, &span); - } else { - if (switch_is_number(id)) { - span_id = atoi(id); - zstatus = ftdm_span_find(span_id, &span); - } - - if (zstatus != FTDM_SUCCESS) { - zstatus = ftdm_span_find_by_name(id, &span); - } - } - - if (zstatus != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name)); - continue; - } - - if (!span_id) { - span_id = ftdm_span_get_id(span); - } - - memset(spanparameters, 0, sizeof(spanparameters)); - paramindex = 0; - - if (configname) { - paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters)); - if (paramindex) { - ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id); - } - } - - /* some defaults first */ - SPAN_CONFIG[span_id].limit_backend = "hash"; - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT; - - for (param = switch_xml_child(myspan, "param"); param; param = param->next) { - char *var = (char *) switch_xml_attr_soft(param, "name"); - char *val = (char *) switch_xml_attr_soft(param, "value"); - - if (ftdm_array_len(spanparameters) == paramindex) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var); - break; - } - - if (!strcasecmp(var, "context")) { - context = val; - } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; - } 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); - } else if (!strcasecmp(var, "call_limit_rate")) { - int calls; - int seconds; - if (sscanf(val, "%d/%d", &calls, &seconds) != 2) { - ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var); - } else { - if (calls < 1 || seconds < 1) { - ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var); - } else { - SPAN_CONFIG[span_id].limit_calls = calls; - SPAN_CONFIG[span_id].limit_seconds = seconds; - } - } - } else if (!strcasecmp(var, "call_limit_reset_event")) { - if (!strcasecmp(val, "answer")) { - SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER; - } else { - ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var); - } - } else { - spanparameters[paramindex].var = var; - spanparameters[paramindex].val = val; - paramindex++; - } - } - - if (ftdm_configure_span_signaling(span, - "sangoma_isdn", - on_clear_channel_signal, - spanparameters) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error configuring Sangoma ISDN FreeTDM span %d\n", span_id); - continue; - } - SPAN_CONFIG[span_id].span = span; - switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context)); - switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan)); - switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type)); - ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id); - ftdm_span_start(span); - } + if ((spans = switch_xml_child(cfg, "sangoma_bri_spans"))) { + parse_bri_pri_spans(cfg, spans); } switch_core_hash_init(&globals.ss7_configs, module_pool); @@ -2769,11 +2782,13 @@ static switch_status_t load_config(void) switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan); SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options; - chancount = ftdm_span_get_chan_count(span); - for (i = 1; i <= chancount; i++) { - fchan = ftdm_span_get_channel(span, i); + chaniter = ftdm_span_get_chan_iterator(span, NULL); + curr = chaniter; + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + fchan = ftdm_iterator_current(curr); ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]); } + ftdm_iterator_free(chaniter); if (dial_regex) { switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex); @@ -3436,7 +3451,10 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre const char *chan_type; const char *state; const char *last_state; + const char *uuid = NULL; + char sessionid[255]; float txgain, rxgain; + switch_core_session_t *session = NULL; ftdm_alarm_flag_t alarmflag; ftdm_caller_data_t *caller_data; ftdm_channel_t *ftdmchan; @@ -3446,6 +3464,7 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre return; } + strcpy(sessionid, "(none)"); ftdmchan = ftdm_span_get_channel(span, chan_id); span_id = ftdm_span_get_id(span); @@ -3460,6 +3479,16 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre ftdm_channel_get_sig_status(ftdmchan, &sigstatus); ftdm_channel_get_alarms(ftdmchan, &alarmflag); + uuid = ftdm_channel_get_uuid(ftdmchan, 0); + if (!zstr(uuid)) { + if (!(session = switch_core_session_locate(uuid))) { + snprintf(sessionid, sizeof(sessionid), "%s (dead)", uuid); + } else { + snprintf(sessionid, sizeof(sessionid), "%s", uuid); + switch_core_session_rwunlock(session); + } + } + stream->write_function(stream, "span_id: %u\n" "chan_id: %u\n" @@ -3479,7 +3508,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre "aniII: %s\n" "dnis: %s\n" "rdnis: %s\n" - "cause: %s\n\n", + "cause: %s\n" + "session: %s\n\n", span_id, chan_id, phspan_id, @@ -3498,7 +3528,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre caller_data->aniII, caller_data->dnis.digits, caller_data->rdnis.digits, - switch_channel_cause2str(caller_data->hangup_cause)); + switch_channel_cause2str(caller_data->hangup_cause), + sessionid); } void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream) @@ -3581,6 +3612,8 @@ SWITCH_STANDARD_API(ft_function) { char *mycmd = NULL, *argv[10] = { 0 }; int argc = 0; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; if (!zstr(cmd) && (mycmd = strdup(cmd))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); @@ -3626,11 +3659,11 @@ SWITCH_STANDARD_API(ft_function) dump_chan_xml(span, chan_id, stream); } } else { - uint32_t j; - uint32_t ccount = ftdm_span_get_chan_count(span); - for (j = 1; j <= ccount; j++) { - dump_chan_xml(span, j, stream); + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + dump_chan_xml(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream); } + ftdm_iterator_free(chaniter); } } @@ -3643,15 +3676,20 @@ SWITCH_STANDARD_API(ft_function) if(chan_id > ftdm_span_get_chan_count(span)) { stream->write_function(stream, "-ERR invalid channel\n"); } else { + char *dbgstr = NULL; + ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id); dump_chan(span, chan_id, stream); + dbgstr = ftdm_channel_get_history_str(fchan); + stream->write_function(stream, "%s\n", dbgstr); + ftdm_free(dbgstr); } } else { - uint32_t j; - uint32_t ccount = ftdm_span_get_chan_count(span); stream->write_function(stream, "+OK\n"); - for (j = 1; j <= ccount; j++) { - dump_chan(span, j, stream); + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + dump_chan(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream); } + ftdm_iterator_free(chaniter); } } @@ -3972,7 +4010,7 @@ SWITCH_STANDARD_API(ft_function) if (rply) { stream->write_function(stream, "%s", rply); - free(rply); + ftdm_free(rply); } else { stream->write_function(stream, "-ERR Usage: %s\n", FT_SYNTAX); } @@ -4057,8 +4095,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load) ftdm_global_set_logger(ftdm_logger); - ftdm_cpu_monitor_disable(); - + ftdm_global_set_mod_directory(SWITCH_GLOBAL_dirs.mod_dir); + + ftdm_global_set_config_directory(SWITCH_GLOBAL_dirs.conf_dir); + if (ftdm_global_init() != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n"); return SWITCH_STATUS_TERM; diff --git a/libs/freetdm/sample/boost/ftdmstart.c b/libs/freetdm/sample/boost/ftdmstart.c index 972ed43146..bff0664bce 100644 --- a/libs/freetdm/sample/boost/ftdmstart.c +++ b/libs/freetdm/sample/boost/ftdmstart.c @@ -313,13 +313,6 @@ int main(int argc, char *argv[]) /* set the logging level to use */ ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - /* this is optional. - * cpu monitor is a default feature in freetdm that launches 1 thread - * to monitor system-wide CPU usage. If it goes above a predefined threshold - * it will stop accepting calls to try to protect the quality of current calls */ - ftdm_cpu_monitor_disable(); - - /* Initialize the FTDM library */ if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); diff --git a/libs/freetdm/sample/dso/ftdmload.c b/libs/freetdm/sample/dso/ftdmload.c index 5b150d67ed..80bcc02fc0 100644 --- a/libs/freetdm/sample/dso/ftdmload.c +++ b/libs/freetdm/sample/dso/ftdmload.c @@ -134,8 +134,6 @@ int main(int argc, char *argv[]) ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - ftdm_cpu_monitor_disable(); - if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); exit(-1); diff --git a/libs/freetdm/sample/sched/ftdmsched.c b/libs/freetdm/sample/sched/ftdmsched.c index 5cd7d6340a..e6e391ee4b 100644 --- a/libs/freetdm/sample/sched/ftdmsched.c +++ b/libs/freetdm/sample/sched/ftdmsched.c @@ -73,8 +73,6 @@ int main(int argc, char *argv[]) ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG); - ftdm_cpu_monitor_disable(); - if (ftdm_global_init() != FTDM_SUCCESS) { fprintf(stderr, "Error loading FreeTDM\n"); exit(-1); diff --git a/libs/freetdm/src/ftdm_config.c b/libs/freetdm/src/ftdm_config.c index 4ba2e19c67..1b023e93eb 100644 --- a/libs/freetdm/src/ftdm_config.c +++ b/libs/freetdm/src/ftdm_config.c @@ -37,6 +37,27 @@ #include "private/ftdm_core.h" +#ifndef FTDM_MOD_DIR +#define FTDM_MOD_DIR "." +#endif + +#define FTDM_MAX_CONF_DIR 512 + +static char g_ftdm_config_dir[FTDM_MAX_CONF_DIR] = FTDM_CONFIG_DIR; +static char g_ftdm_mod_dir[FTDM_MAX_CONF_DIR] = FTDM_MOD_DIR; + +FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path) +{ + snprintf(g_ftdm_mod_dir, sizeof(g_ftdm_mod_dir), "%s", path); + ftdm_log(FTDM_LOG_DEBUG, "New mod directory: %s\n", g_ftdm_mod_dir); +} + +FT_DECLARE(void) ftdm_global_set_config_directory(const char *path) +{ + snprintf(g_ftdm_config_dir, sizeof(g_ftdm_config_dir), "%s", path); + ftdm_log(FTDM_LOG_DEBUG, "New config directory: %s\n", g_ftdm_config_dir); +} + int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) { FILE *f; @@ -46,7 +67,7 @@ int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) if (file_path[0] == '/') { path = file_path; } else { - snprintf(path_buf, sizeof(path_buf), "%s%s%s", FTDM_CONFIG_DIR, FTDM_PATH_SEPARATOR, file_path); + snprintf(path_buf, sizeof(path_buf), "%s%s%s", g_ftdm_config_dir, FTDM_PATH_SEPARATOR, file_path); path = path_buf; } @@ -64,7 +85,7 @@ int ftdm_config_open_file(ftdm_config_t *cfg, const char *file_path) int last = -1; char *var, *val; - snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", FTDM_CONFIG_DIR, FTDM_PATH_SEPARATOR); + snprintf(path_buf, sizeof(path_buf), "%s%sfreetdm.conf", g_ftdm_config_dir, FTDM_PATH_SEPARATOR); path = path_buf; if ((f = fopen(path, "r")) == 0) { @@ -268,13 +289,24 @@ FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node if (parent) { /* store who my parent is */ newnode->parent = parent; - /* save any siblings */ - sibling = parent->child; - /* as a newborn I am first */ - parent->child = newnode; - if (sibling) { - /* store a pointer to my next sibling */ - newnode->next = sibling; + + /* arrange them in FIFO order (newnode should be last) */ + if (!parent->child) { + /* we're the first node being added */ + parent->child = newnode; + } else { + if (!parent->last) { + /* we're the second node being added */ + parent->last = newnode; + parent->child->next = newnode; + newnode->prev = parent->child; + } else { + /* we're the third or Nth node to be added */ + sibling = parent->last; + sibling->next = newnode; + parent->last = newnode; + newnode->prev = sibling; + } } } @@ -318,6 +350,26 @@ FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node) return FTDM_SUCCESS; } +FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len) +{ +#ifdef WIN32 + const char *ext = ".dll"; + //const char *EXT = ".DLL"; +#elif defined (MACOSX) || defined (DARWIN) + const char *ext = ".dylib"; + //const char *EXT = ".DYLIB"; +#else + const char *ext = ".so"; + //const char *EXT = ".SO"; +#endif + if (*name == *FTDM_PATH_SEPARATOR) { + snprintf(path, len, "%s%s", name, ext); + } else { + snprintf(path, len, "%s%s%s%s", g_ftdm_mod_dir, FTDM_PATH_SEPARATOR, name, ext); + } + return path; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index b275403c85..99c0c86ed5 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -50,6 +50,7 @@ #endif #include "ftdm_cpu_monitor.h" +#define FORCE_HANGUP_TIMER 3000 #define SPAN_PENDING_CHANS_QUEUE_SIZE 1000 #define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000 #define FTDM_READ_TRACE_INDEX 0 @@ -85,6 +86,7 @@ FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void) } typedef struct { + uint8_t enabled; uint8_t running; uint8_t alarm; uint32_t interval; @@ -102,6 +104,7 @@ static struct { ftdm_mutex_t *mutex; ftdm_mutex_t *span_mutex; ftdm_mutex_t *group_mutex; + ftdm_sched_t *timingsched; uint32_t span_index; uint32_t group_index; uint32_t running; @@ -110,8 +113,6 @@ static struct { cpu_monitor_t cpu_monitor; } globals; -static uint8_t ftdm_cpu_monitor_disabled = 0; - enum ftdm_enum_cpu_alarm_action_flags { FTDM_CPU_ALARM_ACTION_WARN = (1 << 0), @@ -243,6 +244,39 @@ static __inline__ void ftdm_std_free(void *pool, void *ptr) free(ptr); } +static void ftdm_set_echocancel_call_begin(ftdm_channel_t *chan) +{ + ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); + if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) { + if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) { + if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) { + ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL); + } + } else { + if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) { + ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL); + } + } + } +} + +static void ftdm_set_echocancel_call_end(ftdm_channel_t *chan) +{ + ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); + if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) { + if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) { + if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) { + ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL); + } + } else { + if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) { + ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL); + } + } + } +} + + FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler = { /*.pool =*/ NULL, @@ -463,6 +497,7 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span) status = FTDM_FAIL; } ftdm_safe_free(span->type); + ftdm_safe_free(span->name); ftdm_safe_free(span->dtmf_hangup); } @@ -536,7 +571,7 @@ static void ftdm_span_add(ftdm_span_t *span) } else { globals.spans = span; } - hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_NONE); + hashtable_insert(globals.span_hash, (void *)span->name, span, HASHTABLE_FLAG_FREE_VALUE); ftdm_mutex_unlock(globals.span_mutex); } @@ -1249,6 +1284,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *f case FTDM_CHANNEL_STATE_RING: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_IDLE: case FTDM_CHANNEL_STATE_GET_CALLERID: case FTDM_CHANNEL_STATE_GENRING: ok = 1; @@ -1290,6 +1326,16 @@ end: ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state)); ftdmchan->last_state = ftdmchan->state; ftdmchan->state = state; + ftdmchan->history[ftdmchan->hindex].file = file; + ftdmchan->history[ftdmchan->hindex].func = func; + ftdmchan->history[ftdmchan->hindex].line = line; + ftdmchan->history[ftdmchan->hindex].state = ftdmchan->state; + ftdmchan->history[ftdmchan->hindex].last_state = ftdmchan->last_state; + ftdmchan->history[ftdmchan->hindex].time = ftdm_current_time_in_ms(); + ftdmchan->hindex++; + if (ftdmchan->hindex == ftdm_array_len(ftdmchan->history)) { + ftdmchan->hindex = 0; + } ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE); ftdm_mutex_lock(ftdmchan->span->mutex); @@ -1747,7 +1793,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t *best_rated = NULL; ftdm_status_t status = FTDM_FAIL; int best_rate = 0; - int may_be_available = 0; *ftdmchan = NULL; @@ -1782,38 +1827,55 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_mutex_lock(check->mutex); + /* The following if's and gotos replace a big if (this || this || this || this) else { nothing; } */ + + /* if it is not a voice channel, nothing else to check to open it */ + if (!FTDM_IS_VOICE_CHANNEL(check)) { + goto openchan; + } + + /* if it's an FXS device with a call active and has callwaiting enabled, we allow to open it twice */ + if (check->type == FTDM_CHAN_TYPE_FXS + && check->token_count == 1 + && ftdm_channel_test_feature(check, FTDM_CHANNEL_FEATURE_CALLWAITING)) { + goto openchan; + } + + /* if channel is available, time to open it */ + if (chan_is_avail(check)) { + goto openchan; + } + + /* not available, but still might be available ... */ calculate_best_rate(check, &best_rated, &best_rate); if (best_rated) { - may_be_available = 1; + goto openchan; } - /* the channel is only allowed to be open if not in use, or, for FXS devices with a call with call waiting enabled */ - if ( - (check->type == FTDM_CHAN_TYPE_FXS - && check->token_count == 1 - && ftdm_channel_test_feature(check, FTDM_CHANNEL_FEATURE_CALLWAITING)) - || - chan_is_avail(check) - || - may_be_available) { - if (!ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { - status = check->fio->open(check); - if (status == FTDM_SUCCESS) { - ftdm_set_flag(check, FTDM_CHANNEL_OPEN); - } - } else { - status = FTDM_SUCCESS; + /* channel is unavailable, do not open the channel */ + goto unlockchan; + +openchan: + if (!ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) { + status = check->fio->open(check); + if (status == FTDM_SUCCESS) { + ftdm_set_flag(check, FTDM_CHANNEL_OPEN); } - ftdm_set_flag(check, FTDM_CHANNEL_INUSE); - ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND); - *ftdmchan = check; + } else { + status = FTDM_SUCCESS; } + ftdm_set_flag(check, FTDM_CHANNEL_INUSE); + ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND); + *ftdmchan = check; +unlockchan: ftdm_mutex_unlock(check->mutex); done: - ftdm_mutex_unlock(globals.mutex); + if (status != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Failed to open channel %d:%d\n", span_id, chan_id); + } return status; } @@ -1996,11 +2058,17 @@ done: static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line) { ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP); + + ftdm_set_echocancel_call_end(chan); + if (chan->state != FTDM_CHANNEL_STATE_DOWN) { if (chan->state == FTDM_CHANNEL_STATE_HANGUP) { /* make user's life easier, and just ignore double hangup requests */ return FTDM_SUCCESS; } + if (chan->hangup_timer) { + ftdm_sched_cancel_timer(globals.timingsched, chan->hangup_timer); + } ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1); } else { /* the signaling stack did not touch the state, @@ -2158,10 +2226,12 @@ done: FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { ftdm_status_t status = FTDM_FAIL; - + ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel"); ftdm_assert_return(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), FTDM_FAIL, "Call place, but outbound flag not set\n"); + ftdm_set_echocancel_call_begin(ftdmchan); + ftdm_channel_lock(ftdmchan); if (ftdmchan->span->outgoing_call) { @@ -2282,6 +2352,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan) close_dtmf_debug(ftdmchan); #endif ftdm_channel_clear_vars(ftdmchan); + if (ftdmchan->hangup_timer) { + ftdm_sched_cancel_timer(globals.timingsched, ftdmchan->hangup_timer); + } ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN; ftdmchan->state = FTDM_CHANNEL_STATE_DOWN; @@ -3524,16 +3597,56 @@ done: return var; } -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan) +static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter) { - ftdm_hash_iterator_t *iter = NULL; + int allocated = 0; + if (iter) { + if (iter->type != type) { + ftdm_log(FTDM_LOG_ERROR, "Cannot switch iterator types\n"); + return NULL; + } + allocated = iter->allocated; + memset(iter, 0, sizeof(*iter)); + iter->type = type; + iter->allocated = allocated; + return iter; + } + iter = ftdm_calloc(1, sizeof(*iter)); + if (!iter) { + return NULL; + } + iter->type = type; + iter->allocated = 1; + return iter; +} + +FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter) +{ + ftdm_hash_iterator_t *hashiter = NULL; ftdm_channel_lock(ftdmchan); - - iter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); - + hashiter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash); ftdm_channel_unlock(ftdmchan); + + if (hashiter == NULL) { + return NULL; + } + + if (!(iter = get_iterator(FTDM_ITERATOR_VARS, iter))) { + return NULL; + } + iter->pvt.hashiter = hashiter; + return iter; +} + +FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter) +{ + if (!(iter = get_iterator(FTDM_ITERATOR_CHANS, iter))) { + return NULL; + } + iter->pvt.chaniter.index = 1; + iter->pvt.chaniter.span = span; return iter; } @@ -3545,11 +3658,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co *var_name = NULL; *var_val = NULL; - if (!iter) { - return FTDM_FAIL; - } + ftdm_assert_return(iter && (iter->type == FTDM_ITERATOR_VARS) && iter->pvt.hashiter, FTDM_FAIL, "Cannot get variable from invalid iterator!\n"); - hashtable_this(iter, &key, NULL, &val); + hashtable_this(iter->pvt.hashiter, &key, NULL, &val); *var_name = key; *var_val = val; @@ -3559,16 +3670,175 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter) { - if (!iter) { - return NULL; + ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); + + switch (iter->type) { + case FTDM_ITERATOR_VARS: + if (!iter->pvt.hashiter) { + return NULL; + } + iter->pvt.hashiter = hashtable_next(iter->pvt.hashiter); + if (!iter->pvt.hashiter) { + return NULL; + } + return iter; + case FTDM_ITERATOR_CHANS: + ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); + if (iter->pvt.chaniter.index == iter->pvt.chaniter.span->chan_count) { + return NULL; + } + iter->pvt.chaniter.index++; + return iter; + default: + break; } - return hashtable_next(iter); + + ftdm_assert_return(0, NULL, "Unknown iterator type\n"); + return NULL; +} + +FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter) +{ + const void *key = NULL; + void *val = NULL; + + ftdm_assert_return(iter && iter->type, NULL, "Invalid iterator\n"); + + switch (iter->type) { + case FTDM_ITERATOR_VARS: + hashtable_this(iter->pvt.hashiter, &key, NULL, &val); + /* I decided to return the key instead of the value since the value can be retrieved using the key */ + return (void *)key; + case FTDM_ITERATOR_CHANS: + ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n"); + ftdm_assert_return(iter->pvt.chaniter.index <= iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n"); + return iter->pvt.chaniter.span->channels[iter->pvt.chaniter.index]; + default: + break; + } + + ftdm_assert_return(0, NULL, "Unknown iterator type\n"); + return NULL; +} + +FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter) +{ + /* it's valid to pass a NULL iterator, do not return failure */ + if (!iter) { + return FTDM_SUCCESS; + } + + if (!iter->allocated) { + memset(iter, 0, sizeof(*iter)); + return FTDM_SUCCESS; + } + + ftdm_assert_return(iter->type, FTDM_FAIL, "Cannot free invalid iterator\n"); + ftdm_safe_free(iter); + + return FTDM_SUCCESS; } static struct { ftdm_io_interface_t *pika_interface; } interfaces; +static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count) +{ + ftdm_hash_iterator_t *i = NULL; + ftdm_span_t *span; + ftdm_channel_t *fchan = NULL; + ftdm_iterator_t *citer = NULL; + ftdm_iterator_t *curr = NULL; + const void *key = NULL; + void *val = NULL; + + *count = 0; + + ftdm_mutex_lock(globals.mutex); + + for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) { + hashtable_this(i, &key, NULL, &val); + if (!key || !val) { + break; + } + span = val; + citer = ftdm_span_get_chan_iterator(span, NULL); + if (!citer) { + continue; + } + for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) { + fchan = ftdm_iterator_current(curr); + if (not && (fchan->state != state)) { + stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n", + fchan->span_id, fchan->chan_id, + fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state)); + (*count)++; + } else if (!not && (fchan->state == state)) { + stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n", + fchan->span_id, fchan->chan_id, + fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state)); + (*count)++; + } + } + ftdm_iterator_free(citer); + } + + ftdm_mutex_unlock(globals.mutex); +} + +static char *handle_core_command(const char *cmd) +{ + char *mycmd = NULL; + int argc = 0; + int count = 0; + int not = 0; + char *argv[10] = { 0 }; + char *state = NULL; + ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID; + ftdm_stream_handle_t stream = { 0 }; + + FTDM_STANDARD_STREAM(stream); + + if (cmd) { + mycmd = ftdm_strdup(cmd); + argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } else { + stream.write_function(&stream, "invalid core command\n"); + goto done; + } + + if (!strcasecmp(argv[0], "state")) { + if (argc < 2) { + stream.write_function(&stream, "core state command requires an argument\n"); + goto done; + } + state = argv[1]; + if (argv[1][0] == '!') { + not = 1; + state++; + } + for (i = FTDM_CHANNEL_STATE_DOWN; i < FTDM_CHANNEL_STATE_INVALID; i++) { + if (!strcasecmp(state, ftdm_channel_state2str(i))) { + break; + } + } + if (i == FTDM_CHANNEL_STATE_INVALID) { + stream.write_function(&stream, "invalid state %s\n", state); + goto done; + } + print_channels_by_state(&stream, i, not, &count); + stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "not in state" : "in state", ftdm_channel_state2str(i), count); + } else { + stream.write_function(&stream, "invalid core command %s\n", argv[0]); + } + +done: + ftdm_safe_free(mycmd); + + return stream.data; +} + FT_DECLARE(char *) ftdm_api_execute(const char *cmd) { ftdm_io_interface_t *fio = NULL; @@ -3583,6 +3853,10 @@ FT_DECLARE(char *) ftdm_api_execute(const char *cmd) } type = dup; + + if (!strcasecmp(type, "core")) { + return handle_core_command(cmd); + } ftdm_mutex_lock(globals.mutex); if (!(fio = (ftdm_io_interface_t *) hashtable_search(globals.interface_hash, (void *)type))) { @@ -3884,7 +4158,14 @@ static ftdm_status_t load_config(void) ftdm_log(FTDM_LOG_ERROR, "unknown span variable '%s'\n", var); } } else if (!strncasecmp(cfg.category, "general", 7)) { - if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) { + if (!strncasecmp(var, "cpu_monitor", sizeof("cpu_monitor")-1)) { + if (!strncasecmp(val, "yes", 3)) { + globals.cpu_monitor.enabled = 1; + if (!globals.cpu_monitor.alarm_action_flags) { + globals.cpu_monitor.alarm_action_flags |= FTDM_CPU_ALARM_ACTION_WARN; + } + } + } else if (!strncasecmp(var, "cpu_monitoring_interval", sizeof("cpu_monitoring_interval")-1)) { if (atoi(val) > 0) { globals.cpu_monitor.interval = atoi(val); } else { @@ -3963,27 +4244,6 @@ static ftdm_status_t process_module_config(ftdm_io_interface_t *fio) return FTDM_SUCCESS; } -FT_DECLARE(char *) ftdm_build_dso_path(const char *name, char *path, ftdm_size_t len) -{ -#ifdef WIN32 - const char *ext = ".dll"; - //const char *EXT = ".DLL"; -#define FTDM_MOD_DIR "." //todo -#elif defined (MACOSX) || defined (DARWIN) - const char *ext = ".dylib"; - //const char *EXT = ".DYLIB"; -#else - const char *ext = ".so"; - //const char *EXT = ".SO"; -#endif - if (*name == *FTDM_PATH_SEPARATOR) { - snprintf(path, len, "%s%s", name, ext); - } else { - snprintf(path, len, "%s%s%s%s", FTDM_MOD_DIR, FTDM_PATH_SEPARATOR, name, ext); - } - return path; -} - FT_DECLARE(ftdm_status_t) ftdm_global_add_io_interface(ftdm_io_interface_t *interface1) { ftdm_status_t ret = FTDM_SUCCESS; @@ -4499,6 +4759,21 @@ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span) return FTDM_SUCCESS; } + +static void execute_safety_hangup(void *data) +{ + ftdm_channel_t *fchan = data; + ftdm_channel_lock(fchan); + fchan->hangup_timer = 0; + if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER); + call_hangup(fchan, __FILE__, __FUNCTION__, __LINE__); + } else { + ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state)); + } + ftdm_channel_unlock(fchan); +} + FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { if (sigmsg->channel) { @@ -4520,11 +4795,15 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t break; case FTDM_SIGEVENT_START: - /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was - * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if - * is needed at all? - * */ - ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD); + { + ftdm_set_echocancel_call_begin(sigmsg->channel); + + /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was + * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if + * is needed at all? + * */ + ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD); + } break; case FTDM_SIGEVENT_STOP: @@ -4532,6 +4811,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n"); goto done; } + if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) { + ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n"); + /* if the user does not move us to hangup in 2 seconds, we will do it ourselves */ + ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer); + } break; default: @@ -4630,12 +4914,6 @@ static void ftdm_cpu_monitor_stop(void) ftdm_interrupt_destroy(&globals.cpu_monitor.interrupt); } -FT_DECLARE(void) ftdm_cpu_monitor_disable(void) -{ - ftdm_cpu_monitor_disabled = 1; -} - - FT_DECLARE(ftdm_status_t) ftdm_global_init(void) { memset(&globals, 0, sizeof(globals)); @@ -4653,6 +4931,14 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void) ftdm_mutex_create(&globals.span_mutex); ftdm_mutex_create(&globals.group_mutex); ftdm_sched_global_init(); + if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n"); + return FTDM_FAIL; + } + if (ftdm_sched_free_run(globals.timingsched) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n"); + return FTDM_FAIL; + } globals.running = 1; return FTDM_SUCCESS; } @@ -4669,8 +4955,9 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void) ftdm_log(FTDM_LOG_NOTICE, "Modules configured: %d \n", modcount); + globals.cpu_monitor.enabled = 0; globals.cpu_monitor.interval = 1000; - globals.cpu_monitor.alarm_action_flags = FTDM_CPU_ALARM_ACTION_WARN | FTDM_CPU_ALARM_ACTION_REJECT; + globals.cpu_monitor.alarm_action_flags = 0; globals.cpu_monitor.set_alarm_threshold = 80; globals.cpu_monitor.reset_alarm_threshold = 70; @@ -4680,7 +4967,12 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void) return FTDM_FAIL; } - if (!ftdm_cpu_monitor_disabled) { + if (globals.cpu_monitor.enabled) { + ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d lo-thres:%d hi-thres:%d\n", + globals.cpu_monitor.interval, + globals.cpu_monitor.set_alarm_threshold, + globals.cpu_monitor.reset_alarm_threshold); + if (ftdm_cpu_monitor_start() != FTDM_SUCCESS) { return FTDM_FAIL; } @@ -4699,14 +4991,19 @@ FT_DECLARE(uint32_t) ftdm_running(void) FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void) { ftdm_span_t *sp; - uint32_t sanity = 100; time_end(); + /* many freetdm event loops rely on this variable to decide when to stop, do this first */ globals.running = 0; + /* stop the scheduling thread */ + ftdm_free_sched_stop(); + + /* stop the cpu monitor thread */ ftdm_cpu_monitor_stop(); + /* now destroy channels and spans */ globals.span_index = 0; ftdm_span_close_all(); @@ -4731,24 +5028,20 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void) globals.spans = NULL; ftdm_mutex_unlock(globals.span_mutex); + /* destroy signaling and io modules */ ftdm_unload_modules(); - while (ftdm_free_sched_running() && --sanity) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for schedule thread to finish\n"); - ftdm_sleep(100); - } - - if (!sanity) { - ftdm_log(FTDM_LOG_CRIT, "schedule thread did not stop running, we may crash on shutdown\n"); - } - + /* finally destroy the globals */ ftdm_mutex_lock(globals.mutex); + ftdm_sched_destroy(&globals.timingsched); hashtable_destroy(globals.interface_hash); - hashtable_destroy(globals.module_hash); + hashtable_destroy(globals.module_hash); hashtable_destroy(globals.span_hash); + hashtable_destroy(globals.group_hash); ftdm_mutex_unlock(globals.mutex); ftdm_mutex_destroy(&globals.mutex); ftdm_mutex_destroy(&globals.span_mutex); + ftdm_mutex_destroy(&globals.group_mutex); memset(&globals, 0, sizeof(globals)); return FTDM_SUCCESS; @@ -5071,6 +5364,42 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen) return new; } +FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan) +{ + char func[255]; + char line[255]; + char states[255]; + uint8_t i = 0; + + ftdm_stream_handle_t stream = { 0 }; + FTDM_STANDARD_STREAM(stream); + if (!fchan->history[0].file) { + stream.write_function(&stream, "-- No state history --\n"); + return stream.data; + } + + stream.write_function(&stream, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n"); + + for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) { + if (!fchan->history[i].file) { + break; + } + snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); + snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); + snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); + stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line); + } + + for (i = 0; i < fchan->hindex; i++) { + snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state)); + snprintf(func, sizeof(func), "[%s]", fchan->history[i].func); + snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line); + stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line); + } + + return stream.data; +} + /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/ftdm_sched.c b/libs/freetdm/src/ftdm_sched.c index 5aacc202bf..a7736ce8a2 100644 --- a/libs/freetdm/src/ftdm_sched.c +++ b/libs/freetdm/src/ftdm_sched.c @@ -34,6 +34,8 @@ #include "private/ftdm_core.h" +typedef struct ftdm_timer ftdm_timer_t; + static struct { ftdm_sched_t *freeruns; ftdm_mutex_t *mutex; @@ -42,6 +44,7 @@ static struct { struct ftdm_sched { char name[80]; + ftdm_timer_id_t currid; ftdm_mutex_t *mutex; ftdm_timer_t *timers; int freerun; @@ -51,6 +54,7 @@ struct ftdm_sched { struct ftdm_timer { char name[80]; + ftdm_timer_id_t id; #ifdef __linux__ struct timeval time; #endif @@ -172,6 +176,24 @@ FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void) return sched_globals.running; } +FT_DECLARE(ftdm_bool_t) ftdm_free_sched_stop(void) +{ + /* currently we really dont stop the thread here, we rely on freetdm being shutdown and ftdm_running() to be false + * so the scheduling thread dies and we just wait for it here */ + uint32_t sanity = 100; + while (ftdm_free_sched_running() && --sanity) { + ftdm_log(FTDM_LOG_DEBUG, "Waiting for main schedule thread to finish\n"); + ftdm_sleep(100); + } + + if (!sanity) { + ftdm_log(FTDM_LOG_CRIT, "schedule thread did not stop running, we may crash on shutdown\n"); + return FTDM_FALSE; + } + + return FTDM_TRUE; +} + FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name) { ftdm_sched_t *newsched = NULL; @@ -191,6 +213,7 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *na } ftdm_set_string(newsched->name, name); + newsched->currid = 1; *sched = newsched; ftdm_log(FTDM_LOG_DEBUG, "Created schedule %s\n", name); @@ -219,12 +242,13 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_run(ftdm_sched_t *sched) int rc = -1; void *data; struct timeval now; + ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n"); - ftdm_mutex_lock(sched->mutex); - tryagain: + ftdm_mutex_lock(sched->mutex); + rc = gettimeofday(&now, NULL); if (rc == -1) { ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n"); @@ -257,11 +281,16 @@ tryagain: runtimer->prev->next = runtimer->next; } + runtimer->id = 0; ftdm_safe_free(runtimer); + /* avoid deadlocks by releasing the sched lock before triggering callbacks */ + ftdm_mutex_unlock(sched->mutex); + callback(data); /* after calling a callback we must start the scanning again since the - * callback may have added or cancelled timers to the linked list */ + * callback or some other thread may have added or cancelled timers to + * the linked list */ goto tryagain; } } @@ -283,7 +312,7 @@ done: } FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, - int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_t **timer) + int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timerid) { ftdm_status_t status = FTDM_FAIL; #ifdef __linux__ @@ -296,8 +325,8 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name ftdm_assert_return(callback != NULL, FTDM_EINVAL, "sched callback is null!\n"); ftdm_assert_return(ms > 0, FTDM_EINVAL, "milliseconds must be bigger than 0!\n"); - if (timer) { - *timer = NULL; + if (timerid) { + *timerid = 0; } rc = gettimeofday(&now, NULL); @@ -312,6 +341,15 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name if (!newtimer) { goto done; } + newtimer->id = sched->currid; + sched->currid++; + if (!sched->currid) { + ftdm_log(FTDM_LOG_NOTICE, "Timer id wrap around for sched %s\n", sched->name); + /* we do not want currid to be zero since is an invalid id + * TODO: check that currid does not exists already in the context, it'd be insane + * though, having a timer to live all that time */ + sched->currid++; + } ftdm_set_string(newtimer->name, name); newtimer->callback = callback; @@ -332,9 +370,10 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name sched->timers = newtimer; } - if (timer) { - *timer = newtimer; + if (timerid) { + *timerid = newtimer->id; } + status = FTDM_SUCCESS; done: @@ -349,7 +388,7 @@ done: UNREFERENCED_PARAMETER(ms); UNREFERENCED_PARAMETER(callback); UNREFERENCED_PARAMETER(data); - UNREFERENCED_PARAMETER(timer); + UNREFERENCED_PARAMETER(timerid); #endif return status; } @@ -418,53 +457,37 @@ done: return status; } -FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_t **intimer) +FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timerid) { ftdm_status_t status = FTDM_FAIL; ftdm_timer_t *timer; ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n"); - ftdm_assert_return(intimer != NULL, FTDM_EINVAL, "timer is null!\n"); - ftdm_assert_return(*intimer != NULL, FTDM_EINVAL, "timer is null!\n"); + + if (!timerid) { + return FTDM_SUCCESS; + } ftdm_mutex_lock(sched->mutex); - /* special case where the cancelled timer is the head */ - if (*intimer == sched->timers) { - timer = *intimer; - /* the timer next is the new head (even if that means the new head will be NULL)*/ - sched->timers = timer->next; - /* if there is a new head, clean its prev member */ - if (sched->timers) { - sched->timers->prev = NULL; - } - /* free the old head */ - ftdm_safe_free(timer); - status = FTDM_SUCCESS; - *intimer = NULL; - goto done; - } - - /* look for the timer and destroy it (we know now that is not head, se we start at the next member after head) */ - for (timer = sched->timers->next; timer; timer = timer->next) { - if (timer == *intimer) { + /* look for the timer and destroy it */ + for (timer = sched->timers; timer; timer = timer->next) { + if (timer->id == timerid) { + if (timer == sched->timers) { + /* it's the head timer, put a new head */ + sched->timers = timer->next; + } if (timer->prev) { timer->prev->next = timer->next; } if (timer->next) { timer->next->prev = timer->prev; } - ftdm_log(FTDM_LOG_DEBUG, "cancelled timer %s\n", timer->name); ftdm_safe_free(timer); status = FTDM_SUCCESS; - *intimer = NULL; break; } } -done: - if (status == FTDM_FAIL) { - ftdm_log(FTDM_LOG_ERROR, "Could not find timer %s to cancel it\n", (*intimer)->name); - } ftdm_mutex_unlock(sched->mutex); diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index ba4049a32f..bb62f07754 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -1087,10 +1087,17 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj) got_d = 1; x++; break; + } else { + ftdm_log(FTDM_LOG_ERROR, "failed to open d-channel #%d %d:%d\n", x, span->channels[i]->span_id, span->channels[i]->chan_id); } } } } + + if (!got_d) { + ftdm_log(FTDM_LOG_ERROR, "Failed to get a D-channel in span %d\n", span->span_id); + break; + } if (lpwrap_init_pri(&isdn_data->spri, @@ -1133,7 +1140,9 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj) } ftdm_log(FTDM_LOG_CRIT, "PRI down on span %d\n", isdn_data->spri.span->span_id); - isdn_data->spri.dchan->state = FTDM_CHANNEL_STATE_DOWN; + if (isdn_data->spri.dchan) { + isdn_data->spri.dchan->state = FTDM_CHANNEL_STATE_DOWN; + } if (!down) { ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART); @@ -1147,7 +1156,7 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj) ftdm_sleep(5000); } - ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", isdn_data->spri.span->span_id); + ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", span->span_id); ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD); ftdm_clear_flag(isdn_data, FTMOD_LIBPRI_RUNNING); diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index b286ec1df6..8dfba34ec3 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -177,7 +177,7 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t * spri->dchan = dchan; spri->span = span; - if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){ + if (spri->dchan && (spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){ unsigned char buf[4] = { 0 }; size_t buflen = sizeof(buf), len = 0; pri_set_debug(spri->pri, debug); diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index 9ffd7097a3..08f340dc83 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 @@ -189,7 +189,8 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_DOWN, FTDM_END} + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, + FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_DOWN, FTDM_END} }, { ZSD_OUTBOUND, @@ -471,10 +472,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_RING: /* incoming call request */ { ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending incoming call from %s to %s to FTDM core\n", ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.dnis.digits); - ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); - ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap"); - ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s"); - ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad"); + /* we have enough information to inform FTDM of the call*/ sigev.event_id = FTDM_SIGEVENT_START; ftdm_span_send_signal(ftdmchan->span, &sigev); @@ -558,6 +556,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) /* We are hangup local call because there was a glare, we are waiting for a RELEASE on this call, before we can process the saved call */ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Waiting for RELEASE on hungup glared call\n"); + } else if (sngisdn_test_flag(sngisdn_info, FLAG_SEND_DISC)) { + /* Remote side sent a PROGRESS message, but cause indicates disconnect or T310 expired*/ + sngisdn_snd_disconnect(ftdmchan); } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Hanging up call upon local request!\n"); @@ -568,16 +569,15 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan) if (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALING) { + sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); + sngisdn_snd_release(ftdmchan, 0); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); } - - sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); - sngisdn_snd_release(ftdmchan, 0); } else { sngisdn_snd_disconnect(ftdmchan); } - } /* now go to the HANGUP complete state */ @@ -691,7 +691,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call) return status; } -static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_sig_status) +static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_chan_sig_status) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { *status = FTDM_SIG_STATE_UP; @@ -702,17 +702,34 @@ static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_sig_status) return FTDM_SUCCESS; } -static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_sig_status) +static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_chan_sig_status) { ftdm_log(FTDM_LOG_ERROR,"Cannot set channel status in this module\n"); return FTDM_NOTIMPL; } +static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_span_sig_status) +{ + if (ftdm_test_flag(span->channels[1], FTDM_CHANNEL_SIG_UP)) { + *status = FTDM_SIG_STATE_UP; + } else { + *status = FTDM_SIG_STATE_DOWN; + } + + return FTDM_SUCCESS; +} + +static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status) +{ + ftdm_log(FTDM_LOG_ERROR,"Cannot set span status in this module\n"); + return FTDM_NOTIMPL; +} + static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) { ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id); - if (sng_isdn_stack_activate(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "Failed to activate span %s\n", span->name); + if (sng_isdn_stack_start(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name); return FTDM_FAIL; } /* clear the monitor thread stop flag */ @@ -731,7 +748,8 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span) static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) { - unsigned i; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; ftdm_log(FTDM_LOG_INFO, "Stopping span %s\n", span->name); /* throw the STOP_THREAD flag to signal monitor thread stop */ @@ -743,11 +761,19 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) ftdm_sleep(10); } - /* FIXME: deconfigure any links, attached to this span */ - /* TODO: Use Moy's channel Iterator when its implemented */ - for (i=1;i<=span->chan_count;i++) { - ftdm_safe_free(span->channels[i]->call_data); + if (sng_isdn_stack_stop(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "Failed to stop span %s\n", span->name); } + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdm_safe_free(((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data); + ((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = NULL; + } + ftdm_iterator_free(chaniter); + + ftdm_sched_destroy(&((sngisdn_span_data_t*)span->signal_data)->sched); + ftdm_queue_destroy(&((sngisdn_span_data_t*)span->signal_data)->event_queue); ftdm_safe_free(span->signal_data); ftdm_log(FTDM_LOG_DEBUG, "Finished stopping span %s\n", span->name); @@ -757,6 +783,9 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span) static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) { + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + sngisdn_span_data_t *span_data; ftdm_log(FTDM_LOG_INFO, "Configuring ftmod_sangoma_isdn span = %s\n", span->name); @@ -764,13 +793,15 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) span_data = ftdm_calloc(1, sizeof(sngisdn_span_data_t)); span_data->ftdm_span = span; span->signal_data = span_data; - - unsigned i; - for (i=1;i <= span->chan_count; i++) { + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { sngisdn_chan_data_t *chan_data = ftdm_calloc(1, sizeof(sngisdn_chan_data_t)); - chan_data->ftdmchan = span->channels[i]; - span->channels[i]->call_data = chan_data; + chan_data->ftdmchan = ((ftdm_channel_t*)ftdm_iterator_current(curr)); + ((ftdm_channel_t*)ftdm_iterator_current(curr))->call_data = chan_data; + } + ftdm_iterator_free(chaniter); if (ftmod_isdn_parse_cfg(ftdm_parameters, span) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Failed to parse configuration\n"); @@ -789,8 +820,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) span->outgoing_call = ftdm_sangoma_isdn_outgoing_call; span->channel_request = NULL; span->signal_cb = sig_cb; - span->get_channel_sig_status = ftdm_sangoma_isdn_get_sig_status; - span->set_channel_sig_status = ftdm_sangoma_isdn_set_sig_status; + span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status; + span->set_channel_sig_status = ftdm_sangoma_isdn_set_chan_sig_status; + span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status; + span->set_span_sig_status = ftdm_sangoma_isdn_set_span_sig_status; span->state_map = &sangoma_isdn_state_map; ftdm_set_flag(span, FTDM_SPAN_USE_CHAN_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); @@ -852,7 +885,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) for(i=1;i<=MAX_VARIANTS;i++) { ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex); } - + /* initalize sng_isdn library */ sng_isdn_init(&g_sngisdn_event_interface); return FTDM_SUCCESS; @@ -920,16 +953,35 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api) if (!strcasecmp(argv[0], "l1_stats")) { ftdm_span_t *span; if (argc < 2) { - ftdm_log(FTDM_LOG_ERROR, "Usage: ftdm sangoma_isdn l1_stats <span name>\n"); + stream->write_function(stream, "Usage: ftdm sangoma_isdn l1_stats <span name>\n"); 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 by name %s\n", argv[2]); + 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; goto done; } - /* TODO: implement PHY stats */ + sngisdn_print_phy_stats(stream, span); + } + + if (!strcasecmp(argv[0], "show_spans")) { + ftdm_span_t *span = NULL; + if (argc == 2) { + 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; + goto done; + } + sngisdn_print_span(stream, span); + status = FTDM_SUCCESS; + goto done; + } + sngisdn_print_spans(stream); } if (!strcasecmp(argv[0], "check_ids")) { sngisdn_check_free_ids(); 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 3f63fbc1d4..ae6c0d92f7 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 @@ -68,6 +68,7 @@ typedef enum { FLAG_GLARE = (1 << 6), FLAG_DELAYED_REL = (1 << 7), FLAG_SENT_PROCEED = (1 << 8), + FLAG_SEND_DISC = (1 << 9), } sngisdn_flag_t; @@ -127,6 +128,13 @@ typedef enum { SNGISDN_EVENT_RST_IND, } ftdm_sngisdn_event_id_t; +/* Only timers that can be cancelled are listed here */ +#define SNGISDN_NUM_TIMERS 1 +/* Increase NUM_TIMERS as number of ftdm_sngisdn_timer_t increases */ +typedef enum { + SNGISDN_TIMER_FACILITY = 0, +} ftdm_sngisdn_timer_t; + typedef struct sngisdn_glare_data { int16_t suId; uint32_t suInstId; @@ -148,6 +156,7 @@ typedef struct sngisdn_chan_data { uint8_t globalFlg; sngisdn_glare_data_t glare; + ftdm_timer_id_t timers[SNGISDN_NUM_TIMERS]; } sngisdn_chan_data_t; /* Span specific data */ @@ -165,6 +174,7 @@ typedef struct sngisdn_span_data { uint8_t overlap_dial; uint8_t setup_arb; uint8_t facility; + int8_t facility_timeout; ftdm_sched_t *sched; ftdm_queue_t *event_queue; } sngisdn_span_data_t; @@ -223,8 +233,8 @@ typedef struct sngisdn_cc { ftdm_trunk_type_t trunktype; uint32_t last_suInstId; ftdm_mutex_t *mutex; - sngisdn_chan_data_t *active_spInstIds[MAX_INSTID]; - sngisdn_chan_data_t *active_suInstIds[MAX_INSTID]; + sngisdn_chan_data_t *active_spInstIds[MAX_INSTID+1]; + sngisdn_chan_data_t *active_suInstIds[MAX_INSTID+1]; }sngisdn_cc_t; /* Global sngisdn data */ @@ -233,7 +243,8 @@ typedef struct ftdm_sngisdn_data { uint8_t num_cc; /* 1 ent per switchtype */ struct sngisdn_cc ccs[MAX_VARIANTS+1]; uint8_t num_dchan; - sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1]; + sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1]; + sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */ }ftdm_sngisdn_data_t; @@ -349,12 +360,16 @@ void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t void sngisdn_delayed_release(void* p_sngisdn_info); void sngisdn_delayed_connect(void* p_sngisdn_info); void sngisdn_delayed_disconnect(void* p_sngisdn_info); +void sngisdn_facility_timeout(void* p_sngisdn_info); /* Stack management functions */ ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span); - +ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span); +ftdm_status_t sng_isdn_stack_stop(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); #endif /* __FTMOD_SNG_ISDN_H__ */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index ec44142303..361b389f96 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -62,7 +62,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) } break; case FTDM_TRUNK_E1: - if (!strcasecmp(switch_name, "euroisdn") || strcasecmp(switch_name, "etsi")) { + if (!strcasecmp(switch_name, "euroisdn") || + !strcasecmp(switch_name, "etsi")) { signal_data->switchtype = SNGISDN_SWITCH_EUROISDN; } else if (!strcasecmp(switch_name, "qsig")) { signal_data->switchtype = SNGISDN_SWITCH_QSIG; @@ -116,6 +117,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span) signal_data->span_id = dchan_data->num_spans; dchan_data->spans[signal_data->span_id] = signal_data; + + g_sngisdn_data.spans[signal_data->link_id] = signal_data; ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id); @@ -163,6 +166,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ signal_data->overlap_dial = SNGISDN_OPT_DEFAULT; signal_data->setup_arb = SNGISDN_OPT_DEFAULT; + signal_data->link_id = span->span_id; span->default_caller_data.bearer_capability = IN_ITC_SPEECH; /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */ @@ -249,11 +253,16 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability); } else if (!strcasecmp(var, "outbound-bearer_layer1")) { ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1); + } else if (!strcasecmp(var, "facility-timeout")) { + signal_data->facility_timeout = atoi(val); + if (signal_data->facility_timeout < 0) { + signal_data->facility_timeout = 0; + } } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } } - signal_data->link_id = span->span_id; + if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) { ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name); return FTDM_FAIL; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c index 7aba6a66ce..5060cb6bba 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c @@ -35,7 +35,6 @@ #include "ftmod_sangoma_isdn.h" - void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status); void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) @@ -53,23 +52,21 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status return; } +void sngisdn_set_span_sig_status(ftdm_span_t *span, ftdm_signaling_status_t status) +{ + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; -void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status) -{ - unsigned i; - /* TODO: use channel iterator once it is implemented */ - - for (i=1;i<=ftdmspan->chan_count;i++) { - sngisdn_set_chan_sig_status(ftdmspan->channels[i], status); + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + sngisdn_set_chan_sig_status(((ftdm_channel_t*)ftdm_iterator_current(curr)), status); } + ftdm_iterator_free(chaniter); return; } - - - /* For Emacs: * Local Variables: * mode:c 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 f84e018f1e..7f3c4c3d07 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c @@ -193,10 +193,12 @@ ftdm_status_t sng_isdn_stack_cfg_phy_gen(void) ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span) { - /*local variables*/ - L1Mngmt cfg; /*configuration structure*/ - Pst pst; /*post structure*/ + ftdm_iterator_t *chaniter; + ftdm_iterator_t *curr; + L1Mngmt cfg; + Pst pst; + S32 d_channel_fd = -1; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; /* initalize the post structure */ @@ -219,20 +221,35 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span) cfg.hdr.elmId.elmntInst1 = signal_data->link_id; - cfg.t.cfg.s.l1PSAP.span = span->channels[1]->physical_span_id; + + /* Find the d-channel */ + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); + if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) { + d_channel_fd = ftdmchan->sockfd; + break; + } + } + ftdm_iterator_free(chaniter); + + if(d_channel_fd < 0) { + ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name); + return FTDM_FAIL; + } + + cfg.t.cfg.s.l1PSAP.sockfd = d_channel_fd; + switch(span->trunk_type) { case FTDM_TRUNK_E1: - cfg.t.cfg.s.l1PSAP.chan = 16; cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI; break; case FTDM_TRUNK_T1: case FTDM_TRUNK_J1: - cfg.t.cfg.s.l1PSAP.chan = 24; cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI; break; case FTDM_TRUNK_BRI: case FTDM_TRUNK_BRI_PTMP: - cfg.t.cfg.s.l1PSAP.chan = 3; cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_BRI; break; default: @@ -608,9 +625,10 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.hdr.entId.ent = ENTIN; cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STDLSAP; - + cfg.hdr.response.selector=0; + cfg.t.cfg.s.inDLSAP.sapId = signal_data->link_id; cfg.t.cfg.s.inDLSAP.spId = signal_data->link_id; cfg.t.cfg.s.inDLSAP.swtch = sng_isdn_stack_switchtype(signal_data->switchtype); @@ -656,8 +674,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.t.cfg.s.inDLSAP.ctldInt[1] = 1; } - cfg.t.cfg.s.inDLSAP.numRstInd = 255; - cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; + cfg.t.cfg.s.inDLSAP.numRstInd = 255; cfg.t.cfg.s.inDLSAP.relOpt = TRUE; #ifdef ISDN_SRV cfg.t.cfg.s.inDLSAP.bcas = FALSE; @@ -666,16 +683,19 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span) #endif /* ISDN_SRV */ if (signal_data->signalling == SNGISDN_SIGNALING_NET) { + cfg.t.cfg.s.inDLSAP.ackOpt = TRUE; cfg.t.cfg.s.inDLSAP.intType = NETWORK; cfg.t.cfg.s.inDLSAP.clrGlr = FALSE; /* in case of glare, do not clear local call */ cfg.t.cfg.s.inDLSAP.statEnqOpt = TRUE; - if (span->trunk_type == FTDM_TRUNK_BRI || - span->trunk_type == FTDM_TRUNK_BRI_PTMP) { + + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || + signal_data->switchtype == SNGISDN_SWITCH_INSNET) { cfg.t.cfg.s.inDLSAP.rstOpt = FALSE; } else { cfg.t.cfg.s.inDLSAP.rstOpt = TRUE; } } else { + cfg.t.cfg.s.inDLSAP.ackOpt = FALSE; cfg.t.cfg.s.inDLSAP.intType = USER; cfg.t.cfg.s.inDLSAP.clrGlr = TRUE; /* in case of glare, clear local call */ cfg.t.cfg.s.inDLSAP.statEnqOpt = FALSE; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c index f92eceda5e..cea8ac0173 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c @@ -38,8 +38,8 @@ void stack_resp_hdr_init(Header *hdr); ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span); -ftdm_status_t sng_isdn_activate_q921(ftdm_span_t *span); -ftdm_status_t sng_isdn_activate_q931(ftdm_span_t *span); +ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span); + ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span); ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt); @@ -52,14 +52,23 @@ extern ftdm_sngisdn_data_t g_sngisdn_data; ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span); -ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span) +ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - if (sng_isdn_activate_q921(span) != FTDM_SUCCESS) { + + if (sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q921\n", span->name); return FTDM_FAIL; } + + /* Try to find an alternative for this */ + /* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1, + so we need to give some time before activating q931, as q931 will send a + LdUiDatConReq when activated, and this requires the Mac SAP to be already + bound first */ + ftdm_sleep(500); + ftdm_log(FTDM_LOG_DEBUG, "%s:Stack q921 activated\n", span->name); if (!g_sngisdn_data.ccs[signal_data->cc_id].activation_done) { g_sngisdn_data.ccs[signal_data->cc_id].activation_done = 1; @@ -70,7 +79,8 @@ ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span) ftdm_log(FTDM_LOG_DEBUG, "%s:Stack CC activated\n", span->name); } - if (sng_isdn_activate_q931(span) != FTDM_SUCCESS) { + + if (sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_CRIT, "%s:Failed to activate stack q931\n", span->name); return FTDM_FAIL; } @@ -80,50 +90,72 @@ ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span) return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span) +ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span) { + /* Stop L1 first, so we do not receive any more frames */ + if (sng_isdn_deactivate_phy(span) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack phy\n", span->name); + return FTDM_FAIL; + } + if (sng_isdn_cntrl_q931(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q931\n", span->name); + return FTDM_FAIL; + } + + if (sng_isdn_cntrl_q921(span, AUBND_DIS, SAELMNT) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_CRIT, "%s:Failed to deactivate stack q921\n", span->name); + return FTDM_FAIL; + } + + ftdm_log(FTDM_LOG_INFO, "%s:Signalling stopped\n", span->name); return FTDM_SUCCESS; } ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span) +{ + + /* There is no need to start phy, as it will Q921 will send a activate request to phy when it starts */ + + return FTDM_SUCCESS; +} + +ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span) { L1Mngmt cntrl; - Pst pst; + Pst pst; - ftdm_log(FTDM_LOG_ERROR, "%s:PHY control not implemented\n", span->name); - return FTDM_SUCCESS; - /* TODO: phy cntrl not implemented yet */ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data; - sng_isdn_phy_cntrl(&pst, &cntrl); + /* initalize the post structure */ + stack_pst_init(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTL1; + + /* initalize the control structure */ + memset(&cntrl, 0, sizeof(cntrl)); + + /* initalize the control header */ + stack_hdr_init(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* configuration */ + cntrl.hdr.entId.ent = ENTL1; /* entity */ + cntrl.hdr.entId.inst = S_INST; /* instance */ + cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */ + + cntrl.t.cntrl.action = AUBND_DIS; + cntrl.t.cntrl.subAction = SAELMNT; + cntrl.t.cntrl.sapId = signal_data->link_id; + + if (sng_isdn_phy_cntrl(&pst, &cntrl)) { + return FTDM_FAIL; + } return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_activate_q921(ftdm_span_t *span) -{ - ftdm_status_t status; - status = sng_isdn_cntrl_q921(span, ABND_ENA, NOTUSED); - - /* Try to find an alternative for this */ - /* LAPD will call LdUiDatBndCfm before it received a LdLiMacBndCfm from L1, - so we need to give some time before activating q931, as q931 will send a - LdUiDatConReq when activated, and this requires the Mac SAP to be already - bound first */ - - if (status == FTDM_SUCCESS) { - ftdm_sleep(500); - } - return status; -} - -ftdm_status_t sng_isdn_activate_q931(ftdm_span_t *span) -{ - /* TODO: remove this function later, just call sng_isdn_cntrl_q931 directly */ - return sng_isdn_cntrl_q931(span, ABND_ENA, SAELMNT); -} - ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span) { CcMngmt cntrl;; @@ -167,7 +199,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra ftdm_log(FTDM_LOG_INFO, "s%d Disabling q921 trace\n", signal_data->link_id); sngisdn_clear_trace_flag(signal_data, SNGISDN_TRACE_Q921); - if (sng_isdn_cntrl_q921(span, ADISIMM, SAELMNT) != FTDM_SUCCESS) { + if (sng_isdn_cntrl_q921(span, ADISIMM, SATRC) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "s%d Failed to disable q921 trace\n"); } } 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 c3d97e5c5c..b7af8e98c5 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 @@ -78,14 +78,13 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) } sngisdn_info->suInstId = get_unique_suInstId(suId); - sngisdn_info->spInstId = spInstId; + sngisdn_info->spInstId = spInstId; /* If this is a glared call that was previously saved, we moved all the info to the current call, so clear the glared saved data */ - if (sngisdn_info->glare.spInstId == spInstId) { clear_call_glare_data(sngisdn_info); - } + } ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info; @@ -105,7 +104,15 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); break; - } + } + +#if 0 + /* Export ftdmchan variables here if we need to */ + ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1"); + ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap"); + ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s"); + ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad"); +#endif /* Fill in call information */ cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb); cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb); @@ -124,14 +131,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) } - if (conEvnt->facilityStr.eh.pres) { + if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) { /* Verify whether the Caller Name will come in a subsequent FACILITY message */ uint16_t ret_val; - uint8_t facility_str[255]; char retrieved_str[255]; - memcpy(facility_str, (uint8_t*)&conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len); - - ret_val = sng_isdn_retrieve_facility_caller_name(facility_str, conEvnt->facilityStr.facilityStr.len, retrieved_str); + + ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); /* return values for "sng_isdn_retrieve_facility_information_following": If there will be no information following, or fails to decode IE, returns -1 @@ -142,6 +147,11 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) if (ret_val == 1) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID); + /* Launch timer in case we never get a FACILITY msg */ + if (signal_data->facility_timeout) { + ftdm_sched_timer(signal_data->sched, "facility_timeout", signal_data->facility_timeout, + sngisdn_facility_timeout, (void*) sngisdn_info, &sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + } break; } else if (ret_val == 0) { strcpy(ftdmchan->caller_data.cid_name, retrieved_str); @@ -263,6 +273,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) /* This is the only valid state we should get a CONNECT ACK on */ /* do nothing */ break; + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + /* We just hung up an incoming call right after we sent a CONNECT so ignore this message */ + break; default: ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state)); @@ -289,6 +302,8 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n"); @@ -302,19 +317,49 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) suId, suInstId, spInstId, ces); switch(evntType) { + case MI_PROGRESS: + if (signal_data->switchtype == SNGISDN_SWITCH_NI2 && + cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) { + + switch(cnStEvnt->causeDgn[0].causeVal.val) { + case 17: /* User Busy */ + case 18: /* No User responding */ + case 19: /* User alerting, no answer */ + case 21: /* Call rejected, the called party does not with to accept this call */ + case 27: /* Destination out of order */ + case 31: /* Normal, unspecified */ + case 34: /* Circuit/Channel congestion */ + case 41: /* Temporary failure */ + case 42: /* Switching equipment is experiencing a period of high traffic */ + case 47: /* Resource unavailable */ + case 58: /* Bearer Capability not available */ + case 63: /* Service or option not available */ + case 65: /* Bearer Cap not implemented, not supported */ + case 79: /* Service or option not implemented, unspecified */ + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val); + ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val; + + sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + goto sngisdn_process_cnst_ind_end; + } + } + /* fall-through */ case MI_ALERTING: case MI_CALLPROC: - case MI_PROGRESS: + switch(ftdmchan->state) { - case FTDM_CHANNEL_STATE_DIALING: - if (evntType == MI_PROGRESS) { + case FTDM_CHANNEL_STATE_DIALING: + if (evntType == MI_PROGRESS || + (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); } break; case FTDM_CHANNEL_STATE_PROGRESS: - if (evntType == MI_PROGRESS) { + if (evntType == MI_PROGRESS || + (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } break; @@ -371,6 +416,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) break; } +sngisdn_process_cnst_ind_end: ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } @@ -638,12 +684,14 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event) void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); + int16_t suId = sngisdn_event->suId; uint32_t suInstId = sngisdn_event->suInstId; uint32_t spInstId = sngisdn_event->spInstId; sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; FacEvnt *facEvnt = &sngisdn_event->event.facEvnt; @@ -653,16 +701,31 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_GET_CALLERID: /* Update the caller ID Name */ if (facEvnt->facElmt.facStr.pres) { - uint8_t facility_str[255]; - memcpy(facility_str, (uint8_t*)&facEvnt->facElmt.facStr.val, facEvnt->facElmt.facStr.len); char retrieved_str[255]; - if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) { + + /* return values for "sng_isdn_retrieve_facility_information_following": + If there will be no information following, or fails to decode IE, returns -1 + If there will be no information following, but current FACILITY IE contains a caller name, returns 0 + If there will be information following, returns 1 + */ + + 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"); } + if (signal_data->facility_timeout) { + /* Cancel facility timeout */ + ftdm_sched_cancel_timer(signal_data->sched, sngisdn_info->timers[SNGISDN_TIMER_FACILITY]); + } } ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); break; + case FTDM_CHANNEL_STATE_RING: + /* We received the caller ID Name in FACILITY, but its too late, facility-timeout already occurred */ + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "FACILITY received, but we already proceeded with call\n"); + break; default: /* We do not support other FACILITY types for now, so do nothing */ break; @@ -794,6 +857,14 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; case 3: switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_PROGRESS: + /* T310 timer has expired */ + ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val; + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T310 Timer expired, hanging up call\n"); + sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + + break; case FTDM_CHANNEL_STATE_UP: /* Remote side is still waiting for our CONNECT message */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { @@ -821,6 +892,22 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; } break; + case 9: /* Remote switch is in "Incoming call proceeding" state */ + switch (ftdmchan->state) { + case FTDM_CHANNEL_STATE_PROGRESS: + case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: + case FTDM_CHANNEL_STATE_GET_CALLERID: + /* Do nothing */ + break; + case FTDM_CHANNEL_STATE_UP: + /* Remote switch missed our CONNECT message, re-send */ + ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL); + break; + default: + ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); + break; + } + break; case 10: /* Remote switch is in active state */ switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_UP: @@ -836,17 +923,6 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event) break; } break; - case 9: - switch (ftdmchan->state) { - case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - /* Do nothing */ - break; - default: - ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state)); - break; - } - break; case 22: switch (ftdmchan->state) { case FTDM_CHANNEL_STATE_UP: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c index 6e8e0e81fd..80a85ceec8 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c @@ -409,7 +409,7 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { + if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -450,6 +450,14 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan) cnStEvnt.chanId.chanNmbSlotMap.len = 1; cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id; } + + cnStEvnt.progInd.eh.pres = PRSNT_NODEF; + cnStEvnt.progInd.location.pres = PRSNT_NODEF; + cnStEvnt.progInd.location.val = IN_LOC_USER; + cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF; + cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT; + cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF; + cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */ ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces); if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) { 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 29cfb2330e..791c6b7d8c 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 @@ -45,8 +45,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); uint8_t bchan_no = 0; - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Ind on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Ind on unconfigured dchan\n"); @@ -96,7 +96,7 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); memcpy(&sngisdn_event->event.conEvnt, conEvnt, sizeof(*conEvnt)); - + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -104,8 +104,8 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Cfm on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Cfm on unconfigured dchan\n"); @@ -118,6 +118,7 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn if (!sngisdn_info->spInstId) { ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); @@ -146,8 +147,8 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Cnst Ind on unconfigured cc\n"); ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Cnst Ind on unconfigured dchan\n"); @@ -160,6 +161,7 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C if (!sngisdn_info->spInstId) { ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); + sngisdn_info->spInstId = spInstId; g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); @@ -188,15 +190,15 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id"); @@ -207,13 +209,6 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D ftdm_assert(0, "Inconsistent call states\n"); return; } - - if (!sngisdn_info->spInstId) { - ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex); - sngisdn_info->spInstId = spInstId; - g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info; - ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex); - } ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); @@ -229,7 +224,7 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D memcpy(&sngisdn_event->event.discEvnt, discEvnt, sizeof(*discEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -237,21 +232,22 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_chan_data_t *sngisdn_info = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); - ftdm_assert(0, "Inconsistent call states\n"); + /* It seems that Trillium has a bug where they sometimes send release twice on a call, so do not crash on these for now */ + /* ftdm_assert(0, "Inconsistent call states\n"); */ return; } ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_REL_IND; @@ -270,7 +266,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -283,7 +279,7 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DATA IND suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_DAT_IND; @@ -302,7 +298,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -315,7 +311,7 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SSHL_IND; @@ -335,7 +331,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -348,7 +344,7 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SSHL_CFM; @@ -360,14 +356,14 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action) { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -380,7 +376,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RMRT IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RMRT_IND; @@ -392,7 +388,7 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -400,7 +396,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -413,7 +409,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RMRT_CFM; @@ -425,7 +421,7 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -433,7 +429,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -446,7 +442,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_FLC_IND; @@ -457,7 +453,7 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt)); - ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -466,7 +462,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -478,7 +474,7 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_FAC_IND; @@ -499,7 +495,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); sngisdn_chan_data_t *sngisdn_info; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) && !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) { @@ -512,7 +508,7 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId); sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_STA_CFM; @@ -532,7 +528,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces); @@ -540,7 +536,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SRV_IND; @@ -550,7 +546,7 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces sngisdn_event->signal_data = signal_data; memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt)); - ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); + ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event); } ISDN_FUNC_TRACE_EXIT(__FUNCTION__); } @@ -560,8 +556,8 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_span_data_t *signal_data = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces); @@ -569,7 +565,7 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_SRV_CFM; @@ -588,16 +584,17 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces { ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; - sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_span_data_t *signal_data = NULL; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received RESTART IND (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); /* Enqueue the event to each span within the dChan */ for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; + sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RST_IND; @@ -618,7 +615,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces ISDN_FUNC_TRACE_ENTER(__FUNCTION__); unsigned i; sngisdn_span_data_t *signal_data; - sngisdn_event_data_t *sngisdn_event; + sngisdn_event_data_t *sngisdn_event = NULL; ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType); @@ -626,7 +623,7 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) { signal_data = g_sngisdn_data.dchans[dChan].spans[i]; sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event)); - ftdm_assert(sngisdn_event, "Failed to allocate memory\n"); + ftdm_assert(sngisdn_event != NULL, "Failed to allocate memory\n"); memset(sngisdn_event, 0, sizeof(*sngisdn_event)); sngisdn_event->event_id = SNGISDN_EVENT_RST_CFM; @@ -645,30 +642,24 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces void sngisdn_rcv_phy_ind(SuId suId, Reason reason) { - ISDN_FUNC_TRACE_ENTER(__FUNCTION__); if (reason != LL1_REASON_CON_REQ_FAIL) { ftdm_log(FTDM_LOG_INFO, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason)); } - ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } void sngisdn_rcv_q921_ind(BdMngmt *status) -{ - ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - - unsigned j,k; - ftdm_span_t *ftdmspan = NULL; - - for(j=1;j<=g_sngisdn_data.num_dchan;j++) { - for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) { - if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.lnkNmb) { - ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span; - } - } +{ + ftdm_span_t *ftdmspan; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.lnkNmb]; + if (!signal_data) { + ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); + return; } - if (ftdmspan == NULL) { - ftdm_log(FTDM_LOG_WARNING, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); + ftdmspan = signal_data->ftdm_span; + + if (!ftdmspan) { + ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); return; } @@ -699,69 +690,56 @@ void sngisdn_rcv_q921_ind(BdMngmt *status) } break; } - - ISDN_FUNC_TRACE_EXIT(__FUNCTION__) return; } void sngisdn_rcv_q931_ind(InMngmt *status) -{ - ISDN_FUNC_TRACE_ENTER(__FUNCTION__); - ftdm_span_t *ftdmspan = NULL; - +{ if (status->t.usta.alarm.cause == 287) { get_memory_info(); return; } - switch (status->t.usta.alarm.category) { - case (LCM_CATEGORY_INTERFACE): - ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - - /* clean this up later */ - - switch (status->t.usta.alarm.event) { - case LCM_EVENT_UP: - case LCM_EVENT_DOWN: - { - unsigned j,k; - for(j=1;j<=g_sngisdn_data.num_dchan;j++) { - for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) { - if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.suId) { - ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span; - } - } - } - - if (ftdmspan == NULL) { - ftdm_log(FTDM_LOG_CRIT, "Received q931 LCM EVENT on unconfigured span (suId:%u)\n", status->t.usta.suId); - return; - } - - if (status->t.usta.alarm.event == LCM_EVENT_UP) { - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); - sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); - } else { - sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); - sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); - } - } - break; + switch (status->t.usta.alarm.event) { + case LCM_EVENT_UP: + case LCM_EVENT_DOWN: + { + ftdm_span_t *ftdmspan; + sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.suId]; + if (!signal_data) { + ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); + return; } - break; + ftdmspan = signal_data->ftdm_span; + + if (status->t.usta.alarm.event == LCM_EVENT_UP) { + ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); + + sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP); + sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP); + } else { + ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); + + sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); + sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); + } + } + break; default: - ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", - status->t.usta.suId, - DECODE_LCM_CATEGORY(status->t.usta.alarm.category), - DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, - DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); - break; + ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n", + status->t.usta.suId, + DECODE_LCM_CATEGORY(status->t.usta.alarm.category), + DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, + DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); } - - + ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } @@ -907,12 +885,13 @@ void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...) break; case SNG_LOGLEVEL_CRIT: ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s", data); - /*ftdm_assert(0, "Got an error from stack");*/ + /* ftdm_assert(0, "Got an error from stack"); */ break; default: ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data); break; } + ftdm_safe_free(data); return; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 29e7994c87..db22fe5ce8 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -73,8 +73,10 @@ void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info) sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId, sngisdn_info->suInstId, sngisdn_info->spInstId); - ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); - g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL; + ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); + if (sngisdn_info->glare.spInstId != sngisdn_info->spInstId) { + g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL; + } g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_suInstIds[sngisdn_info->glare.suInstId]=NULL; ftdm_mutex_unlock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex); @@ -132,16 +134,22 @@ ftdm_status_t __inline__ get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInst return FTDM_SUCCESS; } -ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail) +ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail) { - unsigned i; - if (ftdmspan->trunk_type == FTDM_TRUNK_BRI || - ftdmspan->trunk_type == FTDM_TRUNK_BRI_PTMP) { + + if (span->trunk_type == FTDM_TRUNK_BRI || + span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - for(i=1; i<=ftdmspan->chan_count; i++) { - ftdm_log_chan(ftdmspan->channels[i], FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); - ftdmspan->channels[i]->availability_rate = avail; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + + + chaniter = ftdm_span_get_chan_iterator(span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail); + ((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail; } + ftdm_iterator_free(chaniter); } return FTDM_SUCCESS; } @@ -427,6 +435,24 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info) return; } +void sngisdn_facility_timeout(void* p_sngisdn_info) +{ + sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info; + ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + ftdm_mutex_lock(ftdmchan->mutex); + if (ftdmchan->state == FTDM_CHANNEL_STATE_GET_CALLERID) { + ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Facility timeout reached proceeding with call (suId:%d suInstId:%u spInstId:%u)\n", + signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId); + + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); + } + + ftdm_mutex_unlock(ftdmchan->mutex); + return; +} + ftdm_status_t sngisdn_check_free_ids(void) { unsigned i; @@ -534,6 +560,77 @@ ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_pro return FTDM_USER_LAYER1_PROT_ULAW; } +void sngisdn_print_phy_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; + + memset(&sts, 0, sizeof(sts)); + sng_isdn_phy_stats(signal_data->link_id , &sts); + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " Span:%s", span->name); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " Performance Counters"); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, "RX Packets:\t%u\tTX Packets:\t%u\tEvents:%u\n", sts.t.sts.rx_packets, sts.t.sts.tx_packets, sts.t.sts.rx_events); + stream->write_function(stream, "RX Bytes:\t%u\tTX Bytes:\t%u\n\n", sts.t.sts.rx_bytes, sts.t.sts.tx_bytes); + stream->write_function(stream, "TX Queue:\t%u/%u\tRX Queue:\t%u/%u\tEvents Queue:\t%u/%u\n", + sts.t.sts.num_frames_in_tx_queue,sts.t.sts.tx_queue_len, + sts.t.sts.num_frames_in_rx_queue, sts.t.sts.rx_queue_len, + sts.t.sts.rx_events_in_queue, sts.t.sts.event_queue_len); + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " Errors"); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, "RX Errors:\t%u\tTX Errors:\t%u\n", sts.t.sts.rx_errors, sts.t.sts.tx_errors); + stream->write_function(stream, "RX Dropped:\t%u\tTX Dropped:\t%u\tEvents Dropped:\t%u\n", sts.t.sts.rx_dropped, sts.t.sts.tx_dropped,sts.t.sts.rx_events_dropped); + + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, " RX Errors Details"); + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + stream->write_function(stream, "CRC:\t\t%u\tFrame:\t\t%u\tOverruns:\t%u\n", sts.t.sts.rx_crc_errors, sts.t.sts.rx_frame_errors, sts.t.sts.rx_over_errors); + stream->write_function(stream, "Fifo:\t\t%u\tAborts:\t\t%u\tMissed:\t\t%u\n", sts.t.sts.rx_fifo_errors, sts.t.sts.rx_hdlc_abort_counter, sts.t.sts.rx_missed_errors); + stream->write_function(stream, "Length:\t\t%u\n", sts.t.sts.rx_length_errors); + + stream->write_function(stream, "\n---------------------------------------------------------------------\n"); + 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; +} + + +void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span) +{ + ftdm_signaling_status_t sigstatus; + ftdm_alarm_flag_t alarmbits; + ftdm_channel_t *fchan; + alarmbits = FTDM_ALARM_NONE; + fchan = ftdm_span_get_channel(span, 1); + if (fchan) { + ftdm_channel_get_alarms(fchan, &alarmbits); + } + + ftdm_span_get_sig_status(span, &sigstatus); + stream->write_function(stream, "span:%s physical:%s signalling:%s\n", + span->name, alarmbits ? "ALARMED" : "OK", + ftdm_signaling_status2str(sigstatus)); + return; +} + +void sngisdn_print_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); + } + } + return; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index c8c8bc3dd1..21feb4f8fe 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -85,35 +85,35 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp1_gen_config()) { SS7_CRITICAL("MTP1 General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP1 General configuration DONE\n"); } if (ftmod_ss7_mtp2_gen_config()) { SS7_CRITICAL("MTP2 General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP2 General configuration DONE\n"); } if (ftmod_ss7_mtp3_gen_config()) { SS7_CRITICAL("MTP3 General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 General configuration DONE\n"); } if (ftmod_ss7_isup_gen_config()) { SS7_CRITICAL("ISUP General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP General configuration DONE\n"); } if (ftmod_ss7_cc_gen_config()) { SS7_CRITICAL("CC General configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { SS7_INFO("CC General configuration DONE\n"); } @@ -131,7 +131,7 @@ int ft_to_sngss7_cfg_all(void) /* configure mtp1 */ if (ftmod_ss7_mtp1_psap_config(x)) { SS7_CRITICAL("MTP1 PSAP %d configuration FAILED!\n", x); - SS7_ASSERT; + return 1;; } else { SS7_INFO("MTP1 PSAP %d configuration DONE!\n", x); } @@ -139,7 +139,7 @@ int ft_to_sngss7_cfg_all(void) /* configure mtp2 */ if (ftmod_ss7_mtp2_dlsap_config(x)) { SS7_CRITICAL("MTP2 DLSAP %d configuration FAILED!\n",x); - SS7_ASSERT; + return 1;; } else { SS7_INFO("MTP2 DLSAP %d configuration DONE!\n", x); } @@ -147,7 +147,7 @@ int ft_to_sngss7_cfg_all(void) /* configure mtp3 */ if (ftmod_ss7_mtp3_dlsap_config(x)) { SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x); - SS7_ASSERT; + return 1;; } else { SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x); } @@ -166,14 +166,14 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_nsap_config(x)) { SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x); } if (ftmod_ss7_isup_nsap_config(x)) { SS7_CRITICAL("ISUP NSAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP NSAP %d configuration DONE!\n", x); } @@ -192,7 +192,7 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_linkset_config(x)) { SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x); } @@ -211,9 +211,9 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_route_config(x)) { SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { - SS7_INFO("MTP3 ROUTE %d configuration DONE!\n"); + SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x); } /* set the CONFIGURED flag */ @@ -227,9 +227,9 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_mtp3_route_config(0)) { SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n"); - SS7_ASSERT + return 1; } else { - SS7_INFO("MTP3 ROUTE %d configuration DONE!\n"); + SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n"); } /* set the CONFIGURED flag */ @@ -244,14 +244,14 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_isup_isap_config(x)) { SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP ISAP %d configuration DONE!\n", x); } if (ftmod_ss7_cc_isap_config(x)) { SS7_CRITICAL("CC ISAP %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("CC ISAP %d configuration DONE!\n", x); } @@ -270,9 +270,11 @@ int ft_to_sngss7_cfg_all(void) if (ftmod_ss7_isup_intf_config(x)) { SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP INTF %d configuration DONE!\n", x); + /* set the interface to paused */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED); } /* set the CONFIGURED flag */ @@ -289,7 +291,7 @@ int ft_to_sngss7_cfg_all(void) if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == 0) { if (ftmod_ss7_isup_ckt_config(x)) { SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); - SS7_ASSERT + return 1; } else { SS7_INFO("ISUP CKT %d configuration DONE!\n", x); } @@ -444,8 +446,8 @@ int ftmod_ss7_mtp3_gen_config(void) cfg.t.cfg.s.snGen.tmr.t21.enb = TRUE; /* t21 - waiting to restart traffic routed through adjacent SP */ cfg.t.cfg.s.snGen.tmr.t21.val = 650; # if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT)) - cfg.t.cfg.s.snGen.t26.enb = TRUE; /* t26 - waiting to repeat traffic restart waiting message for ANSI */ - cfg.t.cfg.s.snGen.t26.val = 600; + cfg.t.cfg.s.snGen.tmr.t26.enb = TRUE; /* t26 - waiting to repeat traffic restart waiting message for ANSI */ + cfg.t.cfg.s.snGen.tmr.t26.val = 600; # endif #endif @@ -644,7 +646,7 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.memMac.region = S_REG; /* memory region and pool id for MAC */ cfg.t.cfg.s.sdDLSAP.memMac.pool = S_POOL; cfg.t.cfg.s.sdDLSAP.maxOutsFrms = MAX_SD_OUTSTANDING; /* maximum outstanding frames */ - cfg.t.cfg.s.sdDLSAP.errType = SD_ERR_NRM; + cfg.t.cfg.s.sdDLSAP.errType = k->mtp2.errorType; cfg.t.cfg.s.sdDLSAP.t1.enb = TRUE; /* timer 1 - Alignment Ready Timer */ cfg.t.cfg.s.sdDLSAP.t1.val = k->mtp2.t1; cfg.t.cfg.s.sdDLSAP.t2.enb = TRUE; /* timer 2 - Not Aligned Timer */ @@ -744,10 +746,6 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.msgPrior = 0; /* management message priority */ cfg.t.cfg.s.snDLSAP.lnkType = k->mtp3.linkType; /* link type ANSI, ITU, BICI or CHINA */ cfg.t.cfg.s.snDLSAP.upSwtch = k->mtp3.switchType; /* user part switch type */ -# if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA) - cfg.t.cfg.s.snDLSAP.l2Type = LSN_MTP2_56KBPS; /* layer 2 type - 56kbps MTP2 link, 1.536Mbps MTP2 link or QSAAL link */ - cfg.t.cfg.s.snDLSAP.isCLink = FALSE; /* identifies if the link is a C type link.Required to check if sls has to be rotated.*/ -# endif cfg.t.cfg.s.snDLSAP.maxSLTtry = MAX_SLTM_RETRIES; /* maximun times to retry SLTM */ cfg.t.cfg.s.snDLSAP.p0QLen = 32; /* size of the priority 0 Q */ cfg.t.cfg.s.snDLSAP.p1QLen = 32; /* size of the priority 1 Q */ @@ -775,17 +773,46 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.selector = 0; /* lower layer selector */ cfg.t.cfg.s.snDLSAP.mem.region = S_REG; /* memory region id */ cfg.t.cfg.s.snDLSAP.mem.pool = S_POOL; /* memory pool id */ -#if( SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || SS7_CHINA ) - cfg.t.cfg.s.snDLSAP.dpcLen = DPC24; /* dpc length 24 bits */ -#else - cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */ -#endif cfg.t.cfg.s.snDLSAP.spId = k->mtp3.mtp2Id ;/* service provider id */ -#if (SS7_ITU88 || SS7_CHINA || SS7_TTC || SS7_NTT || SS7_BICI ) - cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */ -#else - cfg.t.cfg.s.snDLSAP.flushContFlag = TRUE; /* flush continue handling */ -#endif + + switch (k->mtp3.linkType) { + /**************************************************************************/ + case (LSN_SW_ANS): + case (LSN_SW_ANS96): + case (LSN_SW_CHINA): + cfg.t.cfg.s.snDLSAP.dpcLen = DPC24; /* dpc length 24 bits */ + cfg.t.cfg.s.snDLSAP.l2Type = LSN_MTP2_56KBPS; /* layer 2 type - 56kbps MTP2 link, 1.536Mbps MTP2 link or QSAAL link */ + cfg.t.cfg.s.snDLSAP.isCLink = FALSE; /* identifies if the link is a C type link.Required to check if sls has to be rotated.*/ + break; + /**************************************************************************/ + case (LSN_SW_ITU): + cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */ + break; + /**************************************************************************/ + default: + cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */ + break; + /**************************************************************************/ + } /* switch (k->mtp3.linkType) */ + + switch (k->mtp3.linkType) { + /**************************************************************************/ + case (LSN_SW_ANS): + case (LSN_SW_ANS96): + cfg.t.cfg.s.snDLSAP.flushContFlag = TRUE; /* flush continue handling */ + break; + /**************************************************************************/ + case (LSN_SW_ITU): + case (LSN_SW_CHINA): + cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */ + break; + /**************************************************************************/ + default: + cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */ + break; + /**************************************************************************/ + } /* switch (k->mtp3.linkType) */ + cfg.t.cfg.s.snDLSAP.tmr.t1.enb = TRUE; /* t1 - delay to avoid missequencing on changeover */ cfg.t.cfg.s.snDLSAP.tmr.t1.val = k->mtp3.t1; cfg.t.cfg.s.snDLSAP.tmr.t2.enb = TRUE; /* t2 - waiting for changeover ack */ @@ -900,7 +927,7 @@ int ftmod_ss7_mtp3_linkset_config(int id) { Pst pst; SnMngmt cfg; - U16 c; + int c; sng_link_set_t *k = &g_ftdm_sngss7_data.cfg.mtpLinkSet[id]; /* initalize the post structure */ @@ -927,12 +954,13 @@ int ftmod_ss7_mtp3_linkset_config(int id) cfg.t.cfg.s.snLnkSet.lnkSetType = k->linkType; /* link type */ cfg.t.cfg.s.snLnkSet.adjDpc = k->apc; /* adjacent DPC */ cfg.t.cfg.s.snLnkSet.nmbActLnkReqd = k->minActive; /* minimum number of active links */ - cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = 1; /* number of combined link sets */ - for (c = 0; c < LSN_MAXCMBLNK; c++) { - cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].cmbLnkSetId = c+1; + cfg.t.cfg.s.snLnkSet.nmbCmbLnkSet = k->numLinks; /* number of combined link sets */ + for(c = 0; c < k->numLinks;c++) { + cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].cmbLnkSetId = k->links[c]; cfg.t.cfg.s.snLnkSet.cmbLnkSet[c].lnkSetPrior = 0; } + return(sng_cfg_mtp3(&pst, &cfg)); } @@ -1209,12 +1237,12 @@ int ftmod_ss7_isup_ckt_config(int id) cfg.t.cfg.s.siCir.typeCntrl = k->typeCntrl; /* type of control */ cfg.t.cfg.s.siCir.contReq = FALSE; /* continuity check required */ #if (SI_218_COMP || SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL) - cfg.t.cfg.s.siCir.firstCic =; /* First cic in the circuit group */ - cfg.t.cfg.s.siCir.numCir =; /* Number of circuits in the circuit group */ + cfg.t.cfg.s.siCir.firstCic = 1; /* First cic in the circuit group */ + cfg.t.cfg.s.siCir.numCir = 24; /* Number of circuits in the circuit group */ cfg.t.cfg.s.siCir.nonSS7Con = TRUE; /* connecting to non SS7 network */ - cfg.t.cfg.s.siCir.outTrkGrpN =; /* outgoing trunk group number (For EXM) */ - cfg.t.cfg.s.siCir.cvrTrkClli =; /* Trunk Group number (For CVR validation) */ - cfg.t.cfg.s.siCir.clli =; /* common language location identifier */ + cfg.t.cfg.s.siCir.outTrkGrpN.length = 0; /* outgoing trunk group number (For EXM) */ + cfg.t.cfg.s.siCir.cvrTrkClli.length = 0; /* Trunk Group number (For CVR validation) */ + cfg.t.cfg.s.siCir.clli.length = 0; /* common language location identifier */ #endif cfg.t.cfg.s.siCir.cirTmr.t3.enb = TRUE; /* t3 timer - overload received */ cfg.t.cfg.s.siCir.cirTmr.t3.val = k->t3; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index edb15604e5..6ccc693478 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -48,8 +48,6 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream); static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level); static ftdm_status_t handle_set_message_trace(ftdm_stream_handle_t *stream, int on, int level); -static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose); -static ftdm_status_t handle_set_unblks(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *name); @@ -63,6 +61,21 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose); static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose); +static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose); + +static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); + +static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name); + +static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name); + +static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name); + static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name); @@ -282,20 +295,12 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha /**********************************************************************/ } /**************************************************************************/ - } else if (!strcasecmp(argv[c], "block")) { + } else if (!strcasecmp(argv[c], "inhibit")) { /**************************************************************************/ if (check_arg_count(argc, 2)) goto handle_cli_error_argc; c++; - if (!strcasecmp(argv[c], "span")) { - /**********************************************************************/ - if (check_arg_count(argc, 5)) goto handle_cli_error_argc; - - if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - - handle_set_blocks(stream, span, chan, verbose); - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "link")) { + if (!strcasecmp(argv[c], "link")) { /**********************************************************************/ if (check_arg_count(argc, 3)) goto handle_cli_error_argc; c++; @@ -309,7 +314,26 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha /**********************************************************************/ } /**************************************************************************/ - } else if (!strcasecmp(argv[c], "unblock")) { + } else if (!strcasecmp(argv[c], "uninhibit")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_set_uninhibit(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"unblock\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "blo")) { /**************************************************************************/ if (check_arg_count(argc, 2)) goto handle_cli_error_argc; c++; @@ -320,18 +344,101 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; - handle_set_unblks(stream, span, chan, verbose); - /**********************************************************************/ - } else if (!strcasecmp(argv[c], "link")) { - /**********************************************************************/ - if (check_arg_count(argc, 3)) goto handle_cli_error_argc; - c++; - - handle_set_uninhibit(stream, argv[c]); + handle_tx_blo(stream, span, chan, verbose); /**********************************************************************/ } else { /**********************************************************************/ - stream->write_function(stream, "Unknown \"unblock\" command\n"); + stream->write_function(stream, "Unknown \"block\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "ubl")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "span")) { + /**********************************************************************/ + if (check_arg_count(argc, 5)) goto handle_cli_error_argc; + + if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; + + handle_tx_ubl(stream, span, chan, verbose); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"ubl\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "cgb")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "span")) { + /**********************************************************************/ + if (check_arg_count(argc, 5)) goto handle_cli_error_argc; + + if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; + c = c + 4; + + if (check_arg_count(argc, 7)) goto handle_cli_error_argc; + + if (!strcasecmp(argv[c], "range")) { + /******************************************************************/ + c++; + range = atoi(argv[c]); + /******************************************************************/ + } else { + /******************************************************************/ + stream->write_function(stream, "Unknown \"cgb range\" command\n"); + goto handle_cli_error; + /******************************************************************/ + } + + handle_tx_cgb(stream, span, chan, range, verbose); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"cgb\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "cgu")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "span")) { + /**********************************************************************/ + if (check_arg_count(argc, 5)) goto handle_cli_error_argc; + + if (extract_span_chan(argv, c, &span, &chan)) goto handle_cli_error_span_chan; + c = c + 4; + + if (check_arg_count(argc, 7)) goto handle_cli_error_argc; + + if (!strcasecmp(argv[c], "range")) { + /******************************************************************/ + c++; + range = atoi(argv[c]); + /******************************************************************/ + } else { + /******************************************************************/ + stream->write_function(stream, "Unknown \"cgu range\" command\n"); + goto handle_cli_error; + /******************************************************************/ + } + + handle_tx_cgu(stream, span, chan, range, verbose); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"cgu\" command\n"); goto handle_cli_error; /**********************************************************************/ } @@ -389,7 +496,97 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha stream->write_function(stream, "Unknown \"grs\" command\n"); goto handle_cli_error; /**********************************************************************/ - } + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "lpo")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_tx_lpo(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"lpo\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "lpr")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_tx_lpr(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"lpr\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "activate")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_activate_link(stream, argv[c]); + /**********************************************************************/ + }else if (!strcasecmp(argv[c], "linkset")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_activate_linkset(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"activate\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "deactivate")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_deactivate_link(stream, argv[c]); + /**********************************************************************/ + }else if (!strcasecmp(argv[c], "linkset")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_deactivate_linkset(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"deactivate\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } /**************************************************************************/ } else { /**************************************************************************/ @@ -433,10 +630,22 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream) stream->write_function(stream, "ftdm ss7 show inreset span X chan Y\n"); stream->write_function(stream, "\n"); stream->write_function(stream, "Ftmod_sangoma_ss7 circuit control:\n"); - stream->write_function(stream, "ftdm ss7 block span X chan Y\n"); - stream->write_function(stream, "ftdm ss7 unblk span X chan Y\n"); + stream->write_function(stream, "ftdm ss7 blo span X chan Y\n"); + stream->write_function(stream, "ftdm ss7 ubl span X chan Y\n"); stream->write_function(stream, "ftdm ss7 rsc span X chan Y\n"); stream->write_function(stream, "ftdm ss7 grs span X chan Y range Z\n"); + stream->write_function(stream, "ftdm ss7 cgb span X chan Y range Z\n"); + stream->write_function(stream, "ftdm ss7 cgu span X chan Y range Z\n"); + stream->write_function(stream, "\n"); + stream->write_function(stream, "Ftmod_sangoma_ss7 link control:\n"); + stream->write_function(stream, "ftdm ss7 inhibit link X\n"); + stream->write_function(stream, "ftdm ss7 uninhibit link X\n"); + stream->write_function(stream, "ftdm ss7 activate link X\n"); + stream->write_function(stream, "ftdm ss7 deactivate link X\n"); + stream->write_function(stream, "ftdm ss7 activate linkset X\n"); + stream->write_function(stream, "ftdm ss7 deactivate linkset X\n"); + stream->write_function(stream, "ftdm ss7 lpo link X\n"); + stream->write_function(stream, "ftdm ss7 lpr link X\n"); stream->write_function(stream, "\n"); return FTDM_SUCCESS; @@ -811,87 +1020,100 @@ static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, /******************************************************************************/ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; - ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; + int x; + sngss7_chan_data_t *ss7_info; + ftdm_channel_t *ftdmchan; + int lspan; + int lchan; + ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; + sng_isup_ckt_t *ckt; x=1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; + /* extract the circuit to make it easier to work with */ + ckt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; /* if span == 0 then all spans should be printed */ if (span == 0) { - lspan = ftdmchan->physical_span_id; + lspan = ckt->span; } else { lspan = span; } /* if chan == 0 then all chans should be printed */ if (chan == 0) { - lchan = ftdmchan->physical_chan_id; + lchan = ckt->chan; } else { lchan = chan; } - if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* grab the signaling_status */ - ftdm_channel_get_sig_status(ftdmchan, &sigstatus); + /* check if this circuit is one of the circuits we're interested in */ + if ((ckt->span == lspan) && (ckt->chan == lchan)) { + if (ckt->type == HOLE) { + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|NOT USED\n", + ckt->span, + ckt->chan, + ckt->cic); + } else if (ckt->type == SIG) { + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|SIGNALING LINK\n", + ckt->span, + ckt->chan, + ckt->cic); + } else { + ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = ss7_info->ftdmchan; - stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - ss7_info->circuit->cic, - ftdm_signaling_status2str(sigstatus), - ftdm_channel_state2str(ftdmchan->state)); - - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { - stream->write_function(stream, "l_mn=Y|"); - }else { - stream->write_function(stream, "l_mn=N|"); - } - - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { - stream->write_function(stream, "r_mn=Y|"); - }else { - stream->write_function(stream, "r_mn=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { - stream->write_function(stream, "l_hw=Y|"); - }else { - stream->write_function(stream, "l_hw=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { - stream->write_function(stream, "r_hw=Y|"); - }else { - stream->write_function(stream, "r_hw=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { - stream->write_function(stream, "l_mngmt=Y|"); - }else { - stream->write_function(stream, "l_mngmt=N|"); - } - - if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { - stream->write_function(stream, "l_ucic=Y|"); - }else { - stream->write_function(stream, "l_ucic=N|"); - } - - stream->write_function(stream, "flags=0x%X",ss7_info->flags); - - stream->write_function(stream, "\n"); + /* grab the signaling_status */ + ftdm_channel_get_sig_status(ftdmchan, &sigstatus); + + stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|", + ckt->span, + ckt->chan, + ckt->cic, + ftdm_signaling_status2str(sigstatus), + ftdm_channel_state2str(ftdmchan->state)); + + if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + stream->write_function(stream, "l_mn=Y|"); + }else { + stream->write_function(stream, "l_mn=N|"); + } + + if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { + stream->write_function(stream, "r_mn=Y|"); + }else { + stream->write_function(stream, "r_mn=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { + stream->write_function(stream, "l_hw=Y|"); + }else { + stream->write_function(stream, "l_hw=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { + stream->write_function(stream, "r_hw=Y|"); + }else { + stream->write_function(stream, "r_hw=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { + stream->write_function(stream, "l_mngmt=Y|"); + }else { + stream->write_function(stream, "l_mngmt=N|"); + } + + if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { + stream->write_function(stream, "l_ucic=Y|"); + }else { + stream->write_function(stream, "l_ucic=N|"); + } + + stream->write_function(stream, "flags=0x%X",ss7_info->flags); + + stream->write_function(stream, "\n"); + } /* if ( hole, sig, voice) */ } /* if ( span and chan) */ - - } /* if ( cic != 0) */ - /* go the next circuit */ x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ @@ -899,7 +1121,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, return FTDM_SUCCESS; } /******************************************************************************/ -static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, int chan, int verbose) +static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { int x; sngss7_chan_data_t *ss7_info; @@ -934,7 +1156,12 @@ static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, i /* check if there is a pending state change|give it a bit to clear */ if (check_for_state_change(ftdmchan)) { SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); + /* check if we need to die */ SS7_ASSERT; + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + /* move to the next channel */ + continue; } else { /* throw the ckt block flag */ sngss7_set_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); @@ -960,7 +1187,7 @@ static ftdm_status_t handle_set_blocks(ftdm_stream_handle_t *stream, int span, i } /******************************************************************************/ -static ftdm_status_t handle_set_unblks(ftdm_stream_handle_t *stream, int span, int chan, int verbose) +static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { int x; sngss7_chan_data_t *ss7_info; @@ -995,7 +1222,12 @@ static ftdm_status_t handle_set_unblks(ftdm_stream_handle_t *stream, int span, i /* check if there is a pending state change|give it a bit to clear */ if (check_for_state_change(ftdmchan)) { SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); + /* check if we need to die */ SS7_ASSERT; + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + /* move to the next channel */ + continue; } else { /* throw the ckt block flag */ sngss7_set_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); @@ -1154,17 +1386,17 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na /******************************************************************************/ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int chan, int verbose) { - int x; - sngss7_chan_data_t *ss7_info; - ftdm_channel_t *ftdmchan; - int lspan; - int lchan; + int x; + sngss7_chan_data_t *sngss7_info; + ftdm_channel_t *ftdmchan; + int lspan; + int lchan; x=1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { - ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; - ftdmchan = ss7_info->ftdmchan; + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; /* if span == 0 then all spans should be printed */ if (span == 0) { @@ -1181,27 +1413,31 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c } if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change|give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic); - SS7_ASSERT; - } else { - /* throw the ckt block flag */ - sngss7_set_flag(ss7_info, FLAG_RESET_TX); + /* throw the reset flag */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX); - /* set the channel to suspended state */ + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + /* go to idle so that we can redo the restart state*/ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + break; + /**************************************************************************/ + default: + /* set the state of the channel to restart...the rest is done by the chan monitor */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ } - + /* unlock the channel again before we exit */ ftdm_mutex_unlock(ftdmchan->mutex); - } /* if ( span and chan) */ - } /* if ( cic != 0) */ + } /* if ( cic == voice) */ /* go the next circuit */ x++; @@ -1240,7 +1476,12 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c /* check if there is a pending state change|give it a bit to clear */ if (check_for_state_change(ftdmchan)) { SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); + /* check if we need to die */ SS7_ASSERT; + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + /* move to the next channel */ + continue; } else { /* throw the grp reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); @@ -1270,6 +1511,355 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose) +{ + int x; + sngss7_chan_data_t *sngss7_info; + ftdm_channel_t *ftdmchan; + ftdm_channel_t *main_chan = NULL; + sngss7_span_data_t *sngss7_span; + int byte = 0; + int bit = 0; + ftdm_sigmsg_t sigev; + + memset (&sigev, 0, sizeof (sigev)); + + + if (range > 31) { + stream->write_function(stream, "Invalid range value %d", range); + return FTDM_SUCCESS; + } + + x=1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* extract the channel and span info for this circuit */ + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; + sngss7_span = ftdmchan->span->mod_data; + + /* check if this circuit is part of the block */ + if ((ftdmchan->physical_span_id == span) && + ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* throw the grp maint. block flag */ + sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + + /* bring the sig status down */ + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + /* if this is the first channel in the range */ + if (ftdmchan->physical_chan_id == chan) { + /* attach the cgb information */ + main_chan = ftdmchan; + sngss7_span->tx_cgb.circuit = sngss7_info->circuit->id; + sngss7_span->tx_cgb.range = range-1; + sngss7_span->tx_cgb.type = 0; /* maintenace block */ + } /* if (ftdmchan->physical_chan_id == chan) */ + + /* update the status field */ + sngss7_span->tx_cgb.status[byte] = (sngss7_span->tx_cgb.status[byte] | (1 << bit)); + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + } /* if ( span and chan) */ + } /* if ( cic == voice) */ + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + + /* send the circuit group block */ + ft_to_sngss7_cgb(main_chan); + + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose) +{ + int x; + sngss7_chan_data_t *sngss7_info; + ftdm_channel_t *ftdmchan; + ftdm_channel_t *main_chan = NULL; + sngss7_span_data_t *sngss7_span; + int byte = 0; + int bit = 0; + ftdm_sigmsg_t sigev; + + memset (&sigev, 0, sizeof (sigev)); + + + if (range > 31) { + stream->write_function(stream, "Invalid range value %d", range); + return FTDM_SUCCESS; + } + + x=1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* extract the channel and span info for this circuit */ + sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; + ftdmchan = sngss7_info->ftdmchan; + sngss7_span = ftdmchan->span->mod_data; + + /* check if this circuit is part of the block */ + if ((ftdmchan->physical_span_id == span) && + ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) { + + /* now that we have the right channel...put a lock on it so no-one else can use it */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* throw the grp maint. block flag */ + sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + + /* bring the sig status up */ + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + /* if this is the first channel in the range */ + if (ftdmchan->physical_chan_id == chan) { + /* attach the cgb information */ + main_chan = ftdmchan; + sngss7_span->tx_cgu.circuit = sngss7_info->circuit->id; + sngss7_span->tx_cgu.range = range-1; + sngss7_span->tx_cgu.type = 0; /* maintenace block */ + } /* if (ftdmchan->physical_chan_id == chan) */ + + /* update the status field */ + sngss7_span->tx_cgu.status[byte] = (sngss7_span->tx_cgu.status[byte] | (1 << bit)); + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + } /* if ( span and chan) */ + } /* if ( cic == voice) */ + /* go the next circuit */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ + + /* send the circuit group block */ + ft_to_sngss7_cgu(main_chan); + + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_activate_mtplink(x)) { + stream->write_function(stream, "Failed to activate link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the deactivate request */ + if (ftmod_ss7_deactivate2_mtplink(x)) { + stream->write_function(stream, "Failed to deactivate link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_activate_linkset(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the linkset request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) { + + /* send the activate request */ + if (ftmod_ss7_activate_mtplinkSet(x)) { + stream->write_function(stream, "Failed to activate linkset=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the linkset */ + handle_status_linkset(stream, &name[0]); + goto success; + } + + /* move to the next linkset */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find linkset=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the linkset request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, name)) { + + /* send the deactivate request */ + if (ftmod_ss7_deactivate2_mtplinkSet(x)) { + stream->write_function(stream, "Failed to deactivate linkset=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the linkset */ + handle_status_linkset(stream, &name[0]); + goto success; + } + + /* move to the next linkset */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find linkset=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ + +static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_lpo_mtplink(x)) { + stream->write_function(stream, "Failed set LPO link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_lpr_mtplink(x)) { + stream->write_function(stream, "Failed set LPR link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c index 52b3860375..87733dd594 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c @@ -50,6 +50,17 @@ static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId); int ftmod_ss7_inhibit_mtplink(uint32_t id); int ftmod_ss7_uninhibit_mtplink(uint32_t id); + +int ftmod_ss7_activate_mtplink(uint32_t id); +int ftmod_ss7_deactivate_mtplink(uint32_t id); +int ftmod_ss7_deactivate2_mtplink(uint32_t id); + +int ftmod_ss7_activate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); + +int ftmod_ss7_lpo_mtplink(uint32_t id); +int ftmod_ss7_lpr_mtplink(uint32_t id); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -64,7 +75,7 @@ int ft_to_sngss7_activate_all(void) if (ftmod_ss7_enable_isap(x)) { SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x); - SS7_ASSERT; + return 1; } else { SS7_INFO("ISAP %d Enable: OK\n", x); } @@ -83,7 +94,7 @@ int ft_to_sngss7_activate_all(void) if (ftmod_ss7_enable_nsap(x)) { SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x); - SS7_ASSERT; + return 1; } else { SS7_INFO("NSAP %d Enable: OK\n", x); } @@ -102,7 +113,7 @@ int ft_to_sngss7_activate_all(void) if (ftmod_ss7_enable_mtpLinkSet(x)) { SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); - SS7_ASSERT; + return 1; } else { SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name); } @@ -271,6 +282,248 @@ int ftmod_ss7_uninhibit_mtplink(uint32_t id) return (sng_cntrl_mtp3(&pst, &cntrl)); } +/******************************************************************************/ +int ftmod_ss7_activate_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = AENA; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ADISIMM; /* Deactivate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate2_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ADISIMM_L2; /* Deactivate...layer 2 only */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_activate_mtplinkSet(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STLNKSET; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; + + cntrl.t.cntrl.action = AACTLNKSET; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate_mtplinkSet(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STLNKSET; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; + + cntrl.t.cntrl.action = ADEACTLNKSET; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STLNKSET; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; + + cntrl.t.cntrl.action = ADEACTLNKSET_L2; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_lpo_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ACTION_LPO; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_lpr_mtplink(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + + cntrl.t.cntrl.action = ACTION_LPR; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ + /******************************************************************************/ /* For Emacs: * Local Variables: 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 f0cfa0237a..ac7a61646f 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 @@ -71,6 +71,8 @@ ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -80,6 +82,9 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; + char nadi[2]; + + memset(nadi, '\0', sizeof(nadi)); /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { @@ -88,21 +93,13 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM (glare detected on circuit)\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM (glare)\n", sngss7_info->circuit->cic); } else { - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IAM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM\n", sngss7_info->circuit->cic); } /* check if the circuit has a remote block */ @@ -210,7 +207,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ } /* add any special variables for the dialplan */ - /*ftdm_channel_add_var(ftdmchan, "ss7_stuff", "s");*/ + sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val); + ftdm_channel_add_var(ftdmchan, "ss7_nadi", nadi); /* set the state of the channel to collecting...the rest is done by the chan monitor */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT); @@ -281,21 +279,13 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - } - switch (evntType) { /**************************************************************************/ case (ADDRCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ACM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ACM\n", sngss7_info->circuit->cic); switch (ftdmchan->state) { /**********************************************************************/ case FTDM_CHANNEL_STATE_DIALING: @@ -316,115 +306,115 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ } /* switch (ftdmchan->state) */ /**************************************************************************/ case (MODIFY): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (MODCMPLT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-COMPLETE\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-COMPLETE\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (MODREJ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MODIFY-REJECT\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY-REJECT\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (PROGRESS): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CPG\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CPG\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (FRWDTRSFR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FOT\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FOT\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (INFORMATION): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INF\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INF\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (INFORMATREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx INR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (SUBSADDR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SAM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SAM\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (EXIT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx EXIT\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx EXIT\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (NETRESMGT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx NRM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx NRM\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (IDENTREQ): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IDR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IDR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (IDENTRSP): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx IRS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IRS\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (MALCLLPRNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx MALICIOUS CALL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MALICIOUS CALL\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CHARGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (TRFFCHGE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-TARIFF\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-TARIFF\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CHARGEACK): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CRG-ACK\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CRG-ACK\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CALLOFFMSG): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-OFFER\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-OFFER\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (LOOPPRVNT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LOP\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LOP\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (TECT_TIMEOUT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ECT-Timeout\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ECT-Timeout\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (RINGSEND): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RINGING-SEND\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RINGING-SEND\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CALLCLEAR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALL-LINE Clear\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALL-LINE Clear\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (PRERELEASE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx PRI\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx PRI\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (APPTRANSPORT): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx APM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx APM\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (OPERATOR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx OPERATOR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx OPERATOR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (METPULSE): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx METERING-PULSE\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx METERING-PULSE\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (CLGPTCLR): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CALLING_PARTY_CLEAR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CALLING_PARTY_CLEAR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ case (SUBDIRNUM): - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUB-DIR\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUB-DIR\n", sngss7_info->circuit->cic); break; /**************************************************************************/ default: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Unknown Msg\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Unknown Msg\n", sngss7_info->circuit->cic); break; /**************************************************************************/ } @@ -451,25 +441,16 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - /* check whether the ftdm channel is in a state to accept a call */ switch (ftdmchan->state) { /**************************************************************************/ case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM\n", sngss7_info->circuit->cic); /* go to UP */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); @@ -478,7 +459,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**************************************************************************/ case FTDM_CHANNEL_STATE_DIALING: - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CON\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CON\n", sngss7_info->circuit->cic); /* go to UP */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); @@ -487,7 +468,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**************************************************************************/ default: /* incorrect state...reset the CIC */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx ANM/CON\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic); /* throw the TX reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); @@ -521,18 +502,12 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx REL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx REL cause=%d\n", + sngss7_info->circuit->cic, + siRelEvnt->causeDgn.causeVal.val); /* check whether the ftdm channel is in a state to release a call */ switch (ftdmchan->state) { @@ -610,18 +585,10 @@ ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RLC\n", sngss7_info->circuit->cic); /* check whether the ftdm channel is in a state to accept a call */ switch (ftdmchan->state) { @@ -669,18 +636,10 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx DATA IND\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx DATA IND\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -704,18 +663,10 @@ ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -739,18 +690,10 @@ ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx FAC-CON\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx FAC-CON\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -774,18 +717,10 @@ ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx USER-USER msg\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx USER-USER msg\n", sngss7_info->circuit->cic); /* unlock the channel */ ftdm_mutex_unlock(ftdmchan->mutex); @@ -812,217 +747,217 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ switch (evntType) { /**************************************************************************/ case SIT_STA_REATTEMPT: /* reattempt indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Reattempt indication\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Reattempt indication\n", sngss7_info->circuit->cic); handle_reattempt(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_ERRORIND: /* error indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Error indication\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Error indication\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CONTCHK: /* continuity check */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT start\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT start\n", sngss7_info->circuit->cic); handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CONTREP: /* continuity report */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT report\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT report\n", sngss7_info->circuit->cic); handle_cot(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_STPCONTIN: /* stop continuity */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx COT stop\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT stop\n", sngss7_info->circuit->cic); handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGQRYRSP: /* circuit grp query response from far end forwarded to upper layer by ISUP */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CQM\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CONFUSION: /* confusion */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CFN\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CFN\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LOOPBACKACK: /* loop-back acknowledge */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LPA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LPA\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRRSRVREQ: /* circuit reservation request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Resveration req\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Ckt Resveration req\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRRSRVACK: /* circuit reservation acknowledgement */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Ckt Res ack\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Ckt Res ack\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRBLOREQ: /* circuit blocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLO\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx BLO\n", sngss7_info->circuit->cic); handle_blo_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRBLORSP: /* circuit blocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx BLA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx BLA\n", sngss7_info->circuit->cic); handle_blo_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRUBLREQ: /* circuit unblocking request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UBL\n", sngss7_info->circuit->cic); handle_ubl_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRUBLRSP: /* circuit unblocking response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UBA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UBA\n", sngss7_info->circuit->cic); handle_ubl_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRRESREQ: /* circuit reset request - RSC */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RSC\n", sngss7_info->circuit->cic); handle_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRLOCRES: /* reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local RSC\n", sngss7_info->circuit->cic); handle_local_rsc_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRRESRSP: /* circuit reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RSC-RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RSC-RLC\n", sngss7_info->circuit->cic); handle_rsc_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGBREQ: /* CGB request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGB\n", sngss7_info->circuit->cic); + handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGUREQ: /* CGU request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGU\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGU\n", sngss7_info->circuit->cic); + handle_cgu_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CGQRYREQ: /* circuit group query request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CQM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CQM\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CGBRSP: /* mntc. oriented CGB response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGB\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx mntc CGB\n", sngss7_info->circuit->cic); + /*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/ break; /**************************************************************************/ case SIT_STA_CGURSP: /* mntc. oriented CGU response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx mntc CGU\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx mntc CGU\n", sngss7_info->circuit->cic); + /*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/ break; /**************************************************************************/ case SIT_STA_GRSREQ: /* circuit group reset request */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx GRS\n", sngss7_info->circuit->cic); handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRUNEQPD: /* circuit unequipped indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UCIC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic); handle_ucic(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_GRSRSP: /* circuit group reset response */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx GRA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx GRA\n", sngss7_info->circuit->cic); handle_grs_rsp(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_PAUSEIND: /* pause indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx SUS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUS\n", sngss7_info->circuit->cic); handle_pause(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_RESUMEIND: /* resume indication */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx RES\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx RES\n", sngss7_info->circuit->cic); handle_resume(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_USRPARTA: /* user part available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx UPA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UPA\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_RMTUSRUNAV: /* remote user not available */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Remote User not Available\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Remote User not Available\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG0: /* congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L0\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L0\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG1: /* congestion indication level 1 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L1\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L1\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG2: /* congestion indication level 2 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L2\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L2\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPCONG3: /* congestion indication level 3 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Congestion L3\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Congestion L3\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_MTPSTPCONG: /* stop congestion indication level 0 */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Stop Congestion\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Stop Congestion\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRLOCALBLOIND: /* Mngmt local blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local BLO\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local BLO\n", sngss7_info->circuit->cic); handle_local_blk(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_CIRLOCALUBLIND: /* Mngmt local unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local UBL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local UBL\n", sngss7_info->circuit->cic); handle_local_ubl(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt); break; /**************************************************************************/ case SIT_STA_OVERLOAD: /* Overload */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Overload\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGB\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CGB\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LMCGUREQ: /* when LM requests ckt grp unblocking */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CGU\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CGU\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_LMGRSREQ: /* when LM requests ckt grp reset */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM RSC\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CGBINFOIND: /* circuit grp blking ind , no resp req */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx CGB no resp req\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + /*SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CGB no resp req\n", sngss7_info->circuit->cic);*/ +/* handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/ break; /**************************************************************************/ case SIT_STA_LMCQMINFOREQ: /* when LM requests ckt grp query */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx LM CQM\n"); - SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx LM CQM\n", sngss7_info->circuit->cic); +// SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ case SIT_STA_CIRLOCGRS: /* group reset initiated locally by the software */ - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Rx Local GRS\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Local GRS\n", sngss7_info->circuit->cic); SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType)); break; /**************************************************************************/ @@ -1051,17 +986,9 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { /* the glare flag is already up so it was caught ... do nothing */ SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " "); @@ -1100,8 +1027,11 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui int infId; int i; - /* extract the affect infId from the circuit structure */ + /* extract the affected infId from the circuit structure */ infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + /* set the interface to paused */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); /* go through all the circuits now and find any other circuits on this infId */ i = 1; @@ -1121,21 +1051,11 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - i++; - SS7_ASSERT; - }; - /* check if the circuit is fully started */ if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { + SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", ""); /* set the pause flag on the channel */ sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* set the statet o SUSPENDED to bring the sig status down */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } /* unlock the channel again before we exit */ @@ -1165,6 +1085,9 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu /* extract the affect infId from the circuit structure */ infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + /* set the interface to resumed */ + sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); + /* go through all the circuits now and find any other circuits on this infId */ i = 1; while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { @@ -1183,24 +1106,15 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - i++; - SS7_ASSERT; - }; - /* only resume if we are paused */ if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", ""); + /* set the resume flag on the channel */ sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); /* clear the paused flag */ sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); - - /* set the statet to SUSPENDED to bring the sig status up */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); } /* unlock the channel again before we exit */ @@ -1232,17 +1146,9 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* open the channel if it is not open */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { @@ -1290,17 +1196,9 @@ ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t cir return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* tell the core to stop looping the channel */ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); @@ -1351,17 +1249,9 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the circuit is already blocked or not */ if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_WARN("Received BLO on circuit that is already blocked!\n"); @@ -1395,17 +1285,9 @@ ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* KONRAD FIX ME */ /* unlock the channel again before we exit */ @@ -1430,17 +1312,9 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the channel is blocked */ if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { SS7_WARN("Received UBL on circuit that is not blocked!\n"); @@ -1477,17 +1351,9 @@ ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* KONRAD FIX ME */ /* unlock the channel again before we exit */ @@ -1512,17 +1378,9 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* throw the reset flag */ sngss7_set_flag(sngss7_info, FLAG_RESET_RX); @@ -1565,17 +1423,9 @@ ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* throw the reset flag */ sngss7_set_flag(sngss7_info, FLAG_RESET_RX); @@ -1618,17 +1468,9 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - switch (ftdmchan->state) { /**********************************************************************/ case FTDM_CHANNEL_STATE_RESTART: @@ -1694,7 +1536,7 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_channel_t *ftdmchan = NULL; sngss7_span_data_t *sngss7_span = NULL; int range; - int x; + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); @@ -1711,57 +1553,12 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* loop over the cics starting from circuit until range+1 */ - for (x = circuit; x < (circuit + range + 1); x++) { - /* grab the circuit in question */ - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); - break; - } - - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_ASSERT; - }; + /* fill in the span structure for this circuit */ + sngss7_span = ftdmchan->span->mod_data; + sngss7_span->rx_grs.circuit = circuit; + sngss7_span->rx_grs.range = range; - /* fill in the span structure for this circuit */ - sngss7_span = ftdmchan->span->mod_data; - sngss7_span->rx_grs.circuit = circuit; - sngss7_span->rx_grs.range = range; - - SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); - - /* flag the channel as having received a reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); - - switch (ftdmchan->state) { - /**************************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* go to idle so that we can redo the restart state*/ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); - - break; - /**************************************************************************/ - default: - - /* set the state of the channel to restart...the rest is done by the chan monitor */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); - break; - /**************************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } + /* the reset will be started in the main thread by "check_if_rx_grs_started" */ SS7_FUNC_TRACE_EXIT(__FUNCTION__); return FTDM_SUCCESS; @@ -1772,10 +1569,16 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ { SS7_FUNC_TRACE_ENTER(__FUNCTION__); - sngss7_chan_data_t *sngss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + sngss7_span_data_t *sngss7_span = NULL; int range; - int x; + + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } /* extract the range value from the event structure */ if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { @@ -1786,77 +1589,20 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ return FTDM_FAIL; } - /* go through all the circuits in the range */ - for ( x = circuit; x < (circuit + range + 1); x++) { + /* fill in the span structure for this circuit */ + sngss7_span = ftdmchan->span->mod_data; + sngss7_span->rx_gra.circuit = circuit; + sngss7_span->rx_gra.range = range; - /* grab the circuit in question */ - if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - break; - } + /* check if there is a cause value in the GRA */ + if ((siStaEvnt != NULL) && + (siStaEvnt->causeDgn.eh.pres == PRSNT_NODEF) && + (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - /* now that we have the right channel...put a lock on it so no-one else can use it */ - ftdm_mutex_lock(ftdmchan->mutex); + sngss7_span->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val; + } - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_ASSERT; - }; - - SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", - g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, - (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range)); - - switch (ftdmchan->state) { - /**********************************************************************/ - case FTDM_CHANNEL_STATE_RESTART: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - /* go to DOWN */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_DOWN: - - /* do nothing, just drop the message */ - SS7_DEBUG("Receveived GRA in down state, dropping\n"); - - break; - /**********************************************************************/ - case FTDM_CHANNEL_STATE_TERMINATING: - case FTDM_CHANNEL_STATE_HANGUP: - case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: - - /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - - break; - /**********************************************************************/ - default: - /* ITU Q764-2.9.5.1.c -> release the circuit */ - if ((siStaEvnt != NULL) && - (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) && - (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) { - ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val; - } else { - ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ - } - - /* go to terminating to hang up the call */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - break; - /**********************************************************************/ - } - - /* unlock the channel again before we exit */ - ftdm_mutex_unlock(ftdmchan->mutex); - - } /* for (( x = 0; x < (circuit + range); x++) */ + /* the reset will be started in the main thread by "check_if_rx_gra_started" */ SS7_FUNC_TRACE_EXIT(__FUNCTION__); return FTDM_SUCCESS; @@ -1877,17 +1623,9 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the circuit is already blocked or not */ if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { SS7_WARN("Received local BLO on circuit that is already blocked!\n"); @@ -1921,17 +1659,9 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* check if the circuit is already blocked or not */ if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); @@ -1965,17 +1695,9 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit return FTDM_FAIL; } - /* now that we have the right channel...put a lock on it so no-one else can use it */ + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* check if there is a pending state change, give it a bit to clear */ - if (check_for_state_change(ftdmchan)) { - SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - SS7_ASSERT; - }; - /* throw the ckt block flag */ sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); @@ -1989,6 +1711,277 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit return FTDM_SUCCESS; } +/******************************************************************************/ +ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + sngss7_span_data_t *sngss7_span = NULL; + ftdm_channel_t *ftdmchan = NULL; + int range; + uint8_t status[255]; + int blockType = 0; + int byte = 0; + int bit = 0; + int x; + ftdm_sigmsg_t sigev; + + memset(&sigev, 0, sizeof (sigev)); + memset(&status[0], '\0', sizeof(status)); + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* grab the span info */ + sngss7_span = ftdmchan->span->mod_data; + + /* figure out what type of block needs to be applied */ + if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) { + blockType = siStaEvnt->cgsmti.typeInd.val; + } else { + SS7_ERROR("Received CGB with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* pull out the range value */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { + range = siStaEvnt->rangStat.range.val; + } else { + SS7_ERROR("Received CGB with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* pull out the status field */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) { + for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { + status[x] = siStaEvnt->rangStat.status.val[x]; + } + } else { + SS7_ERROR("Received CGB with no status value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* save the circuit, range and status */ + sngss7_span->rx_cgb.circuit = circuit; + sngss7_span->rx_cgb.range = range; + sngss7_span->rx_cgb.type = blockType; + for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { + sngss7_span->rx_cgb.status[x] = status[x]; + } + + /* loop over the cics starting from circuit until range+1 */ + for (x = circuit; x < (circuit + range + 1); x++) { + /* confirm this is a voice channel */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue; + + /* grab the circuit in question */ + if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); + break; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + +#if 0 + SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n", + x, + byte, + bit, + status[byte], + (status[byte] & (1 << bit))); +#endif + if (status[byte] & (1 << bit)) { + switch (blockType) { + /**********************************************************************/ + case 0: /* maintenance oriented */ + sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + break; + /**********************************************************************/ + case 1: /* hardware failure oriented */ + sngss7_set_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + break; + /**********************************************************************/ + case 2: /* reserved for national use */ + break; + /**********************************************************************/ + default: + break; + /**********************************************************************/ + } /* switch (blockType) */ + } + + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + + } /* for (x = circuit; x < (circuit + range + 1); x++) */ + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + ft_to_sngss7_cgba(ftdmchan); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) +{ + SS7_FUNC_TRACE_ENTER(__FUNCTION__); + + sngss7_chan_data_t *sngss7_info = NULL; + sngss7_span_data_t *sngss7_span = NULL; + ftdm_channel_t *ftdmchan = NULL; + int range; + uint8_t status[255]; + int blockType = 0; + int byte = 0; + int bit = 0; + int x; + ftdm_sigmsg_t sigev; + + memset(&sigev, 0, sizeof (sigev)); + memset(&status[0], '\0', sizeof(status)); + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* grab the span info */ + sngss7_span = ftdmchan->span->mod_data; + + /* figure out what type of block needs to be applied */ + if ((siStaEvnt->cgsmti.eh.pres == PRSNT_NODEF) && (siStaEvnt->cgsmti.typeInd.pres == PRSNT_NODEF)) { + blockType = siStaEvnt->cgsmti.typeInd.val; + } else { + SS7_ERROR("Received CGU with no circuit group supervision value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* pull out the range value */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) { + range = siStaEvnt->rangStat.range.val; + } else { + SS7_ERROR("Received CGU with no range value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* pull out the status field */ + if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.status.pres == PRSNT_NODEF)) { + for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { + status[x] = siStaEvnt->rangStat.status.val[x]; + } + } else { + SS7_ERROR("Received CGU with no status value on CIC = %d\n", sngss7_info->circuit->cic); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + /* save the circuit, range and status */ + sngss7_span->rx_cgu.circuit = circuit; + sngss7_span->rx_cgu.range = range; + sngss7_span->rx_cgu.type = blockType; + for (x = 0; x < siStaEvnt->rangStat.status.len; x++) { + sngss7_span->rx_cgu.status[x] = status[x]; + } + + /* loop over the cics starting from circuit until range+1 */ + for (x = circuit; x < (circuit + range + 1); x++) { + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) continue; + /* grab the circuit in question */ + if (extract_chan_data(x, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x); + break; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + if (status[byte] & (1 << bit)) { + switch (blockType) { + /**********************************************************************/ + case 0: /* maintenance oriented */ + sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + break; + /**********************************************************************/ + case 1: /* hardware failure oriented */ + sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + break; + /**********************************************************************/ + case 2: /* reserved for national use */ + break; + /**********************************************************************/ + default: + break; + /**********************************************************************/ + } /* switch (blockType) */ + } /* if (status[byte] & (1 << bit)) */ + + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + + } /* for (x = circuit; x < (circuit + range + 1); x++) */ + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return FTDM_FAIL; + } + + ft_to_sngss7_cgua(ftdmchan); + + return FTDM_SUCCESS; +} /******************************************************************************/ /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index b666f726a1..3f507d6648 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -109,6 +109,10 @@ void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta) /******************************************************************************/ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) { + char buf[50]; + int x = 1; + + memset(buf, '\0', sizeof(buf)); switch (sta->t.usta.alarm.category) { /**************************************************************************/ @@ -126,23 +130,39 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) case (LSD_EVENT_REMOTE_CONG_END): case (LSD_EVENT_RX_REMOTE_SIPO): + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + switch (sta->t.usta.alarm.cause) { /******************************************************************/ case (LCM_CAUSE_UNKNOWN): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s\n", - sta->t.usta.evntParm[0], + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event)); break; /******************************************************************/ case (LCM_CAUSE_MGMT_INITIATED): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d][MGMT] %s\n", - sta->t.usta.evntParm[0], + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s[MGMT] %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event)); break; /******************************************************************/ default: - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s (***unknown cause***)\n", - sta->t.usta.evntParm[0], + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s (***unknown cause***)\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event)); break; /******************************************************************/ @@ -150,23 +170,71 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) break; /**********************************************************************/ case (LSD_EVENT_PROT_ERR): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), DECODE_LSD_CAUSE(sta->t.usta.alarm.cause)); break; /**********************************************************************/ case (LSD_EVENT_ALIGN_LOST): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), DECODE_DISC_REASON(sta->t.usta.evntParm[1])); break; /**********************************************************************/ case (LSD_EVENT_RTB_FULL): case (LSD_EVENT_RTB_FULL_OVER): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), sta->t.usta.evntParm[1], sta->t.usta.evntParm[2], @@ -175,15 +243,47 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) break; /**********************************************************************/ case (LSD_EVENT_NEG_ACK): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), sta->t.usta.evntParm[1]); break; /**********************************************************************/ case (LSD_EVENT_DAT_CFM_SDT): - ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %d\n", - sta->t.usta.evntParm[0], + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + + ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %d\n", + buf, DECODE_LSD_EVENT(sta->t.usta.alarm.event), DECODE_DISC_REASON(sta->t.usta.evntParm[1])); break; @@ -251,15 +351,35 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /******************************************************************************/ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) { + char buf[50]; + int x = 1; + + memset(buf, '\0', sizeof(buf)); switch (sta->hdr.elmId.elmnt) { /**************************************************************************/ case (STDLSAP): + + /* find the name for the sap in question */ + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->hdr.elmId.elmntInst1) { + break; + } + x++; + } + + if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + sprintf(buf, "[SAPID:%d]", sta->hdr.elmId.elmntInst1); + } else { + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + } + switch (sta->t.usta.alarm.event) { /**********************************************************************/ case (LSN_EVENT_INV_OPC_OTHER_END): - ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : OPC(0x%X%X%X%X)\n", - sta->hdr.elmId.elmntInst1, + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n", + buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), sta->t.usta.evntParm[3], @@ -269,16 +389,16 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) break; /**********************************************************************/ case (LSN_EVENT_INV_SLC_OTHER_END): - ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : SLC(%d)\n", - sta->hdr.elmId.elmntInst1, + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : SLC(%d)\n", + buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), sta->t.usta.evntParm[0]); break; /**********************************************************************/ default: - ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s(%d) : %s(%d)\n", - sta->hdr.elmId.elmntInst1, + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s(%d) : %s(%d)\n", + buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), sta->t.usta.alarm.event, DECODE_LSN_CAUSE(sta->t.usta.alarm.cause), @@ -303,13 +423,53 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) break; /**************************************************************************/ case (STROUT): - ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n", - sta->t.usta.evntParm[0], - sta->t.usta.evntParm[1], - sta->t.usta.evntParm[2], - sta->t.usta.evntParm[3], - DECODE_LSN_EVENT(sta->t.usta.alarm.event), - DECODE_LSN_CAUSE(sta->t.usta.alarm.cause)); + switch (sta->t.usta.alarm.event) { + /**********************************************************************/ + case (LSN_EVENT_RX_TRANSFER_MSG): + switch (sta->t.usta.evntParm[5]) { + /******************************************************************/ + case (0x23): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFC\n"); + break; + /******************************************************************/ + case (0x34): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR\n"); + break; + /******************************************************************/ + case (0x54): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA\n"); + break; + /******************************************************************/ + case (0x14): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP\n"); + break; + /******************************************************************/ + case (0x24): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFP (cluster)\n"); + break; + /******************************************************************/ + case (0x64): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFA (cluster)\n"); + break; + /******************************************************************/ + case (0x44): + ftdm_log(FTDM_LOG_INFO,"[MTP3] Rx SNM TFR (cluster)\n"); + break; + /******************************************************************/ + } /* switch (sta->t.usta.evntParm[5]) */ + break; + /**********************************************************************/ + default: + ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n", + sta->t.usta.evntParm[0], + sta->t.usta.evntParm[1], + sta->t.usta.evntParm[2], + sta->t.usta.evntParm[3], + DECODE_LSN_EVENT(sta->t.usta.alarm.event), + DECODE_LSN_CAUSE(sta->t.usta.alarm.cause)); + break; + /**********************************************************************/ + } /* switch (sta->t.usta.alarm.event) */ break; /**************************************************************************/ default: @@ -336,6 +496,12 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta) /* initalize the msg variable to NULLs */ memset(&msg[0], '\0', sizeof(&msg)); + /* if the event is REMOTE/LOCAL we don't need to print these */ + if ((sta->t.usta.alarm.event == LSI_EVENT_REMOTE) || + (sta->t.usta.alarm.event == LSI_EVENT_LOCAL)) { + return; + } + /* point p to the first spot in msg */ p = &msg[0]; @@ -568,6 +734,8 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta) DECODE_LSI_EVENT(sta->t.usta.alarm.event), DECODE_LSI_CAUSE(sta->t.usta.alarm.cause)); + return; + } /* handle_isup_alarm */ /******************************************************************************/ 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 66efe1ab12..fc14d04c80 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -46,7 +46,7 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data; /* PROTOTYPES *****************************************************************/ static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj); -static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); +void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event); static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span); @@ -272,10 +272,8 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) ftdm_interrupt_t *ftdm_sangoma_ss7_int[2]; ftdm_span_t *ftdmspan = (ftdm_span_t *) obj; ftdm_channel_t *ftdmchan = NULL; - sngss7_chan_data_t *sngss7_info = NULL; sngss7_event_data_t *sngss7_event = NULL; sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; - int i; ftdm_log (FTDM_LOG_INFO, "ftmod_sangoma_ss7 monitor thread for span=%u started.\n", ftdmspan->span_id); @@ -344,73 +342,22 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj) /**********************************************************************/ } /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */ - /* extract the span data structure */ - sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; + /* check if there is a GRA to proccess on the span */ + if (sngss7_span->rx_gra.range > 0) { + check_if_rx_gra_started(ftdmspan); + } /* if (sngss7->span->rx_gra.range > 0) */ /* check if there is a GRS being processed on the span */ if (sngss7_span->rx_grs.range > 0) { - ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id); - /*SS7_DEBUG("Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);*/ + /* check if the rx_grs has started */ + check_if_rx_grs_started(ftdmspan); - /* check all the circuits in the range to see if they are done resetting */ - for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { + /* check if the rx_grs has cleared */ + check_if_rx_grs_processed(ftdmspan); + } /* if (sngss7_span->rx_grs.range > 0) */ - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); - SS7_ASSERT; - } - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if there is a state change pending on the channel */ - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { - /* check the state to the GRP_RESET_RX_DN flag */ - if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { - /* this channel is still resetting...do nothing */ - goto GRS_UNLOCK_ALL; - } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ - } else { - /* state change pending */ - goto GRS_UNLOCK_ALL; - } - } /* for ( i = circuit; i < (circuit + range + 1); i++) */ - - SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n", - sngss7_span->rx_grs.circuit, - sngss7_span->rx_grs.range); - - /* check all the circuits in the range to see if they are done resetting */ - for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { - - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i); - SS7_ASSERT; - } - - /* throw the GRP reset flag complete flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); - - /* move the channel to the down state */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); - - } /* for ( i = circuit; i < (circuit + range + 1); i++) */ - -GRS_UNLOCK_ALL: - for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { - /* extract the channel in question */ - if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); - SS7_ASSERT; - } - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - } - - } /* if (ftdmspan->grs.range > 0) */ + /* check each channel on the span to see if there is an un-procressed SUS/RES flag */ + check_for_res_sus_flag(ftdmspan); } /* master while loop */ /* clear the IN_THREAD flag so that we know the thread is done */ @@ -513,11 +460,11 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev } /******************************************************************************/ -static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) +void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) { - ftdm_sigmsg_t sigev; sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; int i = 0; + ftdm_sigmsg_t sigev; memset (&sigev, 0, sizeof (sigev)); @@ -544,10 +491,13 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) i++; } - /* check if the end of pulsing character has arrived or the right number of digits */ - if (ftdmchan->caller_data.dnis.digits[i] == 0xF) { + /* check if the end of pulsing (ST) character has arrived or the right number of digits */ + if (ftdmchan->caller_data.dnis.digits[i-1] == 'F') { SS7_DEBUG_CHAN(ftdmchan, "Received the end of pulsing character %s\n", ""); + /* remove the ST */ + ftdmchan->caller_data.dnis.digits[i-1] = '\0'; + /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); @@ -569,7 +519,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sngss7_info->t35.beat, sngss7_info->t35.callback, &sngss7_info->t35, - &sngss7_info->t35.heartbeat_timer)) { + &sngss7_info->t35.hb_timer_id)) { SS7_ERROR ("Unable to schedule timer, hanging up call!\n"); @@ -594,8 +544,8 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* kill t35 if active */ - if (sngss7_info->t35.heartbeat_timer) { - ftdm_sched_cancel_timer (sngss7_info->t35.sched,&sngss7_info->t35.heartbeat_timer); + if (sngss7_info->t35.hb_timer_id) { + ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id); } SS7_DEBUG_CHAN(ftdmchan, "Sending incoming call from %s to %s to FTDM core\n", @@ -785,14 +735,19 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_DOWN: /*the call is finished and removed */ + if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { + SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); + break; + } + /* check if there is a reset response that needs to be sent */ if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) { /* send a RSC-RLC */ ft_to_sngss7_rsca (ftdmchan); /* clear the reset flag */ - sngss7_clear_flag (sngss7_info, FLAG_RESET_RX); - } + clear_rx_rsc_flags(sngss7_info); + } /* if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) */ /* check if there was a GRS that needs a GRA */ if ((sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) && @@ -814,27 +769,24 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* clear the grp reset flag */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); - + clear_rx_grs_flags(sngss7_info); }/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */ /* check if we got the reset response */ if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) { /* clear the reset flag */ - sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP); - sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT); - sngss7_clear_flag(sngss7_info, FLAG_RESET_TX); - } + clear_tx_rsc_flags(sngss7_info); + } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) */ if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { /* clear the reset flag */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT); - } + clear_tx_grs_flags(sngss7_info); + + /* clean out the spans GRA structure */ + sngss7_span_data_t *span = ftdmchan->span->mod_data; + span->rx_gra.circuit = 0; + span->rx_gra.range = 0; + } /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */ /* check if we came from reset (aka we just processed a reset) */ if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) || @@ -846,16 +798,25 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) && !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { - /* check if the sig status is down, and bring it up if it isn't */ - if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { - SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", ""); - /* all flags are down so we can bring up the sig status */ - sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_UP; - ftdm_span_send_signal (ftdmchan->span, &sigev); - } + /* now check if there is an active block */ + if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) && + !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { + + /* check if the sig status is down, and bring it up if it isn't */ + if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { + SS7_DEBUG_CHAN(ftdmchan,"All reset flags cleared %s\n", ""); + /* all flags are down so we can bring up the sig status */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal (ftdmchan->span, &sigev); + } /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */ + } /* if !blocked */ } else { - SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags); /* there is still another reset pending so go back to reset*/ @@ -864,8 +825,8 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) */ /* check if t35 is active */ - if (sngss7_info->t35.heartbeat_timer) { - ftdm_sched_cancel_timer (sngss7_info->t35.sched, &sngss7_info->t35.heartbeat_timer); + if (sngss7_info->t35.hb_timer_id) { + ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id); } /* clear all of the call specific data store in the channel structure */ @@ -1012,34 +973,52 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags); /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_INFID_PAUSED)) { - SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE flag %s\n", ""); - - /* bring the channel signaling status to down */ - sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; - sigev.sigstatus = FTDM_SIG_STATE_DOWN; - ftdm_span_send_signal (ftdmchan->span, &sigev); + if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", ""); - /* check the last state and return to it to allow the call to finish */ - goto suspend_goto_last; - } - - if (sngss7_test_flag (sngss7_info, FLAG_INFID_RESUME)) { - SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME flag %s\n", ""); - - /* the reset flag is set for the first channel in the span at handle_resume */ - - /* clear the resume flag */ + /* clear the RESUME flag */ sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); - /* go to restart state */ - goto suspend_goto_last; - } + /* if there are any resets present */ + if ((sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) || + (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) || + (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) || + (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { + /* go back to the reset state */ + goto suspend_goto_restart; + } else { + + /* bring the sig status back up */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + } + + /* go back to the last state */ + goto suspend_goto_last; + } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */ + + if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", ""); + + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + + /* go back to the last state */ + goto suspend_goto_last; + } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ /**********************************************************************/ if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", ""); + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a BLA */ ft_to_sngss7_bla (ftdmchan); @@ -1053,6 +1032,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the unblock flag */ sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); + /* bring the sig status up */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a uba */ ft_to_sngss7_uba (ftdmchan); @@ -1064,6 +1048,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", ""); + /* bring the sig status down */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_DOWN; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a blo */ ft_to_sngss7_blo (ftdmchan); @@ -1077,6 +1066,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the unblock flag */ sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX); + /* bring the sig status up */ + sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sigev.sigstatus = FTDM_SIG_STATE_UP; + ftdm_span_send_signal(ftdmchan->span, &sigev); + /* send a ubl */ ft_to_sngss7_ubl (ftdmchan); @@ -1117,14 +1111,10 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) ftdm_span_send_signal (ftdmchan->span, &sigev); /* remove any reset flags */ - sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP); - sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_TX); - sngss7_clear_flag (sngss7_info, FLAG_RESET_TX_RSP); - sngss7_clear_flag (sngss7_info, FLAG_RESET_TX); - sngss7_clear_flag (sngss7_info, FLAG_RESET_SENT); - sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_RX); - sngss7_clear_flag (sngss7_info, FLAG_RESET_RX); - sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_BASE); + clear_rx_grs_flags(sngss7_info); + clear_tx_grs_flags(sngss7_info); + clear_rx_rsc_flags(sngss7_info); + clear_tx_rsc_flags(sngss7_info); /* bring the channel down */ goto suspend_goto_last; @@ -1133,8 +1123,14 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");; - /* throw the channel into reset from our side since it is already in reset from the remote side */ - sngss7_set_flag (sngss7_info, FLAG_RESET_TX); + /* remove the UCIC block flag */ + sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + + /* remove the UCIC unblock flag */ + sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); + + /* throw the channel into reset to sync states */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX); /* bring the channel into restart again */ goto suspend_goto_restart; @@ -1182,9 +1178,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) /* check if there is a pending state change, give it a bit to clear */ if (check_for_state_change(ftdmchan)) { SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic); - ftdm_mutex_unlock(ftdmchan->mutex); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); + /* check if we need to die */ SS7_ASSERT; + /* end the request */ + goto outgoing_fail; }; /* check if the channel sig state is UP */ @@ -1295,6 +1292,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) ftdm_channel_t *ftdmchan = NULL; sngss7_chan_data_t *sngss7_info = NULL; sngss7_span_data_t *sngss7_span = NULL; + sng_isup_inf_t *sngss7_intf = NULL; int x; @@ -1304,15 +1302,26 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) for (x = 1; x < (span->chan_count + 1); x++) { /* extract the channel structure and sngss7 channel data */ ftdmchan = span->channels[x]; + if (ftdmchan->call_data == NULL) continue; sngss7_info = ftdmchan->call_data; sngss7_span = ftdmchan->span->mod_data; + sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; + /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - /* throw the pause flag */ - sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); - + /* check if the interface is paused or resumed */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + /* throw the pause flag */ + sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); + } else { + /* throw the pause flag */ + sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); + } +#if 0 /* throw the grp reset flag */ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); if (x == 1) { @@ -1320,7 +1329,10 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; sngss7_span->tx_grs.range = span->chan_count -1; } - +#else + /* throw the channel into reset */ + sngss7_set_flag(sngss7_info, FLAG_RESET_TX); +#endif /* throw the channel to suspend */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1446,6 +1458,9 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config) static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) { /*this function is called by the FT-core to load the signaling module */ + uint32_t major = 0; + uint32_t minor = 0; + uint32_t build = 0; ftdm_log (FTDM_LOG_INFO, "Loading ftmod_sangoma_ss7...\n"); @@ -1454,6 +1469,8 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sngss7_id = 0; + cmbLinkSetId = 1; + /* initalize the global gen_config flag */ g_ftdm_sngss7_data.gen_config = 0; @@ -1493,6 +1510,10 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) /* initalize sng_ss7 library */ sng_isup_init (&sng_event); + /* print the version of the library being used */ + sng_isup_version(&major, &minor, &build); + SS7_INFO("Loaded LibSng-SS7 %d.%d.%d\n", major, minor, build); + /* crash on assert fail */ ftdm_global_set_crash_policy (FTDM_CRASH_ON_ASSERT); 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 050f59e00e..d44815df0f 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 @@ -79,7 +79,8 @@ typedef enum { typedef enum { CONFIGURED = (1 << 0), - ACTIVE = (1 << 1) + ACTIVE = (1 << 1), + SNGSS7_PAUSED = (1 << 7) } sng_flag_t; typedef struct sng_mtp_link { @@ -139,7 +140,6 @@ typedef struct sng_mtp_link { uint32_t t23; uint32_t t24; uint32_t t25; - uint32_t t26; uint32_t t27; uint32_t t28; uint32_t t29; @@ -163,6 +163,8 @@ typedef struct sng_link_set { uint32_t flags; uint32_t apc; uint32_t linkType; + uint32_t switchType; + uint32_t ssf; uint32_t minActive; uint32_t numLinks; uint32_t links[16]; @@ -174,9 +176,11 @@ typedef struct sng_route { uint32_t flags; uint32_t dpc; uint32_t cmbLinkSetId; + uint32_t linkSetId; uint32_t linkType; uint32_t switchType; uint32_t ssf; + uint32_t nwId; uint32_t isSTP; uint32_t t6; uint32_t t8; @@ -188,6 +192,7 @@ typedef struct sng_route { uint32_t t19; uint32_t t21; uint32_t t25; + uint32_t t26; } sng_route_t; typedef struct sng_isup_intf { @@ -312,7 +317,7 @@ typedef struct ftdm_sngss7_data { }ftdm_sngss7_data_t; typedef struct sngss7_timer_data { - ftdm_timer_t *heartbeat_timer; + ftdm_timer_id_t hb_timer_id; int beat; int counter; ftdm_sched_callback_t callback; @@ -329,6 +334,9 @@ typedef struct sngss7_glare_data { typedef struct sngss7_group_data { uint32_t circuit; uint32_t range; + uint8_t status[255]; + uint8_t type; + uint8_t cause; }sngss7_group_data_t; typedef struct sngss7_chan_data { @@ -347,7 +355,12 @@ typedef struct sngss7_chan_data { typedef struct sngss7_span_data { ftdm_sched_t *sched; sngss7_group_data_t rx_grs; + sngss7_group_data_t rx_gra; sngss7_group_data_t tx_grs; + sngss7_group_data_t rx_cgb; + sngss7_group_data_t tx_cgb; + sngss7_group_data_t rx_cgu; + sngss7_group_data_t tx_cgu; ftdm_queue_t *event_queue; }sngss7_span_data_t; @@ -376,8 +389,8 @@ typedef struct sngss7_event_data typedef enum { - FLAG_RESET_RX = (1 << 0), - FLAG_RESET_TX = (1 << 1), + FLAG_RESET_RX = (1 << 0), + FLAG_RESET_TX = (1 << 1), FLAG_RESET_SENT = (1 << 2), FLAG_RESET_TX_RSP = (1 << 3), FLAG_GRP_RESET_RX = (1 << 4), @@ -387,27 +400,25 @@ typedef enum { FLAG_GRP_RESET_TX = (1 << 8), FLAG_GRP_RESET_SENT = (1 << 9), FLAG_GRP_RESET_TX_RSP = (1 << 10), - FLAG_REMOTE_REL = (1 << 11), - FLAG_LOCAL_REL = (1 << 12), - FLAG_GLARE = (1 << 13), - FLAG_INFID_RESUME = (1 << 14), - FLAG_INFID_PAUSED = (1 << 15), + FLAG_REMOTE_REL = (1 << 11), + FLAG_LOCAL_REL = (1 << 12), + FLAG_GLARE = (1 << 13), + FLAG_INFID_RESUME = (1 << 14), + FLAG_INFID_PAUSED = (1 << 15), FLAG_CKT_UCIC_BLOCK = (1 << 16), FLAG_CKT_UCIC_UNBLK = (1 << 17), FLAG_CKT_LC_BLOCK_RX = (1 << 18), FLAG_CKT_LC_UNBLK_RX = (1 << 19), FLAG_CKT_MN_BLOCK_RX = (1 << 20), - FLAG_CKT_MN_BLOCK_TX = (1 << 21), - FLAG_CKT_MN_UNBLK_RX = (1 << 22), + FLAG_CKT_MN_UNBLK_RX = (1 << 21), + FLAG_CKT_MN_BLOCK_TX = (1 << 22), FLAG_CKT_MN_UNBLK_TX = (1 << 23), FLAG_GRP_HW_BLOCK_RX = (1 << 24), FLAG_GRP_HW_BLOCK_TX = (1 << 25), FLAG_GRP_MN_BLOCK_RX = (1 << 26), FLAG_GRP_MN_BLOCK_TX = (1 << 27), - FLAG_GRP_HW_UNBLK_RX = (1 << 28), - FLAG_GRP_HW_UNBLK_TX = (1 << 29), - FLAG_GRP_MN_UNBLK_RX = (1 << 30), - FLAG_GRP_MN_UNBLK_TX = (1 << 31) + FLAG_GRP_HW_UNBLK_TX = (1 << 28), + FLAG_GRP_MN_UNBLK_TX = (1 << 29) } flag_t; /******************************************************************************/ @@ -415,9 +426,14 @@ typedef enum { extern ftdm_sngss7_data_t g_ftdm_sngss7_data; extern uint32_t sngss7_id; extern ftdm_sched_t *sngss7_sched; +extern int cmbLinkSetId; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ +/* in ftmod_sangoma_ss7_main.c */ +void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan); + +/* in ftmod_sangoma_ss7_logger.c */ void handle_sng_log(uint8_t level, char *fmt,...); void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta); void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); @@ -425,6 +441,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta); void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta); void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta); +/* in ftmod_sangoma_ss7_cfg.c */ int ft_to_sngss7_cfg_all(void); int ftmod_ss7_mtp1_gen_config(void); int ftmod_ss7_mtp2_gen_config(void); @@ -443,14 +460,26 @@ int ftmod_ss7_isup_ckt_config(int id); int ftmod_ss7_isup_isap_config(int id); int ftmod_ss7_cc_isap_config(int id); +/* in ftmod_sangoma_ss7_cntrl.c */ +int ft_to_sngss7_activate_all(void); + int ftmod_ss7_inhibit_mtplink(uint32_t id); int ftmod_ss7_uninhibit_mtplink(uint32_t id); +int ftmod_ss7_activate_mtplink(uint32_t id); +int ftmod_ss7_deactivate_mtplink(uint32_t id); +int ftmod_ss7_deactivate2_mtplink(uint32_t id); +int ftmod_ss7_activate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); +int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); +int ftmod_ss7_lpo_mtplink(uint32_t id); +int ftmod_ss7_lpr_mtplink(uint32_t id); +/* in ftmod_sangoma_ss7_sta.c */ int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm); int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); -int ft_to_sngss7_activate_all(void); +/* in ftmod_sangoma_ss7_out.c */ void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan); void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan); void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan); @@ -465,7 +494,12 @@ void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan); void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan); void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan); void ft_to_sngss7_grs(ftdm_channel_t *ftdmchan); +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); +/* in ftmod_sangoma_ss7_in.c */ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); @@ -478,6 +512,7 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit); +/* in ftmod_sangoma_ss7_handle.c */ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType); ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt); @@ -508,6 +543,13 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt); +/* in ftmod_sangoma_ss7_xml.c */ +int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span); + +/* in ftmod_sangoma_ss7_cli.c */ +ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data); + +/* in ftmod_sangoma_ss7_support.c */ uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum); uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum); @@ -519,11 +561,19 @@ int check_for_reset(sngss7_chan_data_t *sngss7_info); ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan); unsigned long get_unique_id(void); -int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span); +ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan); +ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan); +ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); +ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); +ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info); +ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info); +ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info); +ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info); + + +/* in ftmod_sangoma_ss7_timers.c */ void handle_isup_t35(void *userdata); - -ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data); /******************************************************************************/ /* MACROS *********************************************************************/ @@ -654,7 +704,14 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha #define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag)) #define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag)) -# define SS7_ASSERT *(int*)0=0; +#ifdef SS7_PRODUCTION +# define SS7_ASSERT \ + SS7_INFO_CHAN(ftdmchan,"Production Mode, continuing%s\n", ""); +#else +# define SS7_ASSERT \ + SS7_ERROR_CHAN(ftdmchan, "Debugging Mode, ending%s\n", ""); \ + *(int*)0=0; +#endif /******************************************************************************/ /******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index 4fac251c17..8b3f9d8424 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 @@ -42,24 +42,30 @@ /******************************************************************************/ /* PROTOTYPES *****************************************************************/ -void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan); +void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_acm(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_anm(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_rel(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_rlc(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan); +void ft_to_sngss7_rsc(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_rsca(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan); +void ft_to_sngss7_blo(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_bla(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_ubl(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_uba(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan); +void ft_to_sngss7_lpa(ftdm_channel_t * ftdmchan); -void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan); -void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan); +void ft_to_sngss7_gra(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_grs(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_cgba(ftdm_channel_t * ftdmchan); +void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -67,8 +73,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) { SS7_FUNC_TRACE_ENTER (__FUNCTION__); - sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; - SiConEvnt iam; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;; + const char *nadi = NULL; + SiConEvnt iam; sngss7_info->suInstId = get_unique_id (); sngss7_info->spInstId = 0; @@ -98,7 +105,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED; iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF; - iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_REQAW; + iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_PREFAW; iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF; iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN; iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF; @@ -113,21 +120,89 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) 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.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS88) || + (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS92) || + (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].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); + copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum); + + /* check if the user would like a custom NADI value for the calling Pty Num */ + nadi = ftdm_channel_get_var(ftdmchan, "ss7_nadi"); + if ((nadi != NULL) && (*nadi)) { + SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", nadi); + iam.cgPtyNum.natAddrInd.val = atoi(nadi); + } else { + SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found, using \"3\" %s\n", " "); + iam.cgPtyNum.natAddrInd.val = 0x03; + } + sng_cc_con_request (sngss7_info->spId, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &iam, 0); - - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx IAM\n"); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\", cld = \"%s\"\n", + sngss7_info->circuit->cic, + ftdmchan->caller_data.cid_num.digits, + ftdmchan->caller_data.dnis.digits); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -144,29 +219,29 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) memset (&acm, 0x0, sizeof (acm)); /* fill in the needed information for the ACM */ - acm.bckCallInd.eh.pres = PRSNT_NODEF; - acm.bckCallInd.chrgInd.pres = PRSNT_NODEF; - acm.bckCallInd.chrgInd.val = 0x00; - acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF; - acm.bckCallInd.cadPtyStatInd.val = 0x01; - acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF; - acm.bckCallInd.cadPtyCatInd.val = 0x00; - acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndMethInd.val = 0x00; - acm.bckCallInd.intInd.pres = PRSNT_NODEF; - acm.bckCallInd.intInd.val = 0x00; - acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF; - acm.bckCallInd.end2EndInfoInd.val = 0x00; - acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnUsrPrtInd.val = 0x0; - acm.bckCallInd.holdInd.pres = PRSNT_NODEF; - acm.bckCallInd.holdInd.val = 0x00; - acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF; - acm.bckCallInd.isdnAccInd.val = 0x0; - acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF; - acm.bckCallInd.echoCtrlDevInd.val = 0x0; - acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF; - acm.bckCallInd.sccpMethInd.val = 0x00; + acm.bckCallInd.eh.pres = PRSNT_NODEF; + acm.bckCallInd.chrgInd.pres = PRSNT_NODEF; + acm.bckCallInd.chrgInd.val = CHRG_CHRG; + acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF; + acm.bckCallInd.cadPtyStatInd.val = 0x01; + acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF; + acm.bckCallInd.cadPtyCatInd.val = CADCAT_ORDSUBS; + acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF; + acm.bckCallInd.end2EndMethInd.val = E2EMTH_NOMETH; + acm.bckCallInd.intInd.pres = PRSNT_NODEF; + acm.bckCallInd.intInd.val = INTIND_NOINTW; + acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF; + acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO; + acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF; + acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED; + acm.bckCallInd.holdInd.pres = PRSNT_NODEF; + acm.bckCallInd.holdInd.val = HOLD_NOTREQD; + acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF; + acm.bckCallInd.isdnAccInd.val = ISDNACC_NONISDN; + acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF; + acm.bckCallInd.echoCtrlDevInd.val = 0x1; /* ec device present */ + acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF; + acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND; /* send the ACM request to LibSngSS7 */ sng_cc_con_status (1, @@ -176,7 +251,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) &acm, ADDRCMPLT); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ACM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -200,7 +275,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan) &anm, 5); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ANM\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -233,7 +308,9 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan) sngss7_info->circuit->id, &rel); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx REL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n", + sngss7_info->circuit->cic, + ftdmchan->caller_data.hangup_cause ); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -256,7 +333,7 @@ void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan) sngss7_info->circuit->id, &rlc); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -277,7 +354,7 @@ void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan) SIT_STA_CIRRESREQ, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -298,7 +375,7 @@ void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan) SIT_STA_CIRRESRSP, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC-RLC\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -319,7 +396,7 @@ void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan) SIT_STA_CIRBLOREQ, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLO\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -340,7 +417,7 @@ void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan) SIT_STA_CIRBLORSP, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -362,7 +439,7 @@ ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan) SIT_STA_CIRUBLREQ, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBL\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -383,7 +460,7 @@ void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan) SIT_STA_CIRUBLRSP, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -404,7 +481,7 @@ void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan) SIT_STA_LOOPBACKACK, NULL); - SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx LPA\n"); + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic); SS7_FUNC_TRACE_EXIT (__FUNCTION__); return; @@ -445,7 +522,8 @@ void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan) SIT_STA_GRSRSP, &gra); - SS7_INFO_CHAN(ftdmchan, "Tx GRA (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx GRA (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->rx_grs.range)); @@ -463,7 +541,7 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) SiStaEvnt grs; - memset (&grs, 0x0, sizeof (grs)); + memset (&grs, 0x0, sizeof(grs)); grs.rangStat.eh.pres = PRSNT_NODEF; grs.rangStat.range.pres = PRSNT_NODEF; @@ -477,7 +555,8 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) SIT_STA_GRSREQ, &grs); - SS7_INFO_CHAN(ftdmchan, "Tx GRS (%d:%d)\n", + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx GRS (%d:%d)\n", + sngss7_info->circuit->cic, sngss7_info->circuit->cic, (sngss7_info->circuit->cic + sngss7_span->tx_grs.range)); @@ -485,6 +564,205 @@ void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan) return; } +/******************************************************************************/ +void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan) +{ + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + + sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + int x = 0; + + SiStaEvnt cgba; + + memset (&cgba, 0x0, sizeof(cgba)); + + /* fill in the circuit group supervisory message */ + cgba.cgsmti.eh.pres = PRSNT_NODEF; + cgba.cgsmti.typeInd.pres = PRSNT_NODEF; + cgba.cgsmti.typeInd.val = sngss7_span->rx_cgb.type; + + cgba.rangStat.eh.pres = PRSNT_NODEF; + /* fill in the range */ + cgba.rangStat.range.pres = PRSNT_NODEF; + cgba.rangStat.range.val = sngss7_span->rx_cgb.range; + /* fill in the status */ + cgba.rangStat.status.pres = PRSNT_NODEF; + cgba.rangStat.status.len = ((sngss7_span->rx_cgb.range + 1) >> 3) + (((sngss7_span->rx_cgb.range + 1) & 0x07) ? 1 : 0); + for(x = 0; x < cgba.rangStat.status.len; x++){ + cgba.rangStat.status.val[x] = sngss7_span->rx_cgb.status[x]; + } + + sng_cc_sta_request (1, + 0, + 0, + sngss7_span->rx_cgb.circuit, + 0, + SIT_STA_CGBRSP, + &cgba); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGBA (%d:%d)\n", + sngss7_info->circuit->cic, + sngss7_info->circuit->cic, + (sngss7_info->circuit->cic + sngss7_span->rx_cgb.range)); + + /* clean out the saved data */ + memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t)); + + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; +} + +/******************************************************************************/ +void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan) +{ + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + + sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + int x = 0; + + SiStaEvnt cgua; + + memset (&cgua, 0x0, sizeof(cgua)); + + /* fill in the circuit group supervisory message */ + cgua.cgsmti.eh.pres = PRSNT_NODEF; + cgua.cgsmti.typeInd.pres = PRSNT_NODEF; + cgua.cgsmti.typeInd.val = sngss7_span->rx_cgu.type; + + cgua.rangStat.eh.pres = PRSNT_NODEF; + /* fill in the range */ + cgua.rangStat.range.pres = PRSNT_NODEF; + cgua.rangStat.range.val = sngss7_span->rx_cgu.range; + /* fill in the status */ + cgua.rangStat.status.pres = PRSNT_NODEF; + cgua.rangStat.status.len = ((sngss7_span->rx_cgu.range + 1) >> 3) + (((sngss7_span->rx_cgu.range + 1) & 0x07) ? 1 : 0); + for(x = 0; x < cgua.rangStat.status.len; x++){ + cgua.rangStat.status.val[x] = sngss7_span->rx_cgu.status[x]; + } + + sng_cc_sta_request (1, + 0, + 0, + sngss7_span->rx_cgu.circuit, + 0, + SIT_STA_CGURSP, + &cgua); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGUA (%d:%d)\n", + sngss7_info->circuit->cic, + sngss7_info->circuit->cic, + (sngss7_info->circuit->cic + sngss7_span->rx_cgu.range)); + + /* clean out the saved data */ + memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t)); + + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; +} + +/******************************************************************************/ +void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan) +{ + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + + sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + SiStaEvnt cgb; + int x = 0; + + + memset (&cgb, 0x0, sizeof(cgb)); + + /* fill in the circuit group supervisory message */ + cgb.cgsmti.eh.pres = PRSNT_NODEF; + cgb.cgsmti.typeInd.pres = PRSNT_NODEF; + cgb.cgsmti.typeInd.val = sngss7_span->tx_cgb.type; + + /* fill in the range */ + cgb.rangStat.eh.pres = PRSNT_NODEF; + cgb.rangStat.range.pres = PRSNT_NODEF; + cgb.rangStat.range.val = sngss7_span->tx_cgb.range; + + /* fill in the status */ + cgb.rangStat.status.pres = PRSNT_NODEF; + cgb.rangStat.status.len = ((sngss7_span->tx_cgb.range + 1) >> 3) + (((sngss7_span->tx_cgb.range + 1) & 0x07) ? 1 : 0); + for(x = 0; x < cgb.rangStat.status.len; x++){ + cgb.rangStat.status.val[x] = sngss7_span->tx_cgb.status[x]; + } + + sng_cc_sta_request (1, + 0, + 0, + sngss7_span->tx_cgb.circuit, + 0, + SIT_STA_CGBREQ, + &cgb); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGB (%d:%d)\n", + sngss7_info->circuit->cic, + sngss7_info->circuit->cic, + (sngss7_info->circuit->cic + sngss7_span->tx_cgb.range)); + + /* clean out the saved data */ + memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t)); + + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; +} + +/******************************************************************************/ +void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan) +{ + SS7_FUNC_TRACE_ENTER (__FUNCTION__); + + sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data; + sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; + SiStaEvnt cgu; + int x = 0; + + + memset (&cgu, 0x0, sizeof(cgu)); + + /* fill in the circuit group supervisory message */ + cgu.cgsmti.eh.pres = PRSNT_NODEF; + cgu.cgsmti.typeInd.pres = PRSNT_NODEF; + cgu.cgsmti.typeInd.val = sngss7_span->tx_cgu.type; + + /* fill in the range */ + cgu.rangStat.eh.pres = PRSNT_NODEF; + cgu.rangStat.range.pres = PRSNT_NODEF; + cgu.rangStat.range.val = sngss7_span->tx_cgu.range; + + /* fill in the status */ + cgu.rangStat.status.pres = PRSNT_NODEF; + cgu.rangStat.status.len = ((sngss7_span->tx_cgu.range + 1) >> 3) + (((sngss7_span->tx_cgu.range + 1) & 0x07) ? 1 : 0); + for(x = 0; x < cgu.rangStat.status.len; x++){ + cgu.rangStat.status.val[x] = sngss7_span->tx_cgu.status[x]; + } + + sng_cc_sta_request (1, + 0, + 0, + sngss7_span->tx_cgu.circuit, + 0, + SIT_STA_CGUREQ, + &cgu); + + SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGU (%d:%d)\n", + sngss7_info->circuit->cic, + sngss7_info->circuit->cic, + (sngss7_info->circuit->cic + sngss7_span->tx_cgu.range)); + + /* clean out the saved data */ + memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t)); + + SS7_FUNC_TRACE_EXIT (__FUNCTION__); + return; +} + + /******************************************************************************/ /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c index 305e1a50f5..d238462046 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c @@ -68,7 +68,7 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm) sta.hdr.elmId.elmnt = STLNKSET; sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; - sta.hdr.elmId.elmntInst2 = 1; + sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0]; return(sng_sta_mtp3(&sta, cfm)); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 97957f3c82..dfa174e85a 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 @@ -57,6 +57,15 @@ unsigned long get_unique_id(void); ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan); +ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan); +ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan); +ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan); +ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan); + +ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info); +ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info); +ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info); +ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -72,9 +81,10 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) int k; int j; int flag; + int odd; char tmp[2]; - unsigned char lower; - unsigned char upper; + uint8_t lower; + uint8_t upper; /**************************************************************************/ cgPtyNum->eh.pres = PRSNT_NODEF; @@ -104,81 +114,73 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum) 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 (!(isdigit(tmp[0])) && (tmp[0] != '\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') { - if (isdigit(tmp[0])) { - lower = atoi(&tmp[0]); + /* push it into the lower nibble */ + lower = atoi(&tmp[0]); + /* 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 (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { k++; tmp[0] = ftdm->cid_num.digits[k]; - } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } /* while(!(isdigit(tmp))) */ + } /* while(!(isdigit(tmp))) */ - if (tmp[0] != '\0') { - lower = atoi(&tmp[0]); - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - } /* (isdigit(tmp)) */ - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - - tmp[0] = ftdm->cid_num.digits[k]; - - if (tmp[0] != '\0') { - if (isdigit(tmp[0])) { + /* check if tmp is null or a digit */ + if (tmp[0] != '\0') { + /* push the digit into the upper nibble */ upper = (atoi(&tmp[0])) << 4; } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->cid_num.digits[k]; - } /* while(!(isdigit(tmp))) */ - - if (tmp[0] != '\0') { - upper = (atoi(&tmp[0])) << 4; - k++; - } else { - flag = 1; - upper = 0xf; - } /* if (tmp != '\0') */ - } /* if (isdigit(tmp)) */ - } else { - if (flag == 1) { + /* there is no upper ... fill in 0 */ upper = 0x0; - } else { + /* throw the odd flag */ + odd = 1; + /* throw the end flag */ flag = 1; - upper = 0xf; - } /* if (flag == 1) */ - } /* if (tmp != '\0') */ + } /* if (tmp != '\0') */ + } else { + /* keep the odd flag down */ + odd = 0; + /* throw the flag */ + flag = 1; + } + /* push the digits into the trillium structure */ cgPtyNum->addrSig.val[j] = upper | lower; + /* increment the trillium pointer */ j++; - if (flag) { - break; - } else { - k++; - } + /* 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 = ((cgPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00; - + cgPtyNum->oddEven.val = odd; /**************************************************************************/ return 0; } @@ -196,9 +198,10 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) int k; int j; int flag; + int odd; char tmp[2]; - unsigned char lower; - unsigned char upper; + uint8_t lower; + uint8_t upper; /**************************************************************************/ cdPtyNum->eh.pres = PRSNT_NODEF; @@ -217,77 +220,74 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) /* 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 (!(isdigit(tmp[0])) && (tmp[0] != '\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') { - if (isdigit(tmp[0])) { - lower = atoi(&tmp[0]); + /* push it into the lower nibble */ + lower = atoi(&tmp[0]); + /* 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 (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { k++; tmp[0] = ftdm->dnis.digits[k]; - } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->dnis.digits[k]; - } /* while(!(isdigit(tmp))) */ + } /* while(!(isdigit(tmp))) */ - if (tmp[0] != '\0') { - lower = atoi(&tmp[0]); - k++; - tmp[0] = ftdm->dnis.digits[k]; - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - } /* (isdigit(tmp)) */ - } else { - flag = 1; - lower = 0xf; - } /* if (tmp != '\0') */ - - tmp[0] = ftdm->dnis.digits[k]; - - if (tmp[0] != '\0') { - if (isdigit(tmp[0])) { + /* check if tmp is null or a digit */ + if (tmp[0] != '\0') { + /* push the digit into the upper nibble */ upper = (atoi(&tmp[0])) << 4; } else { - while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) { - k++; - tmp[0] = ftdm->dnis.digits[k]; - } /* while(!(isdigit(tmp))) */ - - if (tmp[0] != '\0') { - upper = (atoi(&tmp[0])) << 4; - k++; - } else { - flag = 1; - upper = 0xf; - } /* if (tmp != '\0') */ - } /* if (isdigit(tmp)) */ - } else { - if (flag == 1) { - upper = 0x0; - } else { + /* there is no upper ... fill in ST */ + upper = 0xF; + /* throw the odd flag */ + odd = 1; + /* throw the end flag */ flag = 1; - upper = 0xf; - } /* if (flag == 1) */ - } /* if (tmp != '\0') */ + } /* if (tmp != '\0') */ + } else { + /* keep the odd flag down */ + 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 (flag) { - break; - } else { - k++; - } + /* 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; @@ -295,7 +295,7 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum) /**************************************************************************/ cdPtyNum->oddEven.pres = PRSNT_NODEF; - cdPtyNum->oddEven.val = ((cdPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00; + cdPtyNum->oddEven.val = odd; /**************************************************************************/ return 0; @@ -313,9 +313,9 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven) j = 0; for (i = 0; i < str.len; i++) { - sprintf(&ftdm[j], "%d", (str.val[i] & 0x0F)); + sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F)); j++; - sprintf(&ftdm[j], "%d", ((str.val[i] & 0xF0) >> 4)); + sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4)); j++; } @@ -325,6 +325,8 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven) } else { ftdm[j] = '\0'; } + + } else { SS7_ERROR("Asked to copy tknStr that is not present!\n"); return 1; @@ -450,6 +452,353 @@ unsigned long get_unique_id(void) return(sngss7_id); } +/******************************************************************************/ +ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan) +{ + ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; + int i; + + for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { + + /* extract the channel in question */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); + continue; + } + + /* check if the GRP_RESET_RX flag is already up */ + if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) { + /* we have already processed this channel...move along */ + continue; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } + + SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range)); + + /* flag the channel as having received a reset */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); + + switch (ftdmchan->state) { + /**************************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* go to idle so that we can redo the restart state*/ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE); + + break; + /**************************************************************************/ + default: + + /* set the state of the channel to restart...the rest is done by the chan monitor */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); + break; + /**************************************************************************/ + } /* switch (ftdmchan->state) */ + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for (chans in GRS */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) +{ + ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; + int i; + int byte = 0; + int bit = 0; + + + ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id); + + /* check all the circuits in the range to see if they are done resetting */ + for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { + + /* extract the channel in question */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); + continue; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if there is a state change pending on the channel */ + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + /* check the state to the GRP_RESET_RX_DN flag */ + if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { + /* this channel is still resetting...do nothing */ + goto GRS_UNLOCK_ALL; + } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ + } else { + /* state change pending */ + goto GRS_UNLOCK_ALL; + } + } /* for ( i = circuit; i < (circuit + range + 1); i++) */ + + SS7_DEBUG("All circuits out of reset for GRS: circuit=%d, range=%d\n", + sngss7_span->rx_grs.circuit, + sngss7_span->rx_grs.range); + + /* check all the circuits in the range to see if they are done resetting */ + for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { + + /* extract the channel in question */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i); + /* check if we need to die */ + SS7_ASSERT; + /* move along */ + continue; + } + + /* throw the GRP reset flag complete flag */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); + + /* move the channel to the down state */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + /* update the status map if the ckt is in blocked state */ + if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || + (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + + sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit)); + } /* if blocked */ + + /* update the bit and byte counter*/ + bit ++; + if (bit == 8) { + byte++; + bit = 0; + } + } /* for ( i = circuit; i < (circuit + range + 1); i++) */ + +GRS_UNLOCK_ALL: + for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) { + /* extract the channel in question */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); + continue; + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) +{ + ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data; + int i; + + for ( i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) { + + /* extract the channel in question */ + if (extract_chan_data(i, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i); + continue; + } + + /* check if the channel is already procoessing the GRA */ + if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { + /* move along */ + continue; + } + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } + + SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n", + g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic, + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic + sngss7_span->rx_gra.range)); + + switch (ftdmchan->state) { + /**********************************************************************/ + case FTDM_CHANNEL_STATE_RESTART: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + /* go to DOWN */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_DOWN: + + /* do nothing, just drop the message */ + SS7_DEBUG("Receveived GRA in down state, dropping\n"); + + break; + /**********************************************************************/ + case FTDM_CHANNEL_STATE_TERMINATING: + case FTDM_CHANNEL_STATE_HANGUP: + case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + + /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + break; + /**********************************************************************/ + default: + /* ITU Q764-2.9.5.1.c -> release the circuit */ + if (sngss7_span->rx_gra.cause != 0) { + ftdmchan->caller_data.hangup_cause = sngss7_span->rx_gra.cause; + } else { + ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */ + } + + /* go to terminating to hang up the call */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + break; + /**********************************************************************/ + } + + /* unlock the channel again before we exit */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for ( circuits in request */ + + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) +{ + ftdm_channel_t *ftdmchan = NULL; + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_sigmsg_t sigev; + int x; + + for (x = 1; x < (ftdmspan->chan_count + 1); x++) { + + /* extract the channel structure and sngss7 channel data */ + ftdmchan = ftdmspan->channels[x]; + + /* if the call data is NULL move on */ + if (ftdmchan->call_data == NULL) continue; + + sngss7_info = ftdmchan->call_data; + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + memset (&sigev, 0, sizeof (sigev)); + + sigev.chan_id = ftdmchan->chan_id; + sigev.span_id = ftdmchan->span_id; + sigev.channel = ftdmchan; + + /* if we have the PAUSED flag and the sig status is still UP */ + if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) && + (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } + + /* throw the channel into SUSPENDED to process the flag */ + /* after doing this once the sig status will be down */ + ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + } + + /* if the RESUME flag is up go to SUSPENDED to process the flag */ + /* after doing this the flag will be cleared */ + if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + + /* clear up any pending state changes */ + while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_sangoma_ss7_process_state_change (ftdmchan); + } + + /* got SUSPENDED state to clear the flag */ + ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + } + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + + } /* for (x = 1; x < (span->chan_count + 1); x++) */ + + /* signal the core that sig events are queued for processing */ + ftdm_span_trigger_signals(ftdmspan); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info) +{ + /* clear all the flags related to an incoming GRS */ + sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX); + sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); + sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info) +{ + /* clear all the flags related to an outgoing GRS */ + sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE); + sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX); + sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT); + sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info) +{ + /* clear all the flags related to an incoming RSC */ + sngss7_clear_flag(sngss7_info, FLAG_RESET_RX); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info) +{ + /* clear all the flags related to an outgoing RSC */ + sngss7_clear_flag(sngss7_info, FLAG_RESET_TX); + sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT); + sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP); + + return FTDM_SUCCESS; +} + /******************************************************************************/ /******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c index 5185ffcc62..75b32d6892 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c @@ -64,7 +64,7 @@ void handle_isup_t35(void *userdata) sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); /* hang up on timer expiry */ - ftdmchan->caller_data.hangup_cause = 102; + ftdmchan->caller_data.hangup_cause = 28; /* end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL); 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 aa639d1c3a..bd1be4b6a4 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 @@ -46,6 +46,8 @@ typedef struct sng_timeslot int gap; int hole; }sng_timeslot_t; + +int cmbLinkSetId; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ @@ -343,11 +345,11 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) /**********************************************************************/ } else if (!strcasecmp(parm->var, "apc")) { mtpLinkSet.apc = atoi(parm->val); - SS7_DEBUG("\tFoundmtpLinkSet->apc = %d\n", mtpLinkSet.apc); + SS7_DEBUG("\tFound mtpLinkSet->apc = %d\n", mtpLinkSet.apc); /**********************************************************************/ } else if (!strcasecmp(parm->var, "minActive")) { mtpLinkSet.minActive = atoi(parm->val); - SS7_DEBUG("\tFoundmtpLinkSet->minActive = %d\n", mtpLinkSet.minActive); + SS7_DEBUG("\tFound mtpLinkSet->minActive = %d\n", mtpLinkSet.minActive); /**********************************************************************/ } else { SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); @@ -385,8 +387,6 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) if (count < 1 || count > 15 ) { SS7_ERROR("Invalid number of mtp_links found (%d)\n", count); return FTDM_FAIL; - } else { - mtpLinkSet.numLinks = count; } /* now we need to see if this linkset exists already or not and grab an Id */ @@ -418,8 +418,7 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) mtpLink[i].mtp3.apc = mtpLinkSet.apc; mtpLink[i].mtp3.linkSetId = mtpLinkSet.id; - /* fill in the mtplink structure */ - mtpLinkSet.links[count] = ftmod_ss7_fill_in_mtpLink(&mtpLink[i]); + ftmod_ss7_fill_in_mtpLink(&mtpLink[i]); /* increment the links counter */ count++; @@ -428,6 +427,10 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) i++; } + mtpLinkSet.linkType = mtpLink[0].mtp3.linkType; + mtpLinkSet.switchType = mtpLink[0].mtp3.switchType; + mtpLinkSet.ssf = mtpLink[0].mtp3.ssf; + ftmod_ss7_fill_in_mtpLinkSet(&mtpLinkSet); return FTDM_SUCCESS; @@ -497,27 +500,27 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t * if (!strcasecmp(parm->val, "itu92")) { mtpLink->mtp2.linkType = LSD_SW_ITU92; mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ITU92\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ITU92\"\n"); } else if (!strcasecmp(parm->val, "itu88")) { mtpLink->mtp2.linkType = LSD_SW_ITU88; mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ITU88\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ITU88\"\n"); } else if (!strcasecmp(parm->val, "ansi96")) { mtpLink->mtp2.linkType = LSD_SW_ANSI92; mtpLink->mtp3.linkType = LSN_SW_ANS96; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI96\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI96\"\n"); } else if (!strcasecmp(parm->val, "ansi92")) { mtpLink->mtp2.linkType = LSD_SW_ANSI92; mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI92\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI92\"\n"); } else if (!strcasecmp(parm->val, "ansi88")) { mtpLink->mtp2.linkType = LSD_SW_ANSI88; mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ANSI88\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI88\"\n"); } else if (!strcasecmp(parm->val, "etsi")) { mtpLink->mtp2.linkType = LSD_SW_ITU92; mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->linkType = \"ETSI\"\n"); + SS7_DEBUG("\tFound mtpLink->linkType = \"ETSI\"\n"); } else { SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); return FTDM_FAIL; @@ -526,31 +529,40 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t * } else if (!strcasecmp(parm->var, "switchType")) { if (!strcasecmp(parm->val, "itu97")) { mtpLink->mtp3.switchType = LSI_SW_ITU97; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU97\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU97\"\n"); } else if (!strcasecmp(parm->val, "itu88")) { mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU88\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU88\"\n"); } else if (!strcasecmp(parm->val, "itu92")) { mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU92\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU92\"\n"); } else if (!strcasecmp(parm->val, "itu00")) { mtpLink->mtp3.switchType = LSI_SW_ITU2000; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ITU00\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ITU00\"\n"); } else if (!strcasecmp(parm->val, "ETSIV2")) { mtpLink->mtp3.switchType = LSI_SW_ETSI; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ETSIV2\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV2\"\n"); } else if (!strcasecmp(parm->val, "ETSIV3")) { mtpLink->mtp3.switchType = LSI_SW_ETSIV3; - SS7_DEBUG("\tFoundmtpLink->switchType = \"ETSIV3\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV3\"\n"); } else if (!strcasecmp(parm->val, "UK")) { mtpLink->mtp3.switchType = LSI_SW_UK; - SS7_DEBUG("\tFoundmtpLink->switchType = \"UK\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"UK\"\n"); } else if (!strcasecmp(parm->val, "RUSSIA")) { mtpLink->mtp3.switchType = LSI_SW_RUSSIA; - SS7_DEBUG("\tFoundmtpLink->switchType = \"RUSSIA\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"RUSSIA\"\n"); } else if (!strcasecmp(parm->val, "INDIA")) { mtpLink->mtp3.switchType = LSI_SW_INDIA; - SS7_DEBUG("\tFoundmtpLink->switchType = \"INDIA\"\n"); + SS7_DEBUG("\tFound mtpLink->switchType = \"INDIA\"\n"); + } else if (!strcasecmp(parm->val, "ansi88")) { + mtpLink->mtp3.switchType = LSI_SW_ANS88; + SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI88\"\n"); + } else if (!strcasecmp(parm->val, "ansi92")) { + mtpLink->mtp3.switchType = LSI_SW_ANS92; + SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI92\"\n"); + } else if (!strcasecmp(parm->val, "ansi95")) { + mtpLink->mtp3.switchType = LSI_SW_ANS95; + SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI95\"\n"); } else { SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); return FTDM_FAIL; @@ -568,7 +580,7 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t * /**********************************************************************/ } else if (!strcasecmp(parm->var, "slc")) { mtpLink->mtp3.slc = atoi(parm->val); - SS7_DEBUG("\tFoundmtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc); + SS7_DEBUG("\tFound mtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc); /**********************************************************************/ } else { SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); @@ -649,14 +661,17 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) /* check if the name matches */ if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, parm->val)) { - /* grab the mtpLink id value first*/ - int id = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[0]; - /* now, harvest the required infomormation from the global structure */ - mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.linkType; - mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.switchType; - mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLink[id].mtp3.ssf; - mtpRoute.cmbLinkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id; + mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].linkType; + mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].switchType; + mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].ssf; + mtpRoute.linkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id; + cmbLinkSetId++; + mtpRoute.cmbLinkSetId = cmbLinkSetId; + + /* update the linkset with the new cmbLinkSet value */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks++; + g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks-1] = mtpRoute.cmbLinkSetId; break; } x++; @@ -692,9 +707,11 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) parm = parm + 1; } + ftmod_ss7_fill_in_nsap(&mtpRoute); + ftmod_ss7_fill_in_mtp3_route(&mtpRoute); - ftmod_ss7_fill_in_nsap(&mtpRoute); + return FTDM_SUCCESS; } @@ -738,7 +755,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) int num_parms = isup_interface->n_parameters; int i; int linkSetId; - int linkId; memset(&sng_isup, 0x0, sizeof(sng_isup)); memset(&sng_isap, 0x0, sizeof(sng_isap)); @@ -772,36 +788,25 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) /* check if the name matches */ if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpRoute[x].name, parm->val)) { - /* now, harvest the required information from the global structure */ sng_isup.mtpRouteId = g_ftdm_sngss7_data.cfg.mtpRoute[x].id; sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[x].dpc; sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; - /* find the nwID from the nsap */ - int y = 1; - while (g_ftdm_sngss7_data.cfg.nsap[y].id != 0) { - - if ((g_ftdm_sngss7_data.cfg.nsap[y].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) && - (g_ftdm_sngss7_data.cfg.nsap[y].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) && - (g_ftdm_sngss7_data.cfg.nsap[y].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) { - + /* find the NSAP corresponding to this switchType and SSF */ + int z = 1; + while (g_ftdm_sngss7_data.cfg.nsap[z].id != 0) { + if ((g_ftdm_sngss7_data.cfg.nsap[z].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) && + (g_ftdm_sngss7_data.cfg.nsap[z].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) && + (g_ftdm_sngss7_data.cfg.nsap[z].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) { + sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[z].nwId; /* we have a match so break out of this loop */ break; } /* move on to the next one */ - y++; - } /* while (g_ftdm_sngss7_data.cfg.mtp3_isup[y].id != 0) */ - - /* check how we exited the last while loop */ - if (g_ftdm_sngss7_data.cfg.nsap[y].id == 0) { - SS7_ERROR("\tFailed to find the nwID for = \"%s\"!\n", parm->val); - return FTDM_FAIL; - } else { - sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[y].nwId; + z++; } - break; } x++; @@ -846,10 +851,15 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) } /* trickle down the SPC to all sub entities */ - linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].cmbLinkSetId; - for (i = 0; i < g_ftdm_sngss7_data.cfg.mtpLinkSet[linkSetId].numLinks; i ++) { - linkId = g_ftdm_sngss7_data.cfg.mtpLinkSet[linkSetId].links[i]; - g_ftdm_sngss7_data.cfg.mtpLink[linkId].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; + linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId; + + i = 1; + while (g_ftdm_sngss7_data.cfg.mtpLink[i].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkSetId == linkSetId) { + g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; + } + + i++; } ftmod_ss7_fill_in_isap(&sng_isap); @@ -858,8 +868,6 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) ftmod_ss7_fill_in_isup_interface(&sng_isup); - g_ftdm_sngss7_data.cfg.isap[sng_isap.id].spId = sng_isup.id; - return FTDM_SUCCESS; } @@ -957,7 +965,7 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) if ( mtpLink->mtp2.t7 != 0 ) { g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = mtpLink->mtp2.t7; }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 20; + g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 40; } if (mtpLink->mtp3.t1 != 0) { @@ -1057,21 +1065,19 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) /******************************************************************************/ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) { - int count; int i = mtpLinkSet->id; strcpy((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (char *)mtpLinkSet->name); g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = g_ftdm_sngss7_data.cfg.mtpLink[1].mtp3.linkType; /* KONRAD FIX ME */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = mtpLinkSet->linkType; + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].switchType = mtpLinkSet->switchType; + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].ssf = mtpLinkSet->ssf; + + /* these values are filled in as we find routes and start allocating cmbLinkSetIds */ g_ftdm_sngss7_data.cfg.mtpLinkSet[i].minActive = mtpLinkSet->minActive; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = mtpLinkSet->numLinks; - - for (count = 0; count < mtpLinkSet->numLinks; count++) { - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].links[count] = mtpLinkSet->links[count]; - } - + g_ftdm_sngss7_data.cfg.mtpLinkSet[i].numLinks = 0; return 0; } @@ -1083,8 +1089,7 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) /* go through all the existing routes and see if we find a match */ i = 1; while (g_ftdm_sngss7_data.cfg.mtpRoute[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc == mtp3_route->dpc) { - + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpRoute[i].name, mtp3_route->name)) { /* we have a match so break out of this loop */ break; } @@ -1106,8 +1111,10 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc; g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType = mtp3_route->linkType; g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType = mtp3_route->switchType; - g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = 1; /* mtp3_route->cmbLinkSetId;*/ + g_ftdm_sngss7_data.cfg.mtpRoute[i].cmbLinkSetId = mtp3_route->cmbLinkSetId; g_ftdm_sngss7_data.cfg.mtpRoute[i].isSTP = mtp3_route->isSTP; + g_ftdm_sngss7_data.cfg.mtpRoute[i].nwId = mtp3_route->nwId; + g_ftdm_sngss7_data.cfg.mtpRoute[i].linkSetId = mtp3_route->linkSetId; g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf = mtp3_route->ssf; if (mtp3_route->t6 != 0) { g_ftdm_sngss7_data.cfg.mtpRoute[i].t6 = mtp3_route->t6; @@ -1159,6 +1166,11 @@ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) } else { g_ftdm_sngss7_data.cfg.mtpRoute[i].t25 = 100; } + if (mtp3_route->t26 != 0) { + g_ftdm_sngss7_data.cfg.mtpRoute[i].t26 = mtp3_route->t26; + } else { + g_ftdm_sngss7_data.cfg.mtpRoute[i].t26 = 100; + } return 0; } @@ -1184,15 +1196,17 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) if (g_ftdm_sngss7_data.cfg.nsap[i].id == 0) { g_ftdm_sngss7_data.cfg.nsap[i].id = i; + mtp3_route->nwId = i; SS7_DEBUG("found new mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } else { g_ftdm_sngss7_data.cfg.nsap[i].id = i; + mtp3_route->nwId = i; SS7_DEBUG("found existing mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } g_ftdm_sngss7_data.cfg.nsap[i].spId = g_ftdm_sngss7_data.cfg.nsap[i].id; g_ftdm_sngss7_data.cfg.nsap[i].suId = g_ftdm_sngss7_data.cfg.nsap[i].id; - g_ftdm_sngss7_data.cfg.nsap[i].nwId = g_ftdm_sngss7_data.cfg.nsap[i].id; + g_ftdm_sngss7_data.cfg.nsap[i].nwId = mtp3_route->nwId; g_ftdm_sngss7_data.cfg.nsap[i].linkType = mtp3_route->linkType; g_ftdm_sngss7_data.cfg.nsap[i].switchType = mtp3_route->switchType; g_ftdm_sngss7_data.cfg.nsap[i].ssf = mtp3_route->ssf; @@ -1208,7 +1222,7 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) /* go through all the existing interfaces and see if we find a match */ i = 1; while (g_ftdm_sngss7_data.cfg.isupIntf[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.isupIntf[i].nwId == sng_isup->nwId) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.isupIntf[i].name, sng_isup->name)) { /* we have a match so break out of this loop */ break; @@ -1381,7 +1395,8 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap) } g_ftdm_sngss7_data.cfg.isap[i].id = sng_isap->id; - g_ftdm_sngss7_data.cfg.isap[i].suId = 1; /*KONRAD FIX ME */ + g_ftdm_sngss7_data.cfg.isap[i].suId = sng_isap->id; + g_ftdm_sngss7_data.cfg.isap[i].spId = sng_isap->id; g_ftdm_sngss7_data.cfg.isap[i].switchType = sng_isap->switchType; g_ftdm_sngss7_data.cfg.isap[i].ssf = sng_isap->ssf; @@ -1458,7 +1473,7 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap) if (sng_isap->tex != 0) { g_ftdm_sngss7_data.cfg.isap[i].tex = sng_isap->tex; } else { - g_ftdm_sngss7_data.cfg.isap[i].tex = 10; + g_ftdm_sngss7_data.cfg.isap[i].tex = 1000; } if (sng_isap->tcrm != 0) { g_ftdm_sngss7_data.cfg.isap[i].tcrm = sng_isap->tcrm; @@ -1499,7 +1514,9 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i SS7_DEBUG("found existing mtp3 self route\n"); return FTDM_SUCCESS; } else { - SS7_ERROR("found new mtp3 self route but it does not much the route already configured\n"); + SS7_ERROR("found new mtp3 self route but it does not match the route already configured (dpc=%d:spc=%d)\n", + g_ftdm_sngss7_data.cfg.mtpRoute[0].dpc, + spc); return FTDM_FAIL; } @@ -1583,11 +1600,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count; if (timeslot.siglink) { g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG; - } else if (timeslot.hole) { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE; + g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; } + if (timeslot.channel) { g_ftdm_sngss7_data.cfg.isupCkt[x].cic = cicbase; cicbase++; @@ -1608,6 +1624,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ + + /* increment the span channel count */ + count++; + } else { /* if ((timeslot.siglink) || (timeslot.gap)) */ /* find the ftdm the channel structure for this channel*/ i = 1; diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index be99f94aff..23463e9088 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -280,6 +280,25 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT); dtmf = "hardware"; } + + err = sangoma_tdm_get_hw_ec(chan->sockfd, &tdm_api); + if (err > 0) { + ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC); + } + +#ifdef WP_API_FEATURE_HWEC_PERSIST + err = sangoma_tdm_get_hwec_persist_status(chan->sockfd, &tdm_api); + if (err == 0) { + ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE); + } +#else + if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) { + ftdm_log(FTDM_LOG_WARNING, "WP_API_FEATURE_HWEC_PERSIST feature is not supported \ + with your version of libsangoma, you should update your Wanpipe drivers\n"); + + } +#endif + } #ifdef LIBSANGOMA_VERSION @@ -598,18 +617,33 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) break; case FTDM_COMMAND_ENABLE_ECHOCANCEL: { +#ifdef WP_API_FEATURE_EC_CHAN_STAT + err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api); + if (err > 0) { + /* Hardware echo canceller already enabled */ + err = 0; + break; + } +#endif err=sangoma_tdm_enable_hwec(ftdmchan->sockfd, &tdm_api); if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed"); + snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed"); return FTDM_FAIL; } } break; case FTDM_COMMAND_DISABLE_ECHOCANCEL: { +#ifdef WP_API_FEATURE_EC_CHAN_STAT + err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api); + if (!err) { + /* Hardware echo canceller already disabled */ + break; + } +#endif err=sangoma_tdm_disable_hwec(ftdmchan->sockfd, &tdm_api); if (err) { - snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed"); + snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed"); return FTDM_FAIL; } } diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index c4ba3ae749..ae9398418a 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -170,8 +170,8 @@ static const char *chanpath = NULL; static const char dahdi_ctlpath[] = "/dev/dahdi/ctl"; static const char dahdi_chanpath[] = "/dev/dahdi/channel"; -static const char zt_ctlpath[] = "/dev/ftdm/ctl"; -static const char zt_chanpath[] = "/dev/ftdm/channel"; +static const char zt_ctlpath[] = "/dev/zap/ctl"; +static const char zt_chanpath[] = "/dev/zap/channel"; static ftdm_socket_t CONTROL_FD = ZT_INVALID_SOCKET; @@ -974,7 +974,7 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) */ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) { - uint32_t i, event_id = 0; + uint32_t i, event_id = FTDM_OOB_INVALID; zt_event_t zt_event_id = 0; for(i = 1; i <= span->chan_count; i++) { @@ -1022,6 +1022,8 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) event_id = FTDM_OOB_OFFHOOK; } else if (span->channels[i]->type == FTDM_CHAN_TYPE_FXO) { event_id = FTDM_OOB_RING_START; + } else { + event_id = FTDM_OOB_NOOP; } } break; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 0437e02e51..1efe459032 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -386,7 +386,7 @@ typedef struct ftdm_conf_parameter { } ftdm_conf_parameter_t; /*! \brief Opaque general purpose iterator */ -typedef void ftdm_iterator_t; +typedef struct ftdm_iterator ftdm_iterator_t; /*! \brief Channel commands that can be executed through ftdm_channel_command() */ typedef enum { @@ -667,9 +667,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa /*! \brief Get span signaling status (ie: whether protocol layer is up or down) */ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status); -/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */ -FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); - /*! * \brief Set user private data in the channel * @@ -1032,8 +1029,19 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const c FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name); /*! \brief Get an iterator to iterate over the channel variables - * \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. */ -FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan); + * \param ftdmchan The channel structure containing the variables + * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. + * \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. + * This iterator is completely non-thread safe, if you are adding variables or removing variables while iterating + * results are unpredictable + */ +FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan, ftdm_iterator_t *iter); + +/*! \brief Get iterator current value (depends on the iterator type) + * \note Channel iterators return a pointer to ftdm_channel_t + * Variable iterators return a pointer to the variable name (not the variable value) + */ +FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter); /*! \brief Get variable name and value for the current iterator position */ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val); @@ -1041,6 +1049,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, co /*! \brief Advance iterator */ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter); +/*! \brief Free iterator + * \note You must free an iterator after using it unless you plan to reuse it + */ +FT_DECLARE(ftdm_status_t) ftdm_iterator_free(ftdm_iterator_t *iter); + /*! \brief Get the span pointer associated to the channel */ FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan); @@ -1144,6 +1157,12 @@ FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span); /*! \brief Get the span name */ FT_DECLARE(const char *) ftdm_span_get_name(const ftdm_span_t *span); +/*! \brief Get iterator for the span channels + * \param span The span containing the channels + * \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator. + */ +FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter); + /*! * \brief Execute a text command. The text command output will be returned and must be free'd * @@ -1154,16 +1173,6 @@ FT_DECLARE(const char *) ftdm_span_get_name(const ftdm_span_t *span); */ FT_DECLARE(char *) ftdm_api_execute(const char *cmd); -/*! - * \brief Disables CPU monitoring - * - * \note CPU monitoring is enabled by default. This means a thread will be launched at startup (ftdm_global_init) - * with the sole purpose of monitoring system-wide CPU usage. If the CPU usage raises above a defined - * threshold, no new calls will be accepted (neither incoming or outgoing) - * - */ -FT_DECLARE(void) ftdm_cpu_monitor_disable(void); - /*! * \brief Create a configuration node * @@ -1255,7 +1264,13 @@ FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *channe /*! \brief For display debugging purposes you can display this string which describes the last channel internal state */ FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *channel); -/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */ +/*! \brief For display debugging purposes you can display this string which describes the history of the channel + * \param channel The channel to get the history from + * \return History string for the channel. You must free the string with ftdm_free + */ +FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *channel); + +/*! \brief Initialize channel state for an outgoing call */ FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan); /*! \brief Initialize the library */ @@ -1279,6 +1294,12 @@ FT_DECLARE(void) ftdm_global_set_logger(ftdm_logger_t logger); /*! \brief Set the default logger level */ FT_DECLARE(void) ftdm_global_set_default_logger(int level); +/*! \brief Set the directory to look for modules */ +FT_DECLARE(void) ftdm_global_set_mod_directory(const char *path); + +/*! \brief Set the directory to look for configs */ +FT_DECLARE(void) ftdm_global_set_config_directory(const char *path); + /*! \brief Check if the FTDM library is initialized and running */ FT_DECLARE(ftdm_bool_t) ftdm_running(void); diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 74bea8148c..8bdbdd60f8 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -356,6 +356,15 @@ typedef struct { } ftdm_dtmf_debug_t; #endif +typedef struct { + const char *file; + const char *func; + int line; + ftdm_channel_state_t state; + ftdm_channel_state_t last_state; + ftdm_time_t time; +} ftdm_channel_history_entry_t; + /* 2^8 table size, one for each byte (sample) value */ #define FTDM_GAINS_TABLE_SIZE 256 struct ftdm_channel { @@ -381,6 +390,8 @@ struct ftdm_channel { ftdm_channel_state_t state; ftdm_channel_state_t last_state; ftdm_channel_state_t init_state; + ftdm_channel_history_entry_t history[10]; + uint8_t hindex; ftdm_mutex_t *mutex; teletone_dtmf_detect_state_t dtmf_detect; uint32_t buffer_delay; @@ -425,6 +436,7 @@ struct ftdm_channel { float txgain; int availability_rate; void *user_private; + ftdm_timer_id_t hangup_timer; #ifdef FTDM_DEBUG_DTMF ftdm_dtmf_debug_t dtmfdbg; #endif @@ -583,6 +595,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons /* dequeue pending signals and notify the user via the span signal callback */ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span); +/*! \brief clear the tone detector state */ +FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); + + /*! \brief Assert condition */ @@ -619,6 +635,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span); #define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) #define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id) +#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex) +#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex) + FT_DECLARE_DATA extern const char *FTDM_LEVEL_NAMES[9]; static __inline__ void ftdm_abort(void) diff --git a/libs/freetdm/src/include/private/ftdm_sched.h b/libs/freetdm/src/include/private/ftdm_sched.h index 0951d050a7..c1818d8bb5 100644 --- a/libs/freetdm/src/include/private/ftdm_sched.h +++ b/libs/freetdm/src/include/private/ftdm_sched.h @@ -44,8 +44,8 @@ extern "C" { #define FTDM_MICROSECONDS_PER_SECOND 1000000 typedef struct ftdm_sched ftdm_sched_t; -typedef struct ftdm_timer ftdm_timer_t; typedef void (*ftdm_sched_callback_t)(void *data); +typedef uint64_t ftdm_timer_id_t; /*! \brief Create a new scheduling context */ FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name); @@ -62,18 +62,22 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched); * \param name Timer name, typically unique but is not required to be unique, any null terminated string is fine (required) * \param callback The callback to call upon timer expiration (required) * \param data Optional data to pass to the callback - * \param timer The timer that was created, it can be NULL if you dont care, - * but you need this if you want to be able to cancel the timer with ftdm_sched_cancel_timer + * \param timer Timer id pointer to store the id of the newly created timer. It can be null + * if you do not need to know the id, but you need this if you want to be able + * to cancel the timer with ftdm_sched_cancel_timer */ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, - int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_t **timer); + int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timer); /*! * \brief Cancel the timer + * Note that there is a race between cancelling and triggering a timer. + * By the time you call this function the timer may be about to be triggered. + * This is specially true with timers in free run schedule. * \param sched The scheduling context (required) * \param timer The timer to cancel (required) */ -FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_t **timer); +FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timer); /*! \brief Destroy the context and all of the scheduled timers in it */ FT_DECLARE(ftdm_status_t) ftdm_sched_destroy(ftdm_sched_t **sched); @@ -91,6 +95,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_global_init(void); /*! \brief Checks if the main scheduling thread is running */ FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void); +/*! \brief Stop the main scheduling thread (if running) */ +FT_DECLARE(ftdm_bool_t) ftdm_free_sched_stop(void); + #ifdef __cplusplus } #endif diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index d8e8b5c2e6..bddefd9be6 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -191,6 +191,8 @@ typedef enum { FTDM_CHANNEL_FEATURE_CALLERID = (1 << 4), /*!< Channel can detect caller id (read-only) */ FTDM_CHANNEL_FEATURE_PROGRESS = (1 << 5), /*!< Channel can detect inband progress (read-only) */ FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */ + FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */ + FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */ } ftdm_channel_feature_t; typedef enum { @@ -322,9 +324,15 @@ struct ftdm_conf_node { /* first node child */ struct ftdm_conf_node *child; + /* last node child */ + struct ftdm_conf_node *last; + /* next node sibling */ struct ftdm_conf_node *next; + /* prev node sibling */ + struct ftdm_conf_node *prev; + /* my parent if any */ struct ftdm_conf_node *parent; }; @@ -366,6 +374,23 @@ typedef ftdm_status_t (*ftdm_span_start_t)(ftdm_span_t *span); typedef ftdm_status_t (*ftdm_span_stop_t)(ftdm_span_t *span); typedef ftdm_status_t (*ftdm_channel_sig_read_t)(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size); +typedef enum { + FTDM_ITERATOR_VARS = 1, + FTDM_ITERATOR_CHANS, +} ftdm_iterator_type_t; + +struct ftdm_iterator { + ftdm_iterator_type_t type; + unsigned int allocated:1; + union { + struct { + uint32_t index; + const ftdm_span_t *span; + } chaniter; + ftdm_hash_iterator_t *hashiter; + } pvt; +}; + #ifdef __cplusplus } #endif diff --git a/libs/freetdm/src/libteletone_generate.c b/libs/freetdm/src/libteletone_generate.c index 089268bc7b..7f37b7a258 100644 --- a/libs/freetdm/src/libteletone_generate.c +++ b/libs/freetdm/src/libteletone_generate.c @@ -267,7 +267,7 @@ TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone ts->samples * 2); } } - return ts->samples; + return ts->samples / ts->channels; } TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd) diff --git a/libs/libcodec2/.update b/libs/libcodec2/.update new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/libcodec2/AUTHORS b/libs/libcodec2/AUTHORS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/libcodec2/COPYING b/libs/libcodec2/COPYING new file mode 100644 index 0000000000..4362b49151 --- /dev/null +++ b/libs/libcodec2/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/libs/libcodec2/ChangeLog b/libs/libcodec2/ChangeLog new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/libcodec2/INSTALL b/libs/libcodec2/INSTALL new file mode 100644 index 0000000000..23e5f25d0e --- /dev/null +++ b/libs/libcodec2/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/libs/libcodec2/Makefile.am b/libs/libcodec2/Makefile.am new file mode 100644 index 0000000000..a1820f9162 --- /dev/null +++ b/libs/libcodec2/Makefile.am @@ -0,0 +1,98 @@ +AM_CFLAGS = -Isrc -Wall -lm +AUTOMAKE_OPTS = gnu +NAME = libcodec2 +AM_CPPFLAGS = $(AM_CFLAGS) + +EXTRA_DIST = pitch/hts1a.p \ +pitch/hts2a.p \ +octave/glottal.m \ +octave/lsp_pdf.m \ +octave/phase.m \ +octave/pl2.m \ +octave/plinterp.m \ +octave/plnlp.m \ +octave/plpitch.m \ +octave/postfilter.m \ +octave/load_raw.m \ +octave/phase2.m \ +octave/pitch_test.m \ +octave/plamp.m \ +octave/pl.m \ +octave/plphase.m \ +octave/png.m \ +octave/pulse.m \ +raw/b0067.raw \ +raw/forig_speex_8k.raw \ +raw/hts1.raw \ +raw/hts2.raw \ +raw/mmt1.raw \ +raw/morig_speex_8k.raw \ +raw/f2400.raw \ +raw/hts1a_g729a.raw \ +raw/hts2a_g729a.raw \ +raw/hts.raw \ +raw/mmt1_speex_8k.raw \ +raw/forig_g729a.raw \ +raw/hts1a_gsm13k.raw \ +raw/hts2a_gsm13k.raw \ +raw/m2400.raw \ +raw/morig_g729a.raw \ +raw/forig_gsm13k.raw \ +raw/hts1a.raw \ +raw/hts2a.raw \ +raw/mmt1_g729a.raw \ +raw/morig_gsm13k.raw \ +raw/forig.raw \ +raw/hts1a_speex_8k.raw \ +raw/hts2a_speex_8k.raw \ +raw/mmt1_gsm13k.raw \ +raw/morig.raw \ +script/menu.sh \ +script/playraw.sh \ +script/raw2wav.sh \ +script/wav2raw.sh \ +wav/f2400.wav \ +wav/hts1a_c2_v0.1.wav \ +wav/hts1a.wav \ +wav/hts2a_speex_8k.wav \ +wav/mmt1_speex_8k.wav \ +wav/morig.wav \ +wav/forig_speex_8k.wav \ +wav/hts1a_g729a.wav \ +wav/hts2a_c2_v0.1.wav \ +wav/hts2a.wav \ +wav/mmt1.wav \ +wav/forig.wav \ +wav/hts1a_speex_8k.wav \ +wav/hts2a_g729a.wav \ +wav/m2400.wav \ +wav/morig_speex_8k.wav \ +src/globals.c \ +doc/A_m.gif \ +doc/omega_0.gif \ +doc/phi_m.gif \ +doc/s_n.gif \ +doc/s_n.txt \ +unittest/lsp2.txt \ +unittest/lsp7.txt \ +unittest/lspd78.txt \ +unittest/lsp3.txt \ +unittest/lsp8.txt \ +unittest/lspd910.txt \ +unittest/lsp4.txt \ +unittest/lsp9.txt \ +unittest/lsp10.txt \ +unittest/lsp5.txt \ +unittest/lspd123.txt \ +unittest/lsp1.txt \ +unittest/lsp6.txt \ +unittest/lspd456.txt \ +src/codeall.sh \ +src/fq20.sh \ +src/listen1.sh \ +src/listen.sh \ +src/listensim.sh \ +src/sim.sh + + +SUBDIRS = src unittest diff --git a/libs/libcodec2/NEWS b/libs/libcodec2/NEWS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/libcodec2/README b/libs/libcodec2/README new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/libcodec2/configure.gnu b/libs/libcodec2/configure.gnu new file mode 100644 index 0000000000..c78238de46 --- /dev/null +++ b/libs/libcodec2/configure.gnu @@ -0,0 +1,4 @@ +#! /bin/sh +srcpath=$(dirname $0 2>/dev/null ) || srcpath="." +$srcpath/configure "$@" --disable-shared --with-pic + diff --git a/libs/libcodec2/configure.in b/libs/libcodec2/configure.in new file mode 100644 index 0000000000..378ef5f2b9 --- /dev/null +++ b/libs/libcodec2/configure.in @@ -0,0 +1,26 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.59]) +AC_INIT(libcodec2, 1.0, david@rowetel.com) +AM_INIT_AUTOMAKE(libcodec2,1.0) + +# Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL + +# Checks for libraries. +# FIXME: Replace `main' with a function in `-lm': +AC_CHECK_LIB([m], [main]) + +# Checks for header files. +AC_CHECK_HEADERS([stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([floor pow sqrt]) + +AC_CONFIG_FILES([Makefile src/Makefile unittest/Makefile]) +AC_OUTPUT diff --git a/libs/libcodec2/doc/A_m.gif b/libs/libcodec2/doc/A_m.gif new file mode 100644 index 0000000000..47b89bd6c9 Binary files /dev/null and b/libs/libcodec2/doc/A_m.gif differ diff --git a/libs/libcodec2/doc/omega_0.gif b/libs/libcodec2/doc/omega_0.gif new file mode 100644 index 0000000000..02877e09d7 Binary files /dev/null and b/libs/libcodec2/doc/omega_0.gif differ diff --git a/libs/libcodec2/doc/phi_m.gif b/libs/libcodec2/doc/phi_m.gif new file mode 100644 index 0000000000..3f2fd57e52 Binary files /dev/null and b/libs/libcodec2/doc/phi_m.gif differ diff --git a/libs/libcodec2/doc/s_n.gif b/libs/libcodec2/doc/s_n.gif new file mode 100644 index 0000000000..c739ab4de1 Binary files /dev/null and b/libs/libcodec2/doc/s_n.gif differ diff --git a/libs/libcodec2/doc/s_n.txt b/libs/libcodec2/doc/s_n.txt new file mode 100644 index 0000000000..fec16b3a31 --- /dev/null +++ b/libs/libcodec2/doc/s_n.txt @@ -0,0 +1 @@ +s(n)=A_1cos(\omega_0+\phi_1)+A_2cos(2\omega_0+\phi_2)+...+A_Lcos(L\omega_0+\phi_L) diff --git a/libs/libcodec2/octave/glottal.m b/libs/libcodec2/octave/glottal.m new file mode 100644 index 0000000000..2b823c37e3 --- /dev/null +++ b/libs/libcodec2/octave/glottal.m @@ -0,0 +1,25 @@ +% glottal.m +% David Rowe 12 Sep 2009 +% Matlab script to generate the phase spectra of a glottal pulse + +% lpc10 pulse from spandsp. When the file glottal.c was used as a part of the +% excitation phase component in phase.c, phase_synth_zero_order(), no difference +% in speech quality was apparent. So left out of code for now. + +sh=12 +kexc = [ 8, -16, 26, -48, 86, -162, 294, -502, 718, -728, 184 672, -610, -672, 184, 728, 718, 502, 294, 162, 86, 48, 26, 16, 8]; +kexc = shift(kexc,sh); +kexc = [kexc(1:sh) zeros(1,512-25) kexc(sh+1:25)]; +figure(1) +plot(kexc) +figure(2) +G = fft(kexc); +plot((1:256)*(4000/256),unwrap(angle(G(1:256)))) + +f=fopen("glottal.c","wt"); +fprintf(f,"float glottal[]={\n"); +for m=1:255 + fprintf(f," %f,\n",angle(G(m))); +endfor +fprintf(f," %f};\n",angle(G(256))); +fclose(f); diff --git a/libs/libcodec2/octave/load_raw.m b/libs/libcodec2/octave/load_raw.m new file mode 100644 index 0000000000..1f7868d42c --- /dev/null +++ b/libs/libcodec2/octave/load_raw.m @@ -0,0 +1,8 @@ +% load_raw.m +% David Rowe 7 Oct 2009 + +function s = load_raw(fn) + fs=fopen(fn,"rb"); + s = fread(fs,Inf,"short"); + plot(s) +endfunction diff --git a/libs/libcodec2/octave/lsp_pdf.m b/libs/libcodec2/octave/lsp_pdf.m new file mode 100644 index 0000000000..6617066e3d --- /dev/null +++ b/libs/libcodec2/octave/lsp_pdf.m @@ -0,0 +1,50 @@ +% lsp_pdf.m +% David Rowe 2 Oct 2009 +% Plots histograms (PDF estimates) of LSP training data + +function lsp_pdf(lsp) + [r,c] = size(lsp); + + % LSPs + + figure(3); + clf; + [x,y] = hist(lsp(:,1),100); + plot(y*4000/pi,x,";1;"); + hold on; + for i=2:c + [x,y] = hist(lsp(:,i),100); + legend = sprintf(";%d;",i); + plot(y*4000/pi,x,legend); + endfor + hold off; + grid; + + % LSP differences + + figure(4); + clf; + subplot(211) + [x,y] = hist(lsp(:,1),100); + plot(y,x,";1;"); + hold on; + for i=2:5 + [x,y] = hist(lsp(:,i) - lsp(:,i-1),100); + legend = sprintf(";%d;",i); + plot(y,x,legend); + endfor + hold off; + grid; + + subplot(212) + [x,y] = hist(lsp(:,6)-lsp(:,5),100); + plot(y,x,";6;"); + hold on; + for i=7:c + [x,y] = hist(lsp(:,i) - lsp(:,i-1),100); + legend = sprintf(";%d;",i); + plot(y,x,legend); + endfor + hold off; + grid; +endfunction diff --git a/libs/libcodec2/octave/phase.m b/libs/libcodec2/octave/phase.m new file mode 100644 index 0000000000..f973590345 --- /dev/null +++ b/libs/libcodec2/octave/phase.m @@ -0,0 +1,56 @@ +% phase.m +% David Rowe August 2009 +% experiments with phase for sinusoidal codecs + +function phase(samname, F0, png) + Wo=2*pi*F0/8000; + P=2*pi/Wo; + L = floor(pi/Wo); + Nsam = 16000; + N = 80; + F = Nsam/N; + A = 10000/L; + phi = zeros(1,L); + s = zeros(1,Nsam); + + for m=floor(L/2):L + phi_off(m) = -m*Wo*8; + end + + for f=1:F + phi(1) = phi(1) + Wo*N; + phi(1) = mod(phi(1),2*pi); + + for m=1:L + phi(m) = m*phi(1); + end + + x = zeros(1,N); + for m=1:L + x = x + A*cos(m*Wo*(0:(N-1)) + phi(m)); + endfor + s((f-1)*N+1:f*N) = x; + endfor + + figure(1); + clf; + plot(s(1:250)); + + fs=fopen(samname,"wb"); + fwrite(fs,s,"short"); + fclose(fs); + + if (nargin == 3) + % small image to fit blog + + __gnuplot_set__ terminal png size 450,300 + ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname); + eval(ss) + replot; + + % for some reason I need this to stop large plot getting wiped + __gnuplot_set__ output "/dev/null" + endif + +endfunction + diff --git a/libs/libcodec2/octave/phase2.m b/libs/libcodec2/octave/phase2.m new file mode 100644 index 0000000000..ea58dcbe11 --- /dev/null +++ b/libs/libcodec2/octave/phase2.m @@ -0,0 +1,50 @@ +% phase2.m +% David Rowe Sep 2009 +% experiments with phase for sinusoidal codecs, looking at phase +% of excitation with real Am samples from hts1 + +function phase2(samname, png) + N = 16000; + + f=45; + model = load("../src/hts1a_model.txt"); + phase = load("../src/hts1a_phase_phase.txt"); + Wo = model(f,1); + P=2*pi/Wo; + L = model(f,2); + A = model(f,3:(L+2)); + phi = phase(f,1:L); + phi = zeros(1,L); + for m=L/2:L + phi(m) = 2*pi*rand(1,1); + end + + s = zeros(1,N); + + for m=1:L + s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m)); + s = s + s_m; + endfor + + figure(1); + clf; + plot(s(1:250)); + + fs=fopen(samname,"wb"); + fwrite(fs,s,"short"); + fclose(fs); + + if (nargin == 2) + % small image to fit blog + + __gnuplot_set__ terminal png size 450,300 + ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname); + eval(ss) + replot; + + % for some reason I need this to stop large plot getting wiped + __gnuplot_set__ output "/dev/null" + endif + +endfunction + diff --git a/libs/libcodec2/octave/pitch_test.m b/libs/libcodec2/octave/pitch_test.m new file mode 100644 index 0000000000..3fe0d1ad66 --- /dev/null +++ b/libs/libcodec2/octave/pitch_test.m @@ -0,0 +1,39 @@ +% pitch_test.m +% David Rowe Sep 2009 +% Constructs a sequence to test the pitch estimator + +function pitch_test(samname) + M=320; + F=200; + + fs=fopen(samname,"wb"); + + f0 = 100; + for f=1:200 + Wo=2*pi*f0/8000; + P=2*pi/Wo; + L = floor(pi/Wo); + A = 10000/L; + phi = zeros(1,L); + s = zeros(1,M); + + for m=1:L + s = s + A*cos(m*Wo*(0:(M-1)) + phi(m)); + endfor + + figure(1); + clf; + plot(s); + + fwrite(fs,s,"short"); + + f0 = f0 + 5; + if (f0 > 400) + f0 = 100; + endif + endfor + + fclose(fs); + +endfunction + diff --git a/libs/libcodec2/octave/pl.m b/libs/libcodec2/octave/pl.m new file mode 100644 index 0000000000..49968961d4 --- /dev/null +++ b/libs/libcodec2/octave/pl.m @@ -0,0 +1,42 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 + +function pl(samname1, start_sam, end_sam, pngname) + + fs=fopen(samname1,"rb"); + s=fread(fs,Inf,"short"); + + st = 1; + en = length(s); + if (nargin >= 2) + st = start_sam; + endif + if (nargin >= 3) + en = end_sam; + endif + + figure(1); + clf; + plot(s(st:en)); + axis([1 en-st min(s) max(s)]); + + if (nargin == 4) + + % small image + + __gnuplot_set__ terminal png size 420,300 + ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname); + eval(ss) + replot; + + % larger image + + __gnuplot_set__ terminal png size 800,600 + ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname); + eval(ss) + replot; + + endif + +endfunction diff --git a/libs/libcodec2/octave/pl2.m b/libs/libcodec2/octave/pl2.m new file mode 100644 index 0000000000..6e6d37aab8 --- /dev/null +++ b/libs/libcodec2/octave/pl2.m @@ -0,0 +1,50 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 + +function pl2(samname1, samname2, start_sam, end_sam, pngname) + + fs1=fopen(samname1,"rb"); + s1=fread(fs1,Inf,"short"); + fs2=fopen(samname2,"rb"); + s2=fread(fs2,Inf,"short"); + + st = 1; + en = length(s1); + if (nargin >= 3) + st = start_sam; + endif + if (nargin >= 4) + en = end_sam; + endif + + figure(1); + clf; + subplot(211); + l1 = strcat("r;",samname1,";"); + plot(s1(st:en), l1); + axis([1 en-st min(s1(st:en)) max(s1(st:en))]); + subplot(212); + l2 = strcat("r;",samname2,";"); + plot(s2(st:en),l2); + axis([1 en-st min(s1(st:en)) max(s1(st:en))]); + + if (nargin == 5) + + % small image + + __gnuplot_set__ terminal png size 420,300 + s = sprintf("__gnuplot_set__ output \"%s.png\"", pngname); + eval(s) + replot; + + % larger image + + __gnuplot_set__ terminal png size 800,600 + s = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname); + eval(s) + replot; + + endif + +endfunction diff --git a/libs/libcodec2/octave/plamp.m b/libs/libcodec2/octave/plamp.m new file mode 100644 index 0000000000..892830f032 --- /dev/null +++ b/libs/libcodec2/octave/plamp.m @@ -0,0 +1,166 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 +% +% Plot ampltiude modelling information from dump files. + +function plamp(samname, f) + + sn_name = strcat(samname,"_sn.txt"); + Sn = load(sn_name); + + sw_name = strcat(samname,"_sw.txt"); + Sw = load(sw_name); + + sw__name = strcat(samname,"_sw_.txt"); + if (file_in_path(".",sw__name)) + Sw_ = load(sw__name); + endif + + model_name = strcat(samname,"_model.txt"); + model = load(model_name); + + modelq_name = strcat(samname,"_qmodel.txt"); + if (file_in_path(".",modelq_name)) + modelq = load(modelq_name); + endif + + pw_name = strcat(samname,"_pw.txt"); + if (file_in_path(".",pw_name)) + Pw = load(pw_name); + endif + + lsp_name = strcat(samname,"_lsp.txt"); + if (file_in_path(".",lsp_name)) + lsp = load(lsp_name); + endif + + phase_name = strcat(samname,"_phase.txt"); + if (file_in_path(".",phase_name)) + phase = load(phase_name); + endif + + phase_name_ = strcat(samname,"_phase_.txt"); + if (file_in_path(".",phase_name_)) + phase_ = load(phase_name_); + endif + + snr_name = strcat(samname,"_snr.txt"); + if (file_in_path(".",snr_name)) + snr = load(snr_name); + endif + + k = ' '; + do + figure(1); + clf; +% s = [ Sn(2*(f-2)-1,:) Sn(2*(f-2),:) ]; + s = [ Sn(2*f-1,:) Sn(2*f,:) ]; + plot(s); + axis([1 length(s) -20000 20000]); + + figure(2); + Wo = model(f,1); + L = model(f,2); + Am = model(f,3:(L+2)); + plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;r"); + axis([1 4000 -10 80]); + hold on; +% plot((0:255)*4000/256, Sw(f-2,:),";Sw;"); + plot((0:255)*4000/256, Sw(f,:),";Sw;"); + + if (file_in_path(".",modelq_name)) + Amq = modelq(f,3:(L+2)); + plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;g" ); + if (file_in_path(".",pw_name)) + plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;c"); + endif + signal = Am * Am'; + noise = (Am-Amq) * (Am-Amq)'; + snr1 = 10*log10(signal/noise); + Am_err_label = sprintf(";Am error SNR %4.2f dB;m",snr1); + plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am), Am_err_label); + endif + + if (file_in_path(".",snr_name)) + snr_label = sprintf(";phase SNR %4.2f dB;",snr(f)); + plot(1,1,snr_label); + endif + + % phase model - determine SNR and error spectrum for phase model 1 + + if (file_in_path(".",phase_name_)) + orig = Am.*exp(j*phase(f,1:L)); + synth = Am.*exp(j*phase_(f,1:L)); + signal = orig * orig'; + noise = (orig-synth) * (orig-synth)'; + snr_phase = 10*log10(signal/noise); + + phase_err_label = sprintf(";phase_err SNR %4.2f dB;",snr_phase); + plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label); + endif + + if (file_in_path(".",lsp_name)) + for l=1:10 + plot([lsp(f,l)*4000/pi lsp(f,l)*4000/pi], [60 80], 'r'); + endfor + endif + + hold off; + + if (file_in_path(".",phase_name)) + figure(3); + plot((1:L)*Wo*4000/pi, phase(f,1:L), ";phase;"); + axis; + if (file_in_path(".",phase_name_)) + hold on; + plot((1:L)*Wo*4000/pi, phase_(f,1:L), ";phase_;"); + hold off; + endif + figure(2); + endif + + % autocorrelation function to research voicing est + + %M = length(s); + %sw = s .* hanning(M)'; + %for k=0:159 + % R(k+1) = sw(1:320-k) * sw(1+k:320)'; + %endfor + %figure(4); + %R_label = sprintf(";R(k) %3.2f;",max(R(20:159))/R(1)); + %plot(R/R(1),R_label); + %grid + + % interactive menu + + printf("\rframe: %d menu: n-next b-back p-png q-quit ", f); + fflush(stdout); + k = kbhit(); + if (k == 'n') + f = f + 1; + endif + if (k == 'b') + f = f - 1; + endif + + % optional print to PNG + + if (k == 'p') + figure(1); + pngname = sprintf("%s_%d_sn.png",samname,f); + print(pngname, '-dpng', "-S500,500") + pngname = sprintf("%s_%d_sn_large.png",samname,f); + print(pngname, '-dpng', "-S800,600") + + figure(2); + pngname = sprintf("%s_%d_sw.png",samname,f); + print(pngname, '-dpng', "-S500,500") + pngname = sprintf("%s_%d_sw_large.png",samname,f); + print(pngname, '-dpng', "-S800,600") + endif + + until (k == 'q') + printf("\n"); + +endfunction diff --git a/libs/libcodec2/octave/plinterp.m b/libs/libcodec2/octave/plinterp.m new file mode 100644 index 0000000000..794a0853b2 --- /dev/null +++ b/libs/libcodec2/octave/plinterp.m @@ -0,0 +1,11 @@ +load ../unittest/tinterp_prev.txt; +load ../unittest/tinterp_interp.txt; +load ../unittest/tinterp_next.txt; + +clf; +plot(tinterp_prev(:,1), 20.0*log10(tinterp_prev(:,2)),";prev;") +hold on; +plot(tinterp_interp(:,1), 20.0*log10(tinterp_interp(:,2)),'g+-;interp;') +plot(tinterp_next(:,1), 20.0*log10(tinterp_next(:,2)),'ro-;next;') +hold off; +axis([0 pi 0 80]) diff --git a/libs/libcodec2/octave/plnlp.m b/libs/libcodec2/octave/plnlp.m new file mode 100644 index 0000000000..01b493113b --- /dev/null +++ b/libs/libcodec2/octave/plnlp.m @@ -0,0 +1,134 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 +% +% Plot NLP states from dump files. + +function plnlp(samname, f) + + sn_name = strcat(samname,"_sn.txt"); + Sn = load(sn_name); + + sw_name = strcat(samname,"_sw.txt"); + Sw = load(sw_name); + + fw_name = strcat(samname,"_fw.txt"); + if (file_in_path(".",fw_name)) + fw = load(fw_name); + endif + + e_name = strcat(samname,"_e.txt"); + if (file_in_path(".",e_name)) + e = load(e_name); + endif + + p_name = strcat(samname,".p"); + if (file_in_path(".",p_name)) + p = load(p_name); + endif + + sq_name = strcat(samname,"_sq.txt"); + if (file_in_path(".",sq_name)) + sq = load(sq_name); + endif + + dec_name = strcat(samname,"_dec.txt"); + if (file_in_path(".",dec_name)) + dec = load(dec_name); + endif + + do + figure(1); + clf; + s = [ Sn(2*f-1,:) Sn(2*f,:) ]; + plot(s, ";Sn;"); + grid + axis([1 length(s) -20000 20000]); + + figure(2); + plot((0:255)*4000/256, Sw(f,:),";Sw;"); + grid + axis([1 4000 -10 80]); + hold on; + + f0 = 8000/p(f); + Wo = 2*pi/p(f); + L = floor(pi/Wo); + f0_label = sprintf("b;P=%3.1f F0=%3.0f;",p(f),f0); + for m=1:L-1 + plot([ m*Wo*4000/pi m*Wo*4000/pi], [10 60], 'b'); + endfor + plot([ L*Wo*4000/pi L*Wo*4000/pi], [10 60], f0_label); + + hold off; + + if (file_in_path(".",fw_name)) + figure(3); + if (file_in_path(".",e_name)) + subplot(211); + endif + plot((0:255)*800/256, fw(f,:)/max(fw(f,:)), ";Fw;"); + axis([1 400 0 1]); + if (file_in_path(".",e_name)) + subplot(212); + e_concat = [ e(2*f-1,:) e(2*f,:) ]; + plot(e_concat(1:400)/max(e_concat(1:400)), "+;MBE E(f);"); + axis([1 400 0 1]); + endif + endif + + if (file_in_path(".",sq_name)) + figure(4); + sq_concat = [ sq(2*f-1,:) sq(2*f,:) ]; + axis + plot(sq_concat, ";sq;"); + endif + + if (file_in_path(".",dec_name)) + figure(5); + plot(dec(f,:), ";dec;"); + endif + + figure(2); + + % interactive menu + + printf("\rframe: %d menu: n-next b-back p-png q-quit ", f); + fflush(stdout); + k = kbhit(); + if (k == 'n') + f = f + 1; + endif + if (k == 'b') + f = f - 1; + endif + + % optional print to PNG + + if (k == 'p') + + pngname = sprintf("%s_%d",samname,f); + + % small image + + __gnuplot_set__ terminal png size 420,300 + ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname); + eval(ss) + replot; + + % larger image + + __gnuplot_set__ terminal png size 800,600 + ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname); + eval(ss) + replot; + + % for some reason I need this to stop large plot getting wiped + __gnuplot_set__ output "/dev/null" + + endif + + until (k == 'q') + printf("\n"); + +endfunction diff --git a/libs/libcodec2/octave/plphase.m b/libs/libcodec2/octave/plphase.m new file mode 100644 index 0000000000..9e61185676 --- /dev/null +++ b/libs/libcodec2/octave/plphase.m @@ -0,0 +1,198 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 +% +% Plot phase modelling information from dump files. + +function plphase(samname, f) + + sn_name = strcat(samname,"_sn.txt"); + Sn = load(sn_name); + + sw_name = strcat(samname,"_sw.txt"); + Sw = load(sw_name); + + model_name = strcat(samname,"_model.txt"); + model = load(model_name); + + sw__name = strcat(samname,"_sw_.txt"); + if (file_in_path(".",sw__name)) + Sw_ = load(sw__name); + endif + + pw_name = strcat(samname,"_pw.txt"); + if (file_in_path(".",pw_name)) + Pw = load(pw_name); + endif + + ak_name = strcat(samname,"_ak.txt"); + if (file_in_path(".",ak_name)) + ak = load(ak_name); + endif + + phase_name = strcat(samname,"_phase.txt"); + if (file_in_path(".",phase_name)) + phase = load(phase_name); + endif + + phase_name_ = strcat(samname,"_phase_.txt"); + if (file_in_path(".",phase_name_)) + phase_ = load(phase_name_); + endif + + snr_name = strcat(samname,"_snr.txt"); + if (file_in_path(".",snr_name)) + snr = load(snr_name); + endif + + sn_name_ = strcat(samname,".raw"); + if (file_in_path(".",sn_name_)) + fs_ = fopen(sn_name_,"rb"); + sn_ = fread(fs_,Inf,"short"); + endif + + k = ' '; + do + figure(1); + clf; + s = [ Sn(2*f-1,:) Sn(2*f,:) ]; + plot(s); + grid; + axis([1 length(s) -20000 20000]); + if (k == 'p') + pngname = sprintf("%s_%d_sn",samname,f); + png(pngname); + endif + + figure(2); + Wo = model(f,1); + L = model(f,2); + Am = model(f,3:(L+2)); + plot((1:L)*Wo*4000/pi, 20*log10(Am),"r;Am;"); + axis([1 4000 -10 80]); + hold on; + plot((0:255)*4000/256, Sw(f,:),";Sw;"); + grid; + + if (file_in_path(".",sw__name)) + plot((0:255)*4000/256, Sw_(f,:),"g;Sw_;"); + endif + + if (file_in_path(".",pw_name)) + plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;"); + endif + + if (file_in_path(".",snr_name)) + snr_label = sprintf(";phase SNR %4.2f dB;",snr(f)); + plot(1,1,snr_label); + endif + + % phase model - determine SNR and error spectrum for phase model 1 + + if (file_in_path(".",phase_name_)) + orig = Am.*exp(j*phase(f,1:L)); + synth = Am.*exp(j*phase_(f,1:L)); + signal = orig * orig'; + noise = (orig-synth) * (orig-synth)'; + snr_phase = 10*log10(signal/noise); + + phase_err_label = sprintf("g;phase_err SNR %4.2f dB;",snr_phase); + plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label); + endif + + hold off; + if (k == 'p') + pngname = sprintf("%s_%d_sw",samname,f); + png(pngname); + endif + + if (file_in_path(".",phase_name)) + figure(3); + plot((1:L)*Wo*4000/pi, phase(f,1:L)*180/pi, "-o;phase;"); + axis; + if (file_in_path(".", phase_name_)) + hold on; + plot((1:L)*Wo*4000/pi, phase_(f,1:L)*180/pi, "g;phase_;"); + grid + hold off; + endif + if (k == 'p') + pngname = sprintf("%s_%d_phase",samname,f); + png(pngname); + endif + endif + + % synthesised speech + + if (file_in_path(".",sn_name_)) + figure(4); + s_ = sn_((f-3)*80+1:(f+1)*80); + plot(s_); + axis([1 length(s_) -20000 20000]); + if (k == 'p') + pngname = sprintf("%s_%d_sn_",samname,f) + png(pngname); + endif + endif + + if (file_in_path(".",ak_name)) + figure(5); + axis; + akw = ak(f,:); + weight = 1.0 .^ (0:length(akw)-1); + akw = akw .* weight; + H = 1./fft(akw,8000); + subplot(211); + plot(20*log10(abs(H(1:4000))),";LPC mag spec;"); + grid; + subplot(212); + plot(angle(H(1:4000))*180/pi,";LPC phase spec;"); + grid; + if (k == 'p') + % stops multimode errors from gnuplot, I know not why... + figure(2); + figure(5); + + pngname = sprintf("%s_%d_lpc",samname,f); + png(pngname); + endif + endif + + + % autocorrelation function to research voicing est + + %M = length(s); + %sw = s .* hanning(M)'; + %for k=0:159 + % R(k+1) = sw(1:320-k) * sw(1+k:320)'; + %endfor + %figure(4); + %R_label = sprintf(";R(k) %3.2f;",max(R(20:159))/R(1)); + %plot(R/R(1),R_label); + %grid + + figure(2); + + % interactive menu + + printf("\rframe: %d menu: n-next b-back p-png q-quit ", f); + fflush(stdout); + k = kbhit(); + if (k == 'n') + f = f + 1; + endif + if (k == 'b') + f = f - 1; + endif + + % optional print to PNG + + if (k == 'p') + pngname = sprintf("%s_%d",samname,f); + png(pngname); + endif + + until (k == 'q') + printf("\n"); + +endfunction diff --git a/libs/libcodec2/octave/plpitch.m b/libs/libcodec2/octave/plpitch.m new file mode 100644 index 0000000000..69ad533890 --- /dev/null +++ b/libs/libcodec2/octave/plpitch.m @@ -0,0 +1,36 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 +% +% plpitch.m +% Plots two pitch tracks on top of each other, used for comparing pitch +% estimators + +function plpitch(pitch1_name, pitch2_name, start_fr, end_fr) + + pitch1 = load(pitch1_name); + pitch2 = load(pitch2_name); + + st = 1; + en = length(pitch1); + if (nargin >= 3) + st = start_fr; + endif + if (nargin >= 4) + en = end_fr; + endif + + figure(1); + clf; + l1 = strcat("r;",pitch1_name,";") + l1 + st + en + plot(pitch1(st:en), l1); + axis([1 en-st 20 160]); + l2 = strcat("g;",pitch2_name,";"); + hold on; + plot(pitch2(st:en),l2); + hold off; +endfunction + diff --git a/libs/libcodec2/octave/png.m b/libs/libcodec2/octave/png.m new file mode 100644 index 0000000000..09a79968c6 --- /dev/null +++ b/libs/libcodec2/octave/png.m @@ -0,0 +1,25 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 +% +% Replot current plot as a png, generates small and large versions + +function png(pngname) + % small image + + __gnuplot_set__ terminal png size 420,300 + ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname); + eval(ss) + replot; + + % larger image + + __gnuplot_set__ terminal png size 800,600 + ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname); + eval(ss) + replot; + + % for some reason I need this to stop large plot getting wiped + __gnuplot_set__ output "/dev/null" + +endfunction diff --git a/libs/libcodec2/octave/postfilter.m b/libs/libcodec2/octave/postfilter.m new file mode 100644 index 0000000000..84f7dfc773 --- /dev/null +++ b/libs/libcodec2/octave/postfilter.m @@ -0,0 +1,24 @@ +% Copyright David Rowe 2009 +% This program is distributed under the terms of the GNU General Public License +% Version 2 +% +% Plot postfilter doing its thing + +function postfilter(samname) + p = load(samname); + figure(1); + plot(p(:,1),";energy;"); + hold on; + plot(p(:,2),";bg_est;"); + hold off; + grid; + pngname=sprintf("%s_postfilter_1", samname); + png(pngname); + + figure(2); + plot(p(:,3),";% unvoiced;"); + grid; + pngname=sprintf("%s_postfilter_2", samname); + png(pngname); +endfunction + diff --git a/libs/libcodec2/octave/pulse.m b/libs/libcodec2/octave/pulse.m new file mode 100644 index 0000000000..223389e777 --- /dev/null +++ b/libs/libcodec2/octave/pulse.m @@ -0,0 +1,37 @@ +% pulse.m +% David Rowe August 2009 +% +% Experiments with human pulse perception for sinusoidal codecs + +function pulse(samname) + + A = 1000; + K = 16000; + N = 80; + frames = K/N; + s = zeros(1,K); + + for f=1:frames + % lets try placing np random pulses in every frame + + P = 20 + (160-20)*rand(1,1); + Wo = 2*pi/P; + L = floor(pi/Wo); + sf = zeros(1,N); + for m=1:L/2:L + pos = floor(rand(1,1)*N)+1; + %pos = 50; + for l=m:m+L/2-1 + sf = sf + A*cos(l*Wo*((f-1)*N+1:f*N) - pos*l*Wo); + endfor + endfor + s((f-1)*N+1:f*N) = sf; + endfor + + plot(s(1:250)); + + fs=fopen(samname,"wb"); + fwrite(fs,s,"short"); + fclose(fs); +endfunction + diff --git a/libs/libcodec2/pitch/hts1a.p b/libs/libcodec2/pitch/hts1a.p new file mode 100644 index 0000000000..c11b8e90fc --- /dev/null +++ b/libs/libcodec2/pitch/hts1a.p @@ -0,0 +1,298 @@ +111.627907 +97.959183 +97.959183 +97.959183 +87.272736 +78.048775 +112.280701 +120.000008 +61.538464 +68.817207 +84.210526 +90.140846 +90.140846 +90.140846 +101.587303 +80.000000 +72.727272 +95.522392 +90.140846 +90.140846 +101.587303 +90.140846 +85.333336 +86.486488 +91.428574 +91.428574 +91.428574 +91.428574 +91.428574 +90.140846 +86.486488 +86.486488 +85.333336 +85.333336 +85.333336 +81.012657 +74.418610 +71.111115 +71.111115 +71.111115 +71.111115 +68.085106 +68.085106 +67.368423 +67.368423 +70.329674 +70.329674 +70.329674 +71.111115 +74.418610 +74.418610 +75.294121 +79.012352 +85.333336 +96.969704 +111.627907 +111.627907 +120.000008 +111.627907 +104.347832 +104.347832 +97.959183 +104.347832 +104.347832 +104.347832 +104.347832 +104.347832 +104.347832 +104.347832 +104.347832 +97.959183 +97.959183 +112.280701 +112.280701 +96.969704 +96.969704 +96.969704 +110.344841 +104.347832 +97.959183 +97.959183 +104.347832 +97.959183 +104.347832 +120.000008 +104.347832 +120.000008 +120.000008 +97.959183 +83.116882 +75.294121 +71.910118 +71.910110 +71.910110 +71.910110 +75.294121 +76.190483 +80.000008 +80.000008 +84.210526 +85.333336 +90.140846 +101.587303 +108.474571 +104.347832 +120.000008 +120.000008 +104.347832 +104.347832 +71.111115 +88.888893 +75.294121 +111.627907 +120.000008 +120.000008 +97.959183 +111.627907 +111.627907 +111.627907 +97.959183 +92.307693 +92.307693 +92.307693 +92.307693 +120.000008 +111.627907 +111.627907 +86.486488 +85.333336 +85.333336 +90.140846 +95.522392 +101.587311 +101.587311 +104.918037 +104.347832 +104.347832 +111.627907 +120.000008 +97.959183 +104.347832 +111.627907 +88.888893 +80.000000 +81.012657 +85.333336 +85.333336 +86.486488 +91.428574 +90.140846 +91.428574 +96.969704 +96.969704 +95.522392 +95.522392 +95.522392 +96.969704 +96.969704 +98.461533 +104.918022 +97.959183 +97.959183 +97.959183 +104.347832 +120.000008 +120.000008 +92.307693 +92.307693 +77.108429 +79.012344 +75.294121 +75.294121 +76.190483 +76.190483 +80.000008 +81.012657 +85.333336 +85.333336 +85.333336 +85.333336 +85.333336 +90.140846 +90.140846 +91.428574 +96.969704 +98.461533 +120.000008 +120.000008 +104.347832 +97.959183 +97.959183 +104.918037 +120.000008 +120.000008 +120.000008 +104.347832 +92.307693 +72.727272 +72.727272 +76.190483 +84.210533 +88.888901 +120.000008 +104.347832 +120.000008 +120.000008 +111.627907 +92.307693 +97.959183 +97.959183 +111.627907 +120.000008 +120.000008 +97.959183 +97.959183 +104.347832 +104.347832 +104.347832 +111.627907 +120.000008 +97.959183 +104.347832 +97.959183 +97.959183 +84.210526 +94.117653 +96.969704 +110.344841 +120.000008 +97.959183 +97.959183 +104.347832 +97.959183 +104.347832 +97.959183 +97.959183 +111.627907 +120.000008 +92.307693 +92.307693 +98.461533 +98.461533 +104.918022 +111.627907 +111.627907 +92.307693 +97.959183 +92.307693 +92.307693 +92.307693 +92.307693 +92.307693 +57.657658 +90.140846 +90.140846 +95.522392 +101.587311 +101.587311 +108.474586 +111.627907 +97.959183 +111.627907 +120.000008 +92.307693 +74.418610 +74.418610 +74.418610 +74.418610 +76.190483 +72.727280 +76.190483 +76.190483 +69.565224 +66.666672 +54.700855 +56.637169 +56.637169 +71.910110 +90.140846 +90.140846 +72.727272 +72.727272 +72.727272 +72.727272 +55.172413 +57.142857 +55.172413 +90.140846 +95.522392 +101.587311 +101.587311 +71.910110 +74.418610 +46.376812 +40.000000 +95.522392 +0 +0 diff --git a/libs/libcodec2/pitch/hts2a.p b/libs/libcodec2/pitch/hts2a.p new file mode 100644 index 0000000000..20e2680487 --- /dev/null +++ b/libs/libcodec2/pitch/hts2a.p @@ -0,0 +1,300 @@ + 0.0000000e+000 + 9.2753623e+001 + 5.4237288e+001 + 8.5906040e+001 + 7.0329670e+001 + 5.5652174e+001 + 5.4237288e+001 + 5.4935622e+001 + 5.4700855e+001 + 7.5739645e+001 + 7.3563218e+001 + 1.2307692e+002 + 1.1428571e+002 + 7.3563218e+001 + 7.7108434e+001 + 1.8550725e+002 + 1.2673267e+002 + 1.0847458e+002 + 7.8527607e+001 + 8.8888889e+001 + 8.3116883e+001 + 8.1012658e+001 + 1.0756303e+002 + 1.3061224e+002 + 4.8301887e+001 + 4.7940075e+001 + 4.8120301e+001 + 4.9230769e+001 + 4.9420849e+001 + 4.6886447e+001 + 4.2953020e+001 + 3.9263804e+001 + 3.7869822e+001 + 3.5457064e+001 + 3.4224599e+001 + 3.3333333e+001 + 3.2820513e+001 + 3.2000000e+001 + 3.1295844e+001 + 2.9906542e+001 + 2.9493088e+001 + 2.9090909e+001 + 2.8699552e+001 + 2.8131868e+001 + 2.7826087e+001 + 2.7826087e+001 + 2.7826087e+001 + 2.8193833e+001 + 2.7467811e+001 + 2.6890756e+001 + 5.4468085e+001 + 5.4237288e+001 + 6.4974619e+001 + 1.0756303e+002 + 8.8888889e+001 + 1.0406504e+002 + 4.4599303e+001 + 5.4468085e+001 + 3.6260623e+001 + 3.6260623e+001 + 8.1012658e+001 + 7.0329670e+001 + 1.2929293e+002 + 9.9224806e+001 + 4.3097643e+001 + 4.4137931e+001 + 4.5714286e+001 + 4.7407407e+001 + 4.8301887e+001 + 4.9230769e+001 + 4.9420849e+001 + 5.0996016e+001 + 5.1405622e+001 + 5.1405622e+001 + 5.2244898e+001 + 5.2459016e+001 + 5.2459016e+001 + 5.2244898e+001 + 5.3333333e+001 + 5.2459016e+001 + 5.2244898e+001 + 5.1405622e+001 + 5.1405622e+001 + 5.1200000e+001 + 5.0996016e+001 + 5.0196078e+001 + 4.9230769e+001 + 4.9230769e+001 + 4.9230769e+001 + 4.9420849e+001 + 4.9230769e+001 + 4.9042146e+001 + 9.8461538e+001 + 1.0158730e+002 + 5.1821862e+001 + 9.0140845e+001 + 1.0491803e+002 + 1.4382022e+002 + 5.2459016e+001 + 5.2459016e+001 + 1.2929293e+002 + 1.6410256e+002 + 8.0000000e+001 + 7.3563218e+001 + 1.0158730e+002 + 9.9224806e+001 + 4.9042146e+001 + 4.9042146e+001 + 4.9042146e+001 + 5.9259259e+001 + 1.4382022e+002 + 7.2316384e+001 + 1.0847458e+002 + 1.1228070e+002 + 1.6202532e+002 + 8.1528662e+001 + 7.2727273e+001 + 1.8550725e+002 + 6.0093897e+001 + 1.0847458e+002 + 8.9510490e+001 + 7.1508380e+001 + 4.0125392e+001 + 4.0634921e+001 + 4.0634921e+001 + 4.0251572e+001 + 4.0506329e+001 + 4.3986254e+001 + 4.0506329e+001 + 9.8461538e+001 + 5.6140351e+001 + 6.5641026e+001 + 5.4237288e+001 + 1.1636364e+002 + 3.4316354e+001 + 3.4972678e+001 + 3.7758112e+001 + 4.0634921e+001 + 4.0506329e+001 + 4.1290323e+001 + 4.2524917e+001 + 4.3389831e+001 + 4.4599303e+001 + 4.4912281e+001 + 4.6545455e+001 + 4.7232472e+001 + 4.8301887e+001 + 4.9230769e+001 + 4.9420849e+001 + 5.0393701e+001 + 5.1405622e+001 + 5.3333333e+001 + 5.3112033e+001 + 1.1034483e+002 + 9.7709924e+001 + 1.4382022e+002 + 5.0996016e+001 + 5.1821862e+001 + 5.0996016e+001 + 5.2032520e+001 + 5.3112033e+001 + 5.3556485e+001 + 5.4468085e+001 + 5.5652174e+001 + 5.4700855e+001 + 5.4700855e+001 + 5.4935622e+001 + 5.4700855e+001 + 5.4700855e+001 + 5.4468085e+001 + 5.4468085e+001 + 5.4468085e+001 + 5.4468085e+001 + 5.3333333e+001 + 5.1405622e+001 + 5.0996016e+001 + 5.0000000e+001 + 4.8120301e+001 + 4.8669202e+001 + 4.7058824e+001 + 4.6376812e+001 + 4.5070423e+001 + 4.4912281e+001 + 4.4137931e+001 + 4.2809365e+001 + 4.2666667e+001 + 4.2105263e+001 + 4.1423948e+001 + 4.1290323e+001 + 4.1290323e+001 + 4.1290323e+001 + 4.0634921e+001 + 4.0634921e+001 + 4.0634921e+001 + 4.0634921e+001 + 4.0764331e+001 + 4.1423948e+001 + 4.2953020e+001 + 4.5551601e+001 + 1.7534247e+002 + 4.7232472e+001 + 1.3763441e+002 + 1.3061224e+002 + 4.5551601e+001 + 4.3686007e+001 + 4.8669202e+001 + 9.4117647e+001 + 8.1012658e+001 + 1.1228070e+002 + 1.3617021e+002 + 4.3097643e+001 + 4.3835616e+001 + 4.6376812e+001 + 4.6545455e+001 + 4.6043165e+001 + 4.8301887e+001 + 4.9042146e+001 + 4.9420849e+001 + 5.1200000e+001 + 5.1405622e+001 + 5.2244898e+001 + 1.2929293e+002 + 1.2929293e+002 + 1.5238095e+002 + 1.5238095e+002 + 1.3913043e+002 + 9.0140845e+001 + 1.0940171e+002 + 9.0140845e+001 + 1.2307692e+002 + 8.9510490e+001 + 6.9565217e+001 + 7.3142857e+001 + 1.1034483e+002 + 7.8048780e+001 + 7.2727273e+001 + 1.0078740e+002 + 1.0940171e+002 + 1.1743119e+002 + 8.7074830e+001 + 1.8550725e+002 + 6.5306122e+001 + 1.3617021e+002 + 5.2674897e+001 + 1.0940171e+002 + 1.5238095e+002 + 1.4065934e+002 + 1.0756303e+002 + 1.0406504e+002 + 5.0793651e+001 + 4.9420849e+001 + 4.4444444e+001 + 7.0329670e+001 + 7.2727273e+001 + 7.4418605e+001 + 1.1636364e+002 + 1.0406504e+002 + 1.2307692e+002 + 1.2549020e+002 + 1.7297297e+002 + 4.5878136e+001 + 4.9805447e+001 + 6.2745098e+001 + 9.2086331e+001 + 9.1428571e+001 + 5.7142857e+001 + 4.8484848e+001 + 4.1157556e+001 + 2.2857143e+001 + 3.0046948e+001 + 9.4814815e+001 + 5.7918552e+001 + 9.0140845e+001 + 7.4418605e+001 + 7.4418605e+001 + 5.4700855e+001 + 9.5522388e+001 + 7.4853801e+001 + 9.4117647e+001 + 9.5522388e+001 + 9.9224806e+001 + 8.1012658e+001 + 1.1851852e+002 + 6.8817204e+001 + 8.5906040e+001 + 6.7015707e+001 + 4.3537415e+001 + 6.5306122e+001 + 3.1295844e+001 + 7.5739645e+001 + 6.2135922e+001 + 9.9224806e+001 + 5.7657658e+001 + 5.2244898e+001 + 5.8447489e+001 + 0.0000000e+000 + 0.0000000e+000 + 0.0000000e+000 + 0.0000000e+000 + 0.0000000e+000 diff --git a/libs/libcodec2/raw/b0067.raw b/libs/libcodec2/raw/b0067.raw new file mode 100644 index 0000000000..3aea9cdaaa Binary files /dev/null and b/libs/libcodec2/raw/b0067.raw differ diff --git a/libs/libcodec2/raw/f2400.raw b/libs/libcodec2/raw/f2400.raw new file mode 100644 index 0000000000..5f4427f2fb Binary files /dev/null and b/libs/libcodec2/raw/f2400.raw differ diff --git a/libs/libcodec2/raw/forig.raw b/libs/libcodec2/raw/forig.raw new file mode 100644 index 0000000000..4ba294d788 Binary files /dev/null and b/libs/libcodec2/raw/forig.raw differ diff --git a/libs/libcodec2/raw/forig_g729a.raw b/libs/libcodec2/raw/forig_g729a.raw new file mode 100644 index 0000000000..fbca567b24 Binary files /dev/null and b/libs/libcodec2/raw/forig_g729a.raw differ diff --git a/libs/libcodec2/raw/forig_gsm13k.raw b/libs/libcodec2/raw/forig_gsm13k.raw new file mode 100644 index 0000000000..71cbe6f6de Binary files /dev/null and b/libs/libcodec2/raw/forig_gsm13k.raw differ diff --git a/libs/libcodec2/raw/forig_speex_8k.raw b/libs/libcodec2/raw/forig_speex_8k.raw new file mode 100644 index 0000000000..e95302ef59 Binary files /dev/null and b/libs/libcodec2/raw/forig_speex_8k.raw differ diff --git a/libs/libcodec2/raw/hts.raw b/libs/libcodec2/raw/hts.raw new file mode 100644 index 0000000000..79f869add1 Binary files /dev/null and b/libs/libcodec2/raw/hts.raw differ diff --git a/libs/libcodec2/raw/hts1.raw b/libs/libcodec2/raw/hts1.raw new file mode 100644 index 0000000000..3369387e09 Binary files /dev/null and b/libs/libcodec2/raw/hts1.raw differ diff --git a/libs/libcodec2/raw/hts1a.raw b/libs/libcodec2/raw/hts1a.raw new file mode 100644 index 0000000000..7332f936e4 Binary files /dev/null and b/libs/libcodec2/raw/hts1a.raw differ diff --git a/libs/libcodec2/raw/hts1a_g729a.raw b/libs/libcodec2/raw/hts1a_g729a.raw new file mode 100644 index 0000000000..130f1ddcb1 Binary files /dev/null and b/libs/libcodec2/raw/hts1a_g729a.raw differ diff --git a/libs/libcodec2/raw/hts1a_gsm13k.raw b/libs/libcodec2/raw/hts1a_gsm13k.raw new file mode 100644 index 0000000000..dd102f59c6 Binary files /dev/null and b/libs/libcodec2/raw/hts1a_gsm13k.raw differ diff --git a/libs/libcodec2/raw/hts1a_speex_8k.raw b/libs/libcodec2/raw/hts1a_speex_8k.raw new file mode 100644 index 0000000000..9289e1c923 Binary files /dev/null and b/libs/libcodec2/raw/hts1a_speex_8k.raw differ diff --git a/libs/libcodec2/raw/hts2.raw b/libs/libcodec2/raw/hts2.raw new file mode 100644 index 0000000000..0bb9df1028 Binary files /dev/null and b/libs/libcodec2/raw/hts2.raw differ diff --git a/libs/libcodec2/raw/hts2a.raw b/libs/libcodec2/raw/hts2a.raw new file mode 100644 index 0000000000..6d9cf17bb9 Binary files /dev/null and b/libs/libcodec2/raw/hts2a.raw differ diff --git a/libs/libcodec2/raw/hts2a_g729a.raw b/libs/libcodec2/raw/hts2a_g729a.raw new file mode 100644 index 0000000000..9199b0ad70 Binary files /dev/null and b/libs/libcodec2/raw/hts2a_g729a.raw differ diff --git a/libs/libcodec2/raw/hts2a_gsm13k.raw b/libs/libcodec2/raw/hts2a_gsm13k.raw new file mode 100644 index 0000000000..f0a58505d1 Binary files /dev/null and b/libs/libcodec2/raw/hts2a_gsm13k.raw differ diff --git a/libs/libcodec2/raw/hts2a_speex_8k.raw b/libs/libcodec2/raw/hts2a_speex_8k.raw new file mode 100644 index 0000000000..c421bb4e7d Binary files /dev/null and b/libs/libcodec2/raw/hts2a_speex_8k.raw differ diff --git a/libs/libcodec2/raw/m2400.raw b/libs/libcodec2/raw/m2400.raw new file mode 100644 index 0000000000..1c0956daba Binary files /dev/null and b/libs/libcodec2/raw/m2400.raw differ diff --git a/libs/libcodec2/raw/mmt1.raw b/libs/libcodec2/raw/mmt1.raw new file mode 100644 index 0000000000..40638a5a8e Binary files /dev/null and b/libs/libcodec2/raw/mmt1.raw differ diff --git a/libs/libcodec2/raw/mmt1_g729a.raw b/libs/libcodec2/raw/mmt1_g729a.raw new file mode 100644 index 0000000000..196716e04f Binary files /dev/null and b/libs/libcodec2/raw/mmt1_g729a.raw differ diff --git a/libs/libcodec2/raw/mmt1_gsm13k.raw b/libs/libcodec2/raw/mmt1_gsm13k.raw new file mode 100644 index 0000000000..a9965af376 Binary files /dev/null and b/libs/libcodec2/raw/mmt1_gsm13k.raw differ diff --git a/libs/libcodec2/raw/mmt1_speex_8k.raw b/libs/libcodec2/raw/mmt1_speex_8k.raw new file mode 100644 index 0000000000..769a49cde4 Binary files /dev/null and b/libs/libcodec2/raw/mmt1_speex_8k.raw differ diff --git a/libs/libcodec2/raw/morig.raw b/libs/libcodec2/raw/morig.raw new file mode 100644 index 0000000000..4af0e8f90f Binary files /dev/null and b/libs/libcodec2/raw/morig.raw differ diff --git a/libs/libcodec2/raw/morig_g729a.raw b/libs/libcodec2/raw/morig_g729a.raw new file mode 100644 index 0000000000..636ecfdc7f Binary files /dev/null and b/libs/libcodec2/raw/morig_g729a.raw differ diff --git a/libs/libcodec2/raw/morig_gsm13k.raw b/libs/libcodec2/raw/morig_gsm13k.raw new file mode 100644 index 0000000000..660368fece Binary files /dev/null and b/libs/libcodec2/raw/morig_gsm13k.raw differ diff --git a/libs/libcodec2/raw/morig_speex_8k.raw b/libs/libcodec2/raw/morig_speex_8k.raw new file mode 100644 index 0000000000..ab667a1ba2 Binary files /dev/null and b/libs/libcodec2/raw/morig_speex_8k.raw differ diff --git a/libs/libcodec2/script/menu.sh b/libs/libcodec2/script/menu.sh new file mode 100755 index 0000000000..11297df9b9 --- /dev/null +++ b/libs/libcodec2/script/menu.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# ./menu.sh +# +# David Rowe +# Created August 2009 +# +# Presents a menu of sound files, press 1 to play file1, 2 to play file2 etc +# +# The aim is to make comparing files with different processing easier than +# using up-arrow on the command line. Based on cdialog. +# +# usage: +# menu.sh file1.raw file2.raw ........ [-d playbackdevice] +# +# for example: +# +# ../script/menu.sh hts1a.raw hts1a_uq.raw +# +# or: +# +# ../script/menu.sh hts1a.raw hts1a_uq.raw -d /dev/dsp1 +# + +# Copyright (C) 2007 David Rowe +# +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +files=0 +items="Q-Quit\n" +while [ ! -z "$1" ] +do + case "$1" in + -d) dsp="${1} ${2}"; shift;; + *) files=`expr 1 + $files`; + new_file=$1; + file[$files]=$new_file; + items="${items} ${files}-${new_file}\n";; + esac + shift +done + +readchar=1 +echo -n -e "\r" $items"- " +while [ $readchar -ne 0 ] +do + echo -n -e "\r -" + stty cbreak # or stty raw + readchar=`dd if=/dev/tty bs=1 count=1 2>/dev/null` + stty -cbreak + if [ $readchar == 'q' ] ; then + readchar=0 + fi + if [ $readchar -ne 0 ] ; then + play -r 8000 -s -2 ${file[$readchar]} $dsp 2> /dev/null + fi +done +echo diff --git a/libs/libcodec2/script/playraw.sh b/libs/libcodec2/script/playraw.sh new file mode 100755 index 0000000000..683cbaa16d --- /dev/null +++ b/libs/libcodec2/script/playraw.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Plays a raw file +# usage: +# playraw file.raw +# playraw file.raw -d /dev/dsp1 (e.g. for USB headphones) +play -r 8000 -s -2 $1 $2 $3 diff --git a/libs/libcodec2/script/raw2wav.sh b/libs/libcodec2/script/raw2wav.sh new file mode 100755 index 0000000000..a05efb72f6 --- /dev/null +++ b/libs/libcodec2/script/raw2wav.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# Converts 16 bit signed short 8 kHz raw (headerless) files to wave +sox -r 8000 -s -2 $1 $2 diff --git a/libs/libcodec2/script/wav2raw.sh b/libs/libcodec2/script/wav2raw.sh new file mode 100755 index 0000000000..39c0f1aefd --- /dev/null +++ b/libs/libcodec2/script/wav2raw.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# Converts wave files to raw (headerless) files +sox $1 -t raw $2 diff --git a/libs/libcodec2/src/Makefile.am b/libs/libcodec2/src/Makefile.am new file mode 100644 index 0000000000..ce240785d9 --- /dev/null +++ b/libs/libcodec2/src/Makefile.am @@ -0,0 +1,53 @@ +AM_CFLAGS = -I../src -Wall -DFLOATING_POINT -DVAR_ARRAYS +AUTOMAKE_OPTS = gnu +NAME = libcodec2 +AM_CPPFLAGS = $(AM_CFLAGS) + +lib_LTLIBRARIES = libcodec2.la +libcodec2_la_SOURCES = dump.c \ +lpc.c \ +nlp.c \ +postfilter.c \ +sine.c \ +codec2.c \ +four1.c \ +interp.c \ +lsp.c \ +phase.c \ +quantise.c \ +pack.c \ +codebook.c + +libcodec2_la_CFLAGS = $(AM_CFLAGS) +libcodec2_la_LDFLAGS = $(LIBS) + +library_includedir = $(prefix) +library_include_HEADERS = codec2.h \ +defines.h \ +four1.h \ +interp.h \ +lsp.h \ +phase.h \ +quantise.h \ +comp.h \ +dump.h \ +globals.h \ +lpc.h \ +nlp.h \ +postfilter.h \ +sine.h \ +codebook.h + +bin_PROGRAMS = c2dec c2enc c2sim + +c2dec_SOURCES = c2dec.c +c2dec_LDADD = $(lib_LTLIBRARIES) +c2dec_LDFLAGS = $(LIBS) + +c2enc_SOURCES = c2enc.c +c2enc_LDADD = $(lib_LTLIBRARIES) +c2enc_LDFLAGS = $(LIBS) + +c2sim_SOURCES = c2sim.c +c2sim_LDADD = $(lib_LTLIBRARIES) +c2sim_LDFLAGS = $(LIBS) diff --git a/libs/libcodec2/src/c2dec.c b/libs/libcodec2/src/c2dec.c new file mode 100644 index 0000000000..3b876bcac0 --- /dev/null +++ b/libs/libcodec2/src/c2dec.c @@ -0,0 +1,80 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: c2dec.c + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Decodes a file of bits to a file of raw speech samples using codec2. Demo + program for codec2. + + NOTE: the bit file is not packed, 51 bits/frame actually consumes 51 + bytes/frame on disk. If you are using this for a real world + application you may want to pack the 51 bytes into 7 bytes. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "codec2.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +int main(int argc, char *argv[]) +{ + static const int bitsSize = ((CODEC2_BITS_PER_FRAME + 7) / 8); + void *codec2; + FILE *fin; + FILE *fout; + short buf[CODEC2_SAMPLES_PER_FRAME]; + unsigned char bits[bitsSize]; + + if (argc != 3) { + printf("usage: %s InputBitFile OutputRawSpeechFile\n", argv[0]); + exit(1); + } + + if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening input bit file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + if ( (fout = fopen(argv[2],"wb")) == NULL ) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); + } + + codec2 = codec2_create(); + + while(fread(bits, sizeof(char), bitsSize, fin) == bitsSize) { + codec2_decode(codec2, buf, bits); + fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout); + } + + codec2_destroy(codec2); + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/libs/libcodec2/src/c2enc.c b/libs/libcodec2/src/c2enc.c new file mode 100644 index 0000000000..8fd7c7778d --- /dev/null +++ b/libs/libcodec2/src/c2enc.c @@ -0,0 +1,82 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: c2enc.c + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Encodes a file of raw speech samples using codec2 and ouputs a file + of bits (each bit is stored in the LSB or each output byte). Demo + program for codec2. + + NOTE: the bit file is not packed, 51 bits/frame actually consumes 51 + bytes/frame on disk. If you are using this for a real world + application you may want to pack the 51 bytes into 7 bytes. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "codec2.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +int main(int argc, char *argv[]) +{ + static const int bitsSize = ((CODEC2_BITS_PER_FRAME + 7) / 8); + void *codec2; + FILE *fin; + FILE *fout; + short buf[CODEC2_SAMPLES_PER_FRAME]; + unsigned char bits[bitsSize]; + + if (argc != 3) { + printf("usage: %s InputRawspeechFile OutputBitFile\n", argv[0]); + exit(1); + } + + if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening input bit file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + if ( (fout = fopen(argv[2],"wb")) == NULL ) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); + } + + codec2 = codec2_create(); + + while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) == + CODEC2_SAMPLES_PER_FRAME) { + codec2_encode(codec2, bits, buf); + fwrite(bits, sizeof(char), bitsSize, fout); + } + + codec2_destroy(codec2); + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/libs/libcodec2/src/c2sim.c b/libs/libcodec2/src/c2sim.c new file mode 100644 index 0000000000..b9e5f0f78a --- /dev/null +++ b/libs/libcodec2/src/c2sim.c @@ -0,0 +1,408 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: c2sim.c + AUTHOR......: David Rowe + DATE CREATED: 20/8/2010 + + Codec2 simulation. Combines encoder and decoder and allows switching in + out various algorithms and quantisation steps. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include "defines.h" +#include "sine.h" +#include "nlp.h" +#include "dump.h" +#include "lpc.h" +#include "lsp.h" +#include "quantise.h" +#include "phase.h" +#include "postfilter.h" +#include "interp.h" + +/*---------------------------------------------------------------------------*\ + + switch_present() + + Searches the command line arguments for a "switch". If the switch is + found, returns the command line argument where it ws found, else returns + NULL. + +\*---------------------------------------------------------------------------*/ + +int switch_present(sw,argc,argv) +register char sw[]; /* switch in string form */ +register int argc; /* number of command line arguments */ +register char *argv[]; /* array of command line arguments in string form */ +{ + register int i; /* loop variable */ + + for(i=1; i<argc; i++) + if (!strcmp(sw,argv[i])) + return(i); + + return 0; +} + +void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]); + +/*---------------------------------------------------------------------------*\ + + MAIN + +\*---------------------------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + FILE *fout; /* output speech file */ + FILE *fin; /* input speech file */ + short buf[N]; /* input/output buffer */ + float Sn[M]; /* float input speech samples */ + COMP Sw[FFT_ENC]; /* DFT of Sn[] */ + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + MODEL model; + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn_[2*N]; /* synthesised speech */ + int i; /* loop variable */ + int frames; + float prev_Wo; + float pitch; + int voiced1; + + char out_file[MAX_STR]; + int arg; + float snr; + float sum_snr; + + int lpc_model, order; + int lsp, lsp_quantiser; + float ak[LPC_MAX]; + COMP Sw_[FFT_ENC]; + + int dump; + + int phase0; + float ex_phase[MAX_AMP+1]; + + int postfilt; + float bg_est; + + int hand_voicing; + FILE *fvoicing; + + MODEL prev_model, interp_model; + int decimate; + + void *nlp_states; + + for(i=0; i<M; i++) + Sn[i] = 1.0; + for(i=0; i<2*N; i++) + Sn_[i] = 0; + + prev_Wo = TWO_PI/P_MAX; + + prev_model.Wo = TWO_PI/P_MIN; + prev_model.L = floor(PI/prev_model.Wo); + for(i=1; i<=prev_model.L; i++) { + prev_model.A[i] = 0.0; + prev_model.phi[i] = 0.0; + } + for(i=1; i<=MAX_AMP; i++) { + ex_phase[i] = 0.0; + } + + nlp_states = nlp_create(); + + if (argc < 2) { + fprintf(stderr, "\nCodec2 - 2400 bit/s speech codec - Simulation Program\n" + "\thttp://rowetel.com/codec2.html\n\n" + "usage: %s InputFile [-o OutputFile]\n" + "\t[-o lpc Order]\n" + "\t[--lsp]\n" + "\t[--phase0]\n" + "\t[--postfilter]\n" + "\t[--hand_voicing]\n" + "\t[--dec]\n" + "\t[--dump DumpFilePrefix]\n", argv[0]); + exit(1); + } + + /* Interpret command line arguments -------------------------------------*/ + + /* Input file */ + + if ((fin = fopen(argv[1],"rb")) == NULL) { + fprintf(stderr, "Error opening input bit file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + /* Output file */ + + if ((arg = switch_present("-o",argc,argv))) { + if ((fout = fopen(argv[arg+1],"wb")) == NULL) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[arg+1], strerror(errno)); + exit(1); + } + strcpy(out_file,argv[arg+1]); + } + else + fout = NULL; + + lpc_model = 0; + if ((arg = switch_present("--lpc",argc,argv))) { + lpc_model = 1; + order = atoi(argv[arg+1]); + if ((order < 4) || (order > 20)) { + fprintf(stderr, "Error in lpc order: %d\n", order); + exit(1); + } + } + + dump = switch_present("--dump",argc,argv); + if (dump) + dump_on(argv[dump+1]); + + lsp = switch_present("--lsp",argc,argv); + lsp_quantiser = 0; + + phase0 = switch_present("--phase0",argc,argv); + if (phase0) { + ex_phase[0] = 0; + } + + hand_voicing = switch_present("--hand_voicing",argc,argv); + if (hand_voicing) { + fvoicing = fopen(argv[hand_voicing+1],"rt"); + assert(fvoicing != NULL); + } + + bg_est = 0.0; + postfilt = switch_present("--postfilter",argc,argv); + + decimate = switch_present("--dec",argc,argv); + + /* Initialise ------------------------------------------------------------*/ + + make_analysis_window(w,W); + make_synthesis_window(Pn); + quantise_init(); + + /* Main loop ------------------------------------------------------------*/ + + frames = 0; + sum_snr = 0; + while(fread(buf,sizeof(short),N,fin)) { + frames++; + + /* Read input speech */ + + for(i=0; i<M-N; i++) + Sn[i] = Sn[i+N]; + for(i=0; i<N; i++) + Sn[i+M-N] = buf[i]; + + /* Estimate pitch */ + + nlp(nlp_states,Sn,N,M,P_MIN,P_MAX,&pitch,Sw,&prev_Wo); + prev_Wo = TWO_PI/pitch; + model.Wo = TWO_PI/pitch; + + /* estimate model parameters */ + + dft_speech(Sw, Sn, w); + two_stage_pitch_refinement(&model, Sw); + estimate_amplitudes(&model, Sw, W); + dump_Sn(Sn); dump_Sw(Sw); dump_model(&model); + + /* optional zero-phase modelling */ + + if (phase0) { + float Wn[M]; /* windowed speech samples */ + float Rk[LPC_ORD+1]; /* autocorrelation coeffs */ + + dump_phase(&model.phi[0], model.L); + + /* find aks here, these are overwritten if LPC modelling is enabled */ + + for(i=0; i<M; i++) + Wn[i] = Sn[i]*w[i]; + autocorrelate(Wn,Rk,M,LPC_ORD); + levinson_durbin(Rk,ak,LPC_ORD); + + if (lpc_model) + assert(order == LPC_ORD); + + dump_ak(ak, LPC_ORD); + + /* determine voicing */ + + snr = est_voicing_mbe(&model, Sw, W, (FS/TWO_PI)*model.Wo, Sw_); + dump_Sw_(Sw_); + dump_snr(snr); + + /* just to make sure we are not cheating - kill all phases */ + + for(i=0; i<MAX_AMP; i++) + model.phi[i] = 0; + + if (hand_voicing) { + fscanf(fvoicing,"%d\n",&model.voiced); + } + } + + /* optional LPC model amplitudes */ + + if (lpc_model) { + int lpc_correction; + float e; + float lsps[LPC_ORD]; + int lsp_indexes[LPC_ORD]; + + e = speech_to_uq_lsps(lsps, ak, Sn, w, order); + lpc_correction = need_lpc_correction(&model, ak, e); + + if (lsp) { + encode_lsps(lsp_indexes, lsps, LPC_ORD); + /* + for(i=0; i<LPC_ORD; i++) + printf("lsps[%d] = %f lsp_indexes[%d] = %d\n", + i, lsps[i], i, lsp_indexes[i]); + printf("\n"); + */ + decode_lsps(lsps, lsp_indexes, LPC_ORD); + bw_expand_lsps(lsps, LPC_ORD); + lsp_to_lpc(lsps, ak, LPC_ORD); + } + + e = decode_energy(encode_energy(e)); + model.Wo = decode_Wo(encode_Wo(model.Wo)); + + aks_to_M2(ak, order, &model, e, &snr, 1); + apply_lpc_correction(&model, lpc_correction); + sum_snr += snr; + dump_quantised_model(&model); + } + + /* option decimation to 20ms rate, which enables interpolation + routine to synthesise in between frame */ + + if (decimate) { + if (!phase0) { + printf("needs --phase0 to resample phase for interpolated Wo\n"); + exit(0); + } + + /* odd frame - interpolate */ + + if (frames%2) { + + #ifdef TEST + model.voiced = 1; + prev_model.voiced = 1; + if (fabs(prev_model.Wo - model.Wo) < 0.1*model.Wo) { + interp_model.voiced = 1; + interpolate(&interp_model, &prev_model, &model); + for(i=0; i<=interp_model.L; i++) { + interp_model.phi[i] = phi1[i]; + } + printf("interp\n"); + } + else + interp_model = tmp_model; + #endif + + interp_model.voiced = voiced1; + interpolate(&interp_model, &prev_model, &model); + + if (phase0) + phase_synth_zero_order(&interp_model, ak, ex_phase); + if (postfilt) + postfilter(&interp_model, &bg_est); + synth_one_frame(buf, &interp_model, Sn_, Pn); + if (fout != NULL) fwrite(buf,sizeof(short),N,fout); + + if (phase0) + phase_synth_zero_order(&model, ak, ex_phase); + if (postfilt) + postfilter(&model, &bg_est); + synth_one_frame(buf, &model, Sn_, Pn); + if (fout != NULL) fwrite(buf,sizeof(short),N,fout); + + prev_model = model; + } + else { + voiced1 = model.voiced; + } + } + else { + if (phase0) + phase_synth_zero_order(&model, ak, ex_phase); + if (postfilt) + postfilter(&model, &bg_est); + synth_one_frame(buf, &model, Sn_, Pn); + if (fout != NULL) fwrite(buf,sizeof(short),N,fout); + } + } + + if (fout != NULL) + fclose(fout); + + if (lpc_model) + printf("SNR av = %5.2f dB\n", sum_snr/frames); + + if (dump) + dump_off(); + + if (hand_voicing) + fclose(fvoicing); + + nlp_destroy(nlp_states); + + return 0; +} + +void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]) +{ + int i; + + synthesise(Sn_, model, Pn, 1); + + for(i=0; i<N; i++) { + if (Sn_[i] > 32767.0) + buf[i] = 32767; + else if (Sn_[i] < -32767.0) + buf[i] = -32767; + else + buf[i] = Sn_[i]; + } + +} diff --git a/libs/libcodec2/src/codeall.sh b/libs/libcodec2/src/codeall.sh new file mode 100755 index 0000000000..6bdf825f49 --- /dev/null +++ b/libs/libcodec2/src/codeall.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# codeall.sh +# David Rowe 24 sep 2009 +# Code all samples using various processing steps +./code.sh hts1a +./code.sh hts2a +./code.sh mmt1 +./code.sh morig +./code.sh forig diff --git a/libs/libcodec2/src/codebook.c b/libs/libcodec2/src/codebook.c new file mode 100644 index 0000000000..74ed9ad5fe --- /dev/null +++ b/libs/libcodec2/src/codebook.c @@ -0,0 +1,162 @@ +float codebook_lsp1[] = { + 225, + 250, + 275, + 300, + 325, + 350, + 375, + 400, + 425, + 450, + 475, + 500, + 525, + 550, + 575, + 600,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp2[] = { + 325, + 350, + 375, + 400, + 425, + 450, + 475, + 500, + 525, + 550, + 575, + 600, + 625, + 650, + 675, + 700,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp3[] = { + 500, + 550, + 600, + 650, + 700, + 750, + 800, + 850, + 900, + 950, + 1000, + 1050, + 1100, + 1150, + 1200, + 1250,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp4[] = { + 700, + 800, + 900, + 1000, + 1100, + 1200, + 1300, + 1400, + 1500, + 1600, + 1700, + 1800, + 1900, + 2000, + 2100, + 2200,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp5[] = { + 950, + 1050, + 1150, + 1250, + 1350, + 1450, + 1550, + 1650, + 1750, + 1850, + 1950, + 2050, + 2150, + 2250, + 2350, + 2450,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp6[] = { + 1100, + 1200, + 1300, + 1400, + 1500, + 1600, + 1700, + 1800, + 1900, + 2000, + 2100, + 2200, + 2300, + 2400, + 2500, + 2600,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp7[] = { + 1500, + 1600, + 1700, + 1800, + 1900, + 2000, + 2100, + 2200, + 2300, + 2400, + 2500, + 2600, + 2700, + 2800, + 2900, + 3000,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp8[] = { + 2300, + 2400, + 2500, + 2600, + 2700, + 2800, + 2900, + 3000,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp9[] = { + 2500, + 2600, + 2700, + 2800, + 2900, + 3000, + 3100, + 3200,0,0,0,0,0,0,0,0,0,0 +}; + +float codebook_lsp10[] = { + 2900, + 3100, + 3300, + 3500,0,0,0,0,0,0,0,0,0,0 +}; + diff --git a/libs/libcodec2/src/codebook.h b/libs/libcodec2/src/codebook.h new file mode 100644 index 0000000000..d2e77a53f2 --- /dev/null +++ b/libs/libcodec2/src/codebook.h @@ -0,0 +1,15 @@ +#ifndef CODEBOOK_H +#define CODEBOOK_H + +extern float codebook_lsp1[]; +extern float codebook_lsp2[]; +extern float codebook_lsp3[]; +extern float codebook_lsp4[]; +extern float codebook_lsp5[]; +extern float codebook_lsp6[]; +extern float codebook_lsp7[]; +extern float codebook_lsp8[]; +extern float codebook_lsp9[]; +extern float codebook_lsp10[]; + +#endif diff --git a/libs/libcodec2/src/codec2.c b/libs/libcodec2/src/codec2.c new file mode 100644 index 0000000000..30142fec1d --- /dev/null +++ b/libs/libcodec2/src/codec2.c @@ -0,0 +1,337 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2.c + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Codec2 fully quantised encoder and decoder functions. If you want use + codec2, the codec2_xxx functions are for you. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "defines.h" +#include "sine.h" +#include "nlp.h" +#include "dump.h" +#include "lpc.h" +#include "quantise.h" +#include "phase.h" +#include "interp.h" +#include "postfilter.h" +#include "codec2.h" + +typedef struct { + float Sn[M]; /* input speech */ + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn_[2*N]; /* synthesised speech */ + float prev_Wo; /* previous frame's pitch estimate */ + float ex_phase; /* excitation model phase track */ + float bg_est; /* background noise estimate for post filter */ + MODEL prev_model; /* model parameters from 20ms ago */ + void *nlp; /* pitch predictor states */ +} CODEC2; + +/*---------------------------------------------------------------------------*\ + + FUNCTION HEADERS + +\*---------------------------------------------------------------------------*/ + +void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]); +void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model,float ak[]); + +/*---------------------------------------------------------------------------*\ + + FUNCTIONS + +\*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_create + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Create and initialise an instance of the codec. Returns a pointer + to the codec states or NULL on failure. One set of states is + sufficient for a full duuplex codec (i.e. an encoder and decoder). + You don't need separate states for encoders and decoders. See + c2enc.c and c2dec.c for examples. + +\*---------------------------------------------------------------------------*/ + +void *codec2_create() +{ + CODEC2 *c2; + int i,l; + + c2 = (CODEC2*)malloc(sizeof(CODEC2)); + if (c2 == NULL) + return NULL; + + for(i=0; i<M; i++) + c2->Sn[i] = 1.0; + for(i=0; i<2*N; i++) + c2->Sn_[i] = 0; + make_analysis_window(c2->w,c2->W); + make_synthesis_window(c2->Pn); + quantise_init(); + c2->prev_Wo = 0.0; + c2->bg_est = 0.0; + c2->ex_phase = 0.0; + + for(l=1; l<=MAX_AMP; l++) + c2->prev_model.A[l] = 0.0; + c2->prev_model.Wo = TWO_PI/P_MAX; + + c2->nlp = nlp_create(); + if (c2->nlp == NULL) { + free (c2); + return NULL; + } + + return (void*)c2; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_create + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Destroy an instance of the codec. + +\*---------------------------------------------------------------------------*/ + +void codec2_destroy(void *codec2_state) +{ + CODEC2 *c2; + + assert(codec2_state != NULL); + c2 = (CODEC2*)codec2_state; + nlp_destroy(c2->nlp); + free(codec2_state); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Encodes 160 speech samples (20ms of speech) into 51 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm twice. On the + first frame we just send the voicing bit. One the second frame we + send all model parameters. + + The bit allocation is: + + Parameter bits/frame + -------------------------------------- + Harmonic magnitudes (LSPs) 36 + Low frequency LPC correction 1 + Energy 5 + Wo (fundamental frequnecy) 7 + Voicing (10ms update) 2 + TOTAL 51 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode(void *codec2_state, unsigned char * bits, short speech[]) +{ + CODEC2 *c2; + MODEL model; + int voiced1, voiced2; + int lsp_indexes[LPC_ORD]; + int lpc_correction; + int energy_index; + int Wo_index; + int i; + unsigned int nbit = 0; + + assert(codec2_state != NULL); + c2 = (CODEC2*)codec2_state; + + /* first 10ms analysis frame - we just want voicing */ + + analyse_one_frame(c2, &model, speech); + voiced1 = model.voiced; + + /* second 10ms analysis frame */ + + analyse_one_frame(c2, &model, &speech[N]); + voiced2 = model.voiced; + + Wo_index = encode_Wo(model.Wo); + encode_amplitudes(lsp_indexes, + &lpc_correction, + &energy_index, + &model, + c2->Sn, + c2->w); + memset(bits, '\0', ((CODEC2_BITS_PER_FRAME + 7) / 8)); + pack(bits, &nbit, Wo_index, WO_BITS); + for(i=0; i<LPC_ORD; i++) { + pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); + } + pack(bits, &nbit, lpc_correction, 1); + pack(bits, &nbit, energy_index, E_BITS); + pack(bits, &nbit, voiced1, 1); + pack(bits, &nbit, voiced2, 1); + + assert(nbit == CODEC2_BITS_PER_FRAME); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Decodes frames of 51 bits into 160 samples (20ms) of speech. + +\*---------------------------------------------------------------------------*/ + +void codec2_decode(void *codec2_state, short speech[], + const unsigned char * bits) +{ + CODEC2 *c2; + MODEL model; + int voiced1, voiced2; + int lsp_indexes[LPC_ORD]; + int lpc_correction; + int energy_index; + int Wo_index; + float ak[LPC_ORD+1]; + int i; + unsigned int nbit = 0; + MODEL model_interp; + + assert(codec2_state != NULL); + c2 = (CODEC2*)codec2_state; + + Wo_index = unpack(bits, &nbit, WO_BITS); + for(i=0; i<LPC_ORD; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + lpc_correction = unpack(bits, &nbit, 1); + energy_index = unpack(bits, &nbit, E_BITS); + voiced1 = unpack(bits, &nbit, 1); + voiced2 = unpack(bits, &nbit, 1); + assert(nbit == CODEC2_BITS_PER_FRAME); + + model.Wo = decode_Wo(Wo_index); + model.L = PI/model.Wo; + decode_amplitudes(&model, + ak, + lsp_indexes, + lpc_correction, + energy_index); + + model.voiced = voiced2; + model_interp.voiced = voiced1; + interpolate(&model_interp, &c2->prev_model, &model); + + synthesise_one_frame(c2, speech, &model_interp, ak); + synthesise_one_frame(c2, &speech[N], &model, ak); + + memcpy(&c2->prev_model, &model, sizeof(MODEL)); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: synthesise_one_frame() + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Synthesise 80 speech samples (10ms) from model parameters. + +\*---------------------------------------------------------------------------*/ + +void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[]) +{ + int i; + + phase_synth_zero_order(model, ak, &c2->ex_phase); + postfilter(model, &c2->bg_est); + synthesise(c2->Sn_, model, c2->Pn, 1); + + for(i=0; i<N; i++) { + if (c2->Sn_[i] > 32767.0) + speech[i] = 32767; + else if (c2->Sn_[i] < -32767.0) + speech[i] = -32767; + else + speech[i] = c2->Sn_[i]; + } + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: analyse_one_frame() + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Extract sinusoidal model parameters from 80 speech samples (10ms of + speech). + +\*---------------------------------------------------------------------------*/ + +void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]) +{ + COMP Sw[FFT_ENC]; + COMP Sw_[FFT_ENC]; + float pitch; + int i; + + /* Read input speech */ + + for(i=0; i<M-N; i++) + c2->Sn[i] = c2->Sn[i+N]; + for(i=0; i<N; i++) + c2->Sn[i+M-N] = speech[i]; + dft_speech(Sw, c2->Sn, c2->w); + + /* Estimate pitch */ + + nlp(c2->nlp,c2->Sn,N,M,P_MIN,P_MAX,&pitch,Sw,&c2->prev_Wo); + c2->prev_Wo = TWO_PI/pitch; + model->Wo = TWO_PI/pitch; + model->L = PI/model->Wo; + + /* estimate model parameters */ + + dft_speech(Sw, c2->Sn, c2->w); + two_stage_pitch_refinement(model, Sw); + estimate_amplitudes(model, Sw, c2->W); + est_voicing_mbe(model, Sw, c2->W, (FS/TWO_PI)*model->Wo, Sw_); +} diff --git a/libs/libcodec2/src/codec2.h b/libs/libcodec2/src/codec2.h new file mode 100644 index 0000000000..7a1d1450a5 --- /dev/null +++ b/libs/libcodec2/src/codec2.h @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2.h + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Codec2 fully quantised encoder and decoder functions. If you want use + codec2, these are the functions you need to call. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __CODEC2__ +#define __CODEC2__ +#include "codebook.h" + +#define CODEC2_SAMPLES_PER_FRAME 160 +#define CODEC2_BITS_PER_FRAME 51 + +void *codec2_create(); +void codec2_destroy(void *codec2_state); +void codec2_encode(void *codec2_state, unsigned char * bits, short speech_in[]); +void codec2_decode(void *codec2_state, short speech_out[], + const unsigned char * bits); + +#endif diff --git a/libs/libcodec2/src/comp.h b/libs/libcodec2/src/comp.h new file mode 100644 index 0000000000..bca01b5d2f --- /dev/null +++ b/libs/libcodec2/src/comp.h @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: comp.h + AUTHOR......: David Rowe + DATE CREATED: 24/08/09 + + Complex number definition. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __COMP__ +#define __COMP__ + +/* Complex number */ + +typedef struct { + float real; + float imag; +} COMP; + +#endif diff --git a/libs/libcodec2/src/defines.h b/libs/libcodec2/src/defines.h new file mode 100644 index 0000000000..ef4899f70a --- /dev/null +++ b/libs/libcodec2/src/defines.h @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: defines.h + AUTHOR......: David Rowe + DATE CREATED: 23/4/93 + + Defines and structures used throughout the codec. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __DEFINES__ +#define __DEFINES__ + +/*---------------------------------------------------------------------------*\ + + DEFINES + +\*---------------------------------------------------------------------------*/ + +/* General defines */ + +#define N 80 /* number of samples per frame */ +#define MAX_AMP 80 /* maximum number of harmonics */ +#define PI 3.141592654 /* mathematical constant */ +#define TWO_PI 6.283185307 /* mathematical constant */ +#define FS 8000 /* sample rate in Hz */ +#define MAX_STR 256 /* maximum string size */ + +#define NW 279 /* analysis window size */ +#define FFT_ENC 512 /* size of FFT used for encoder */ +#define FFT_DEC 512 /* size of FFT used in decoder */ +#define TW 40 /* Trapezoidal synthesis window overlap */ +#define V_THRESH 4.0 /* voicing threshold in dB */ +#define LPC_MAX 20 /* maximum LPC order */ +#define LPC_ORD 10 /* phase modelling LPC order */ + +/* Pitch estimation defines */ + +#define M 320 /* pitch analysis frame size */ +#define P_MIN 20 /* minimum pitch */ +#define P_MAX 160 /* maximum pitch */ + +/*---------------------------------------------------------------------------*\ + + TYPEDEFS + +\*---------------------------------------------------------------------------*/ + +/* Complex number */ + +typedef struct { + float real; + float imag; +} COMP; + +/* Structure to hold model parameters for one frame */ + +typedef struct { + float Wo; /* fundamental frequency estimate in radians */ + int L; /* number of harmonics */ + float A[MAX_AMP]; /* amplitiude of each harmonic */ + float phi[MAX_AMP]; /* phase of each harmonic */ + int voiced; /* non-zero if this frame is voiced */ +} MODEL; + +#endif diff --git a/libs/libcodec2/src/dump.c b/libs/libcodec2/src/dump.c new file mode 100644 index 0000000000..2d18744483 --- /dev/null +++ b/libs/libcodec2/src/dump.c @@ -0,0 +1,402 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: dump.c + AUTHOR......: David Rowe + DATE CREATED: 25/8/09 + + Routines to dump data to text files for Octave analysis. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "defines.h" +#include "dump.h" +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +static int dumpon = 0; + +static FILE *fsn = NULL; +static FILE *fsw = NULL; +static FILE *fsw_ = NULL; +static FILE *fmodel = NULL; +static FILE *fqmodel = NULL; +static FILE *fpw = NULL; +static FILE *flsp = NULL; +static FILE *fphase = NULL; +static FILE *fphase_ = NULL; +static FILE *ffw = NULL; +static FILE *fe = NULL; +static FILE *fsq = NULL; +static FILE *fdec = NULL; +static FILE *fsnr = NULL; +static FILE *fak = NULL; +static FILE *fbg = NULL; +static FILE *fE = NULL; + +static char prefix[MAX_STR]; + +void dump_on(char p[]) { + dumpon = 1; + strcpy(prefix, p); +} + +void dump_off(){ + if (fsn != NULL) + fclose(fsn); + if (fsw != NULL) + fclose(fsw); + if (fsw_ != NULL) + fclose(fsw_); + if (fmodel != NULL) + fclose(fmodel); + if (fqmodel != NULL) + fclose(fqmodel); + if (fpw != NULL) + fclose(fpw); + if (flsp != NULL) + fclose(flsp); + if (fphase != NULL) + fclose(fphase); + if (fphase_ != NULL) + fclose(fphase_); + if (ffw != NULL) + fclose(ffw); + if (fe != NULL) + fclose(fe); + if (fsq != NULL) + fclose(fsq); + if (fdec != NULL) + fclose(fdec); + if (fsnr != NULL) + fclose(fsnr); + if (fak != NULL) + fclose(fak); + if (fbg != NULL) + fclose(fbg); + if (fE != NULL) + fclose(fE); +} + +void dump_Sn(float Sn[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsn == NULL) { + sprintf(s,"%s_sn.txt", prefix); + fsn = fopen(s, "wt"); + assert(fsn != NULL); + } + + /* split across two lines to avoid max line length problems */ + /* reconstruct in Octave */ + + for(i=0; i<M/2; i++) + fprintf(fsn,"%f\t",Sn[i]); + fprintf(fsn,"\n"); + for(i=M/2; i<M; i++) + fprintf(fsn,"%f\t",Sn[i]); + fprintf(fsn,"\n"); +} + +void dump_Sw(COMP Sw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsw == NULL) { + sprintf(s,"%s_sw.txt", prefix); + fsw = fopen(s, "wt"); + assert(fsw != NULL); + } + + for(i=0; i<FFT_ENC/2; i++) + fprintf(fsw,"%f\t", + 10.0*log10(Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag)); + fprintf(fsw,"\n"); +} + +void dump_Sw_(COMP Sw_[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsw_ == NULL) { + sprintf(s,"%s_sw_.txt", prefix); + fsw_ = fopen(s, "wt"); + assert(fsw_ != NULL); + } + + for(i=0; i<FFT_ENC/2; i++) + fprintf(fsw_,"%f\t", + 10.0*log10(Sw_[i].real*Sw_[i].real + Sw_[i].imag*Sw_[i].imag)); + fprintf(fsw_,"\n"); +} + +void dump_model(MODEL *model) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fmodel == NULL) { + sprintf(s,"%s_model.txt", prefix); + fmodel = fopen(s, "wt"); + assert(fmodel != NULL); + } + + fprintf(fmodel,"%f\t%d\t", model->Wo, model->L); + for(l=1; l<=model->L; l++) + fprintf(fmodel,"%f\t",model->A[l]); + for(l=model->L+1; l<MAX_AMP; l++) + fprintf(fmodel,"0.0\t"); + fprintf(fmodel,"%d\t",model->voiced); + fprintf(fmodel,"\n"); +} + +void dump_quantised_model(MODEL *model) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fqmodel == NULL) { + sprintf(s,"%s_qmodel.txt", prefix); + fqmodel = fopen(s, "wt"); + assert(fqmodel != NULL); + } + + fprintf(fqmodel,"%f\t%d\t", model->Wo, model->L); + for(l=1; l<=model->L; l++) + fprintf(fqmodel,"%f\t",model->A[l]); + for(l=model->L+1; l<MAX_AMP; l++) + fprintf(fqmodel,"0.0\t"); + fprintf(fqmodel,"\n"); +} + +void dump_phase(float phase[], int L) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fphase == NULL) { + sprintf(s,"%s_phase.txt", prefix); + fphase = fopen(s, "wt"); + assert(fphase != NULL); + } + + for(l=1; l<=L; l++) + fprintf(fphase,"%f\t",phase[l]); + for(l=L+1; l<MAX_AMP; l++) + fprintf(fphase,"%f\t",0.0); + fprintf(fphase,"\n"); +} + +void dump_phase_(float phase_[], int L) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fphase_ == NULL) { + sprintf(s,"%s_phase_.txt", prefix); + fphase_ = fopen(s, "wt"); + assert(fphase_ != NULL); + } + + for(l=1; l<=L; l++) + fprintf(fphase_,"%f\t",phase_[l]); + for(l=L+1; l<MAX_AMP; l++) + fprintf(fphase_,"%f\t",0.0); + fprintf(fphase_,"\n"); +} + +void dump_snr(float snr) { + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsnr == NULL) { + sprintf(s,"%s_snr.txt", prefix); + fsnr = fopen(s, "wt"); + assert(fsnr != NULL); + } + + fprintf(fsnr,"%f\n",snr); +} + +void dump_Pw(COMP Pw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fpw == NULL) { + sprintf(s,"%s_pw.txt", prefix); + fpw = fopen(s, "wt"); + assert(fpw != NULL); + } + + for(i=0; i<FFT_DEC/2; i++) + fprintf(fpw,"%f\t",Pw[i].real); + fprintf(fpw,"\n"); +} + +void dump_lsp(float lsp[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (flsp == NULL) { + sprintf(s,"%s_lsp.txt", prefix); + flsp = fopen(s, "wt"); + assert(flsp != NULL); + } + + for(i=0; i<10; i++) + fprintf(flsp,"%f\t",lsp[i]); + fprintf(flsp,"\n"); +} + +void dump_ak(float ak[], int order) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fak == NULL) { + sprintf(s,"%s_ak.txt", prefix); + fak = fopen(s, "wt"); + assert(fak != NULL); + } + + for(i=0; i<=order; i++) + fprintf(fak,"%f\t",ak[i]); + fprintf(fak,"\n"); +} + +void dump_Fw(COMP Fw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (ffw == NULL) { + sprintf(s,"%s_fw.txt", prefix); + ffw = fopen(s, "wt"); + assert(ffw != NULL); + } + + for(i=0; i<256; i++) + fprintf(ffw,"%f\t",Fw[i].real); + fprintf(ffw,"\n"); +} + +void dump_e(float e_hz[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fe == NULL) { + sprintf(s,"%s_e.txt", prefix); + fe = fopen(s, "wt"); + assert(fe != NULL); + } + + for(i=0; i<500/2; i++) + fprintf(fe,"%f\t",e_hz[i]); + fprintf(fe,"\n"); + for(i=500/2; i<500; i++) + fprintf(fe,"%f\t",e_hz[i]); + fprintf(fe,"\n"); +} + +void dump_sq(float sq[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsq == NULL) { + sprintf(s,"%s_sq.txt", prefix); + fsq = fopen(s, "wt"); + assert(fsq != NULL); + } + + for(i=0; i<M/2; i++) + fprintf(fsq,"%f\t",sq[i]); + fprintf(fsq,"\n"); + for(i=M/2; i<M; i++) + fprintf(fsq,"%f\t",sq[i]); + fprintf(fsq,"\n"); +} + +void dump_dec(COMP Fw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fdec == NULL) { + sprintf(s,"%s_dec.txt", prefix); + fdec = fopen(s, "wt"); + assert(fdec != NULL); + } + + for(i=0; i<320/5; i++) + fprintf(fdec,"%f\t",Fw[i].real); + fprintf(fdec,"\n"); +} + +void dump_bg(float e, float bg_est, float percent_uv) { + char s[MAX_STR]; + + if (!dumpon) return; + + if (fbg == NULL) { + sprintf(s,"%s_bg.txt", prefix); + fbg = fopen(s, "wt"); + assert(fbg != NULL); + } + + fprintf(fbg,"%f\t%f\t%f\n", e, bg_est, percent_uv); +} + +void dump_E(float E) { + char s[MAX_STR]; + + if (!dumpon) return; + + if (fE == NULL) { + sprintf(s,"%s_E.txt", prefix); + fE = fopen(s, "wt"); + assert(fE != NULL); + } + + fprintf(fE,"%f\n", 10.0*log10(E)); +} diff --git a/libs/libcodec2/src/dump.h b/libs/libcodec2/src/dump.h new file mode 100644 index 0000000000..8f402251f8 --- /dev/null +++ b/libs/libcodec2/src/dump.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: dump.h + AUTHOR......: David Rowe + DATE CREATED: 25/8/09 + + Routines to dump data to text files for Octave analysis. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __DUMP__ +#define __DUMP__ + +void dump_on(char filename_prefix[]); +void dump_off(); + +void dump_Sn(float Sn[]); +void dump_Sw(COMP Sw[]); +void dump_Sw_(COMP Sw_[]); + +/* amplitude modelling */ + +void dump_model(MODEL *m); +void dump_quantised_model(MODEL *m); +void dump_Pw(COMP Pw[]); +void dump_lsp(float lsp[]); +void dump_ak(float ak[], int order); +void dump_E(float E); + +/* phase modelling */ + +void dump_snr(float snr); +void dump_phase(float phase[], int L); +void dump_phase_(float phase[], int L); + +/* NLP states */ + +void dump_sq(float sq[]); +void dump_dec(COMP Fw[]); +void dump_Fw(COMP Fw[]); +void dump_e(float e_hz[]); + +/* post filter */ + +void dump_bg(float e, float bg_est, float percent_uv); + +#endif diff --git a/libs/libcodec2/src/four1.c b/libs/libcodec2/src/four1.c new file mode 100644 index 0000000000..1c1ede597c --- /dev/null +++ b/libs/libcodec2/src/four1.c @@ -0,0 +1,64 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: four1.c + AUTHOR......: David Rowe + DATE CREATED: 20/2/95 + + Numerical Recipies in C FFT function. I have a nasty licence so please + replace me. + +\*---------------------------------------------------------------------------*/ + +#include <math.h> + +#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr + +void four1(data,nn,isign) +float data[]; +int nn,isign; +{ + int n,mmax,m,j,istep,i; + double wtemp,wr,wpr,wpi,wi,theta; + float tempr,tempi; + + n=nn << 1; + j=1; + for (i=1;i<n;i+=2) { + if (j > i) { + SWAP(data[j],data[i]); + SWAP(data[j+1],data[i+1]); + } + m=n >> 1; + while (m >= 2 && j > m) { + j -= m; + m >>= 1; + } + j += m; + } + mmax=2; + while (n > mmax) { + istep=2*mmax; + theta=6.28318530717959/(isign*mmax); + wtemp=sin(0.5*theta); + wpr = -2.0*wtemp*wtemp; + wpi=sin(theta); + wr=1.0; + wi=0.0; + for (m=1;m<mmax;m+=2) { + for (i=m;i<=n;i+=istep) { + j=i+mmax; + tempr=wr*data[j]-wi*data[j+1]; + tempi=wr*data[j+1]+wi*data[j]; + data[j]=data[i]-tempr; + data[j+1]=data[i+1]-tempi; + data[i] += tempr; + data[i+1] += tempi; + } + wr=(wtemp=wr)*wpr-wi*wpi+wr; + wi=wi*wpr+wtemp*wpi+wi; + } + mmax=istep; + } +} + +#undef SWAP diff --git a/libs/libcodec2/src/four1.h b/libs/libcodec2/src/four1.h new file mode 100644 index 0000000000..51d1e7fcef --- /dev/null +++ b/libs/libcodec2/src/four1.h @@ -0,0 +1,18 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: four1.h + AUTHOR......: David Rowe + DATE CREATED: 20/2/95 + + Numerical Recipies in C FFT function. I have a nasty licence so please + replace me. + +\*---------------------------------------------------------------------------*/ + +#ifndef __FOUR1__ +#define __FOUR1__ + +void four1(float x[], int n, int isign); + +#endif /* __FOUR1__ */ + diff --git a/libs/libcodec2/src/fq20.sh b/libs/libcodec2/src/fq20.sh new file mode 100755 index 0000000000..b83784b437 --- /dev/null +++ b/libs/libcodec2/src/fq20.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# fq20.shsh +# David Rowe 27 July 2010 +# +# Decode a file with fully quantised codec at 20ms frame rate + +../src/sinedec ../raw/$1.raw $1.mdl -o $1_phase0_lsp_20_EWo2.raw --phase 0 --lpc 10 --lsp --postfilter --dec + diff --git a/libs/libcodec2/src/globals.c b/libs/libcodec2/src/globals.c new file mode 100644 index 0000000000..2e04f6806d --- /dev/null +++ b/libs/libcodec2/src/globals.c @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: globals.c + AUTHOR......: David Rowe + DATE CREATED: 11/5/94 + + Globals for sinusoidal speech coder. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "sine.h" /* global defines for coder */ + +/* Globals used in encoder and decoder */ + +int frames; /* number of frames processed so far */ +float Sn[M]; /* float input speech samples */ +MODEL model; /* model parameters for the current frame */ +int Nw; /* number of samples in analysis window */ +float sig; /* energy of current frame */ + +/* Globals used in encoder */ + +float w[M]; /* time domain hamming window */ +COMP W[FFT_ENC]; /* DFT of w[] */ +COMP Sw[FFT_ENC]; /* DFT of current frame */ + +/* Globals used in decoder */ + +COMP Sw_[FFT_ENC]; /* DFT of all voiced synthesised signal */ +float Sn_[AW_DEC]; /* synthesised speech */ +float Pn[AW_DEC]; /* time domain Parzen (trapezoidal) window */ + diff --git a/libs/libcodec2/src/globals.h b/libs/libcodec2/src/globals.h new file mode 100644 index 0000000000..44aab8b0a0 --- /dev/null +++ b/libs/libcodec2/src/globals.h @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: globals.h + AUTHOR......: David Rowe + DATE CREATED: 1/11/94 + + Globals for sinusoidal speech coder. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* Globals used in encoder and decoder */ + +extern int frames; /* number of frames processed so far */ +extern float Sn[]; /* float input speech samples */ +extern MODEL model; /* model parameters for the current frame */ +extern int Nw; /* number of samples in analysis window */ +extern float sig; /* energy of current frame */ + +/* Globals used in encoder */ + +extern float w[]; /* time domain hamming window */ +extern COMP W[]; /* frequency domain hamming window */ +extern COMP Sw[]; /* DFT of current frame */ +extern COMP Sw_[]; /* DFT of all voiced synthesised signal */ + +/* Globals used in decoder */ + +extern float Sn_[]; /* output synthesised speech samples */ +extern float Pn[]; /* time domain Parzen (trapezoidal) window */ + diff --git a/libs/libcodec2/src/interp.c b/libs/libcodec2/src/interp.c new file mode 100644 index 0000000000..ff7faacb67 --- /dev/null +++ b/libs/libcodec2/src/interp.c @@ -0,0 +1,122 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: interp.c + AUTHOR......: David Rowe + DATE CREATED: 9/10/09 + + Interpolation of 20ms frames to 10ms frames. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <math.h> +#include <string.h> + +#include "defines.h" +#include "interp.h" + +float sample_log_amp(MODEL *model, float w); + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: interp() + AUTHOR......: David Rowe + DATE CREATED: 22/8/10 + + Given two frames decribed by model parameters 20ms apart, determines + the model parameters of the 10ms frame between them. Assumes + voicing is available for middle (interpolated) frame. Outputs are + amplitudes and Wo for the interpolated frame. + + This version can interpolate the amplitudes between two frames of + different Wo and L. + +\*---------------------------------------------------------------------------*/ + +void interpolate( + MODEL *interp, /* interpolated model params */ + MODEL *prev, /* previous frames model params */ + MODEL *next /* next frames model params */ +) +{ + int l; + float w,log_amp; + + /* Wo depends on voicing of this and adjacent frames */ + + if (interp->voiced) { + if (prev->voiced && next->voiced) + interp->Wo = (prev->Wo + next->Wo)/2.0; + if (!prev->voiced && next->voiced) + interp->Wo = next->Wo; + if (prev->voiced && !next->voiced) + interp->Wo = prev->Wo; + } + else { + interp->Wo = TWO_PI/P_MAX; + } + interp->L = PI/interp->Wo; + + /* Interpolate amplitudes using linear interpolation in log domain */ + + for(l=1; l<=interp->L; l++) { + w = l*interp->Wo; + log_amp = (sample_log_amp(prev, w) + sample_log_amp(next, w))/2.0; + interp->A[l] = pow(10.0, log_amp); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: sample_log_amp() + AUTHOR......: David Rowe + DATE CREATED: 22/8/10 + + Samples the amplitude envelope at an arbitrary frequency w. Uses + linear interpolation in the log domain to sample between harmonic + amplitudes. + +\*---------------------------------------------------------------------------*/ + +float sample_log_amp(MODEL *model, float w) +{ + int m; + float f, log_amp; + + assert(w > 0.0); assert (w <= PI); + + m = floor(w/model->Wo + 0.5); + f = (w - m*model->Wo)/w; + assert(f <= 1.0); + + if (m < 1) { + log_amp = f*log10(model->A[1]); + } + else if ((m+1) > model->L) { + log_amp = (1.0-f)*log10(model->A[model->L]); + } + else { + log_amp = (1.0-f)*log10(model->A[m]) + f*log10(model->A[m+1]); + } + + return log_amp; +} + diff --git a/libs/libcodec2/src/interp.h b/libs/libcodec2/src/interp.h new file mode 100644 index 0000000000..0684b5bbff --- /dev/null +++ b/libs/libcodec2/src/interp.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: interp.h + AUTHOR......: David Rowe + DATE CREATED: 9/10/09 + + Interpolation of 20ms frames to 10ms frames. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __INTERP__ +#define __INTERP__ + +void interpolate(MODEL *interp, MODEL *prev, MODEL *next); + +#endif diff --git a/libs/libcodec2/src/listen.sh b/libs/libcodec2/src/listen.sh new file mode 100644 index 0000000000..bebd106f7a --- /dev/null +++ b/libs/libcodec2/src/listen.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# listensim.sh +# David Rowe 10 Sep 2009 +# +# Listen to files processed with sim.sh + +../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_lsp.raw $1_phase0_lpc10.raw $1_phase0_lsp.raw $1_phase0_lsp.raw $2 $3 + + diff --git a/libs/libcodec2/src/listen1.sh b/libs/libcodec2/src/listen1.sh new file mode 100755 index 0000000000..a3b72671bc --- /dev/null +++ b/libs/libcodec2/src/listen1.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# listen1.sh +# David Rowe 10 Sep 2009 +# +# Run menu with common sample file options, headphone version + +#../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_lsp.raw $1_phase0_lpc10.raw $1_phase0_lsp.raw ../raw/$1_g729a.raw $2 $3 -d /dev/dsp1 + +# compare to other codecs + +#../script/menu.sh ../raw/$1.raw $1_phase0_lsp.raw $1_phase0_lsp_20.raw ../raw/$1_g729a.raw ../raw/$1_gsm13k.raw ../raw/$1_speex_8k.raw $2 $3 -d /dev/dsp1 + +../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_test.raw ../raw/$1_g729a.raw $2 $3 -d /dev/dsp1 + + diff --git a/libs/libcodec2/src/listensim.sh b/libs/libcodec2/src/listensim.sh new file mode 100755 index 0000000000..64f7455ab3 --- /dev/null +++ b/libs/libcodec2/src/listensim.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# listensim.sh +# David Rowe 10 Sep 2009 +# +# Listen to files processed with sim.sh + +../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_lsp.raw $1_phase0_lpc10.raw $1_phase0_lsp.raw $1_phase0_lsp_dec.raw $2 $3 + + diff --git a/libs/libcodec2/src/lpc.c b/libs/libcodec2/src/lpc.c new file mode 100644 index 0000000000..1f9ff2bf10 --- /dev/null +++ b/libs/libcodec2/src/lpc.c @@ -0,0 +1,253 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lpc.c + AUTHOR......: David Rowe + DATE CREATED: 30/9/90 + + Linear Prediction functions written in C. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define LPC_MAX_N 512 /* maximum no. of samples in frame */ +#define PI 3.141592654 /* mathematical constant */ + +#include <assert.h> +#include <math.h> +#include "defines.h" +#include "lpc.h" + +/*---------------------------------------------------------------------------*\ + + hanning_window() + + Hanning windows a frame of speech samples. + +\*---------------------------------------------------------------------------*/ + +void hanning_window( + float Sn[], /* input frame of speech samples */ + float Wn[], /* output frame of windowed samples */ + int Nsam /* number of samples */ +) +{ + int i; /* loop variable */ + + for(i=0; i<Nsam; i++) + Wn[i] = Sn[i]*(0.5 - 0.5*cos(2*PI*(float)i/(Nsam-1))); +} + +/*---------------------------------------------------------------------------*\ + + autocorrelate() + + Finds the first P autocorrelation values of an array of windowed speech + samples Sn[]. + +\*---------------------------------------------------------------------------*/ + +void autocorrelate( + float Sn[], /* frame of Nsam windowed speech samples */ + float Rn[], /* array of P+1 autocorrelation coefficients */ + int Nsam, /* number of windowed samples to use */ + int order /* order of LPC analysis */ +) +{ + int i,j; /* loop variables */ + + for(j=0; j<order+1; j++) { + Rn[j] = 0.0; + for(i=0; i<Nsam-j; i++) + Rn[j] += Sn[i]*Sn[i+j]; + } +} + +/*---------------------------------------------------------------------------*\ + + levinson_durbin() + + Given P+1 autocorrelation coefficients, finds P Linear Prediction Coeff. + (LPCs) where P is the order of the LPC all-pole model. The Levinson-Durbin + algorithm is used, and is described in: + + J. Makhoul + "Linear prediction, a tutorial review" + Proceedings of the IEEE + Vol-63, No. 4, April 1975 + +\*---------------------------------------------------------------------------*/ + +void levinson_durbin( + float R[], /* order+1 autocorrelation coeff */ + float lpcs[], /* order+1 LPC's */ + int order /* order of the LPC analysis */ +) +{ + float E[LPC_MAX+1]; + float k[LPC_MAX+1]; + float a[LPC_MAX+1][LPC_MAX+1]; + float sum; + int i,j; /* loop variables */ + + E[0] = R[0]; /* Equation 38a, Makhoul */ + + for(i=1; i<=order; i++) { + sum = 0.0; + for(j=1; j<=i-1; j++) + sum += a[i-1][j]*R[i-j]; + k[i] = -1.0*(R[i] + sum)/E[i-1]; /* Equation 38b, Makhoul */ + if (fabs(k[i]) > 1.0) + k[i] = 0.0; + + a[i][i] = k[i]; + + for(j=1; j<=i-1; j++) + a[i][j] = a[i-1][j] + k[i]*a[i-1][i-j]; /* Equation 38c, Makhoul */ + + E[i] = (1-k[i]*k[i])*E[i-1]; /* Equation 38d, Makhoul */ + } + + for(i=1; i<=order; i++) + lpcs[i] = a[order][i]; + lpcs[0] = 1.0; +} + +/*---------------------------------------------------------------------------*\ + + inverse_filter() + + Inverse Filter, A(z). Produces an array of residual samples from an array + of input samples and linear prediction coefficients. + + The filter memory is stored in the first order samples of the input array. + +\*---------------------------------------------------------------------------*/ + +void inverse_filter( + float Sn[], /* Nsam input samples */ + float a[], /* LPCs for this frame of samples */ + int Nsam, /* number of samples */ + float res[], /* Nsam residual samples */ + int order /* order of LPC */ +) +{ + int i,j; /* loop variables */ + + for(i=0; i<Nsam; i++) { + res[i] = 0.0; + for(j=0; j<=order; j++) + res[i] += Sn[i-j]*a[j]; + } +} + +/*---------------------------------------------------------------------------*\ + + synthesis_filter() + + C version of the Speech Synthesis Filter, 1/A(z). Given an array of + residual or excitation samples, and the the LP filter coefficients, this + function will produce an array of speech samples. This filter structure is + IIR. + + The synthesis filter has memory as well, this is treated in the same way + as the memory for the inverse filter (see inverse_filter() notes above). + The difference is that the memory for the synthesis filter is stored in + the output array, wheras the memory of the inverse filter is stored in the + input array. + + Note: the calling function must update the filter memory. + +\*---------------------------------------------------------------------------*/ + +void synthesis_filter( + float res[], /* Nsam input residual (excitation) samples */ + float a[], /* LPCs for this frame of speech samples */ + int Nsam, /* number of speech samples */ + int order, /* LPC order */ + float Sn_[] /* Nsam output synthesised speech samples */ +) +{ + int i,j; /* loop variables */ + + /* Filter Nsam samples */ + + for(i=0; i<Nsam; i++) { + Sn_[i] = res[i]*a[0]; + for(j=1; j<=order; j++) + Sn_[i] -= Sn_[i-j]*a[j]; + } +} + +/*---------------------------------------------------------------------------*\ + + find_aks() + + This function takes a frame of samples, and determines the linear + prediction coefficients for that frame of samples. + +\*---------------------------------------------------------------------------*/ + +void find_aks( + float Sn[], /* Nsam samples with order sample memory */ + float a[], /* order+1 LPCs with first coeff 1.0 */ + int Nsam, /* number of input speech samples */ + int order, /* order of the LPC analysis */ + float *E /* residual energy */ +) +{ + float Wn[LPC_MAX_N]; /* windowed frame of Nsam speech samples */ + float R[LPC_MAX+1]; /* order+1 autocorrelation values of Sn[] */ + int i; + + assert(order < LPC_MAX); + assert(Nsam < LPC_MAX_N); + + hanning_window(Sn,Wn,Nsam); + autocorrelate(Wn,R,Nsam,order); + levinson_durbin(R,a,order); + + *E = 0.0; + for(i=0; i<=order; i++) + *E += a[i]*R[i]; + if (*E < 0.0) + *E = 1E-12; +} + +/*---------------------------------------------------------------------------*\ + + weight() + + Weights a vector of LPCs. + +\*---------------------------------------------------------------------------*/ + +void weight( + float ak[], /* vector of order+1 LPCs */ + float gamma, /* weighting factor */ + int order, /* num LPCs (excluding leading 1.0) */ + float akw[] /* weighted vector of order+1 LPCs */ +) +{ + int i; + + for(i=1; i<=order; i++) + akw[i] = ak[i]*pow(gamma,(float)i); +} + diff --git a/libs/libcodec2/src/lpc.h b/libs/libcodec2/src/lpc.h new file mode 100644 index 0000000000..e9b42aefd7 --- /dev/null +++ b/libs/libcodec2/src/lpc.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lpc.h + AUTHOR......: David Rowe + DATE CREATED: 24/8/09 + + Linear Prediction functions written in C. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __LPC__ +#define __LPC__ + +#define LPC_MAX_ORDER 20 + +void hanning_window(float Sn[], float Wn[], int Nsam); +void autocorrelate(float Sn[], float Rn[], int Nsam, int order); +void levinson_durbin(float R[], float lpcs[], int order); +void inverse_filter(float Sn[], float a[], int Nsam, float res[], int order); +void synthesis_filter(float res[], float a[], int Nsam, int order, float Sn_[]); +void find_aks(float Sn[], float a[], int Nsam, int order, float *E); +void weight(float ak[], float gamma, int order, float akw[]); + +#endif diff --git a/libs/libcodec2/src/lsp.c b/libs/libcodec2/src/lsp.c new file mode 100644 index 0000000000..feab4219ab --- /dev/null +++ b/libs/libcodec2/src/lsp.c @@ -0,0 +1,323 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lsp.c + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + + This file contains functions for LPC to LSP conversion and LSP to + LPC conversion. Note that the LSP coefficients are not in radians + format but in the x domain of the unit circle. + +\*---------------------------------------------------------------------------*/ + +#include "defines.h" +#include "lsp.h" +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +/*---------------------------------------------------------------------------*\ + + Introduction to Line Spectrum Pairs (LSPs) + ------------------------------------------ + + LSPs are used to encode the LPC filter coefficients {ak} for + transmission over the channel. LSPs have several properties (like + less sensitivity to quantisation noise) that make them superior to + direct quantisation of {ak}. + + A(z) is a polynomial of order lpcrdr with {ak} as the coefficients. + + A(z) is transformed to P(z) and Q(z) (using a substitution and some + algebra), to obtain something like: + + A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1) + + As you can imagine A(z) has complex zeros all over the z-plane. P(z) + and Q(z) have the very neat property of only having zeros _on_ the + unit circle. So to find them we take a test point z=exp(jw) and + evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0 + and pi. + + The zeros (roots) of P(z) also happen to alternate, which is why we + swap coefficients as we find roots. So the process of finding the + LSP frequencies is basically finding the roots of 5th order + polynomials. + + The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence + the name Line Spectrum Pairs (LSPs). + + To convert back to ak we just evaluate (1), "clocking" an impulse + thru it lpcrdr times gives us the impulse response of A(z) which is + {ak}. + +\*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: cheb_poly_eva() + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function evalutes a series of chebyshev polynomials + + FIXME: performing memory allocation at run time is very inefficient, + replace with stack variables of MAX_P size. + +\*---------------------------------------------------------------------------*/ + + +float cheb_poly_eva(float *coef,float x,int m) +/* float coef[] coefficients of the polynomial to be evaluated */ +/* float x the point where polynomial is to be evaluated */ +/* int m order of the polynomial */ +{ + int i; + float *T,*t,*u,*v,sum; + + /* Allocate memory for chebyshev series formulation */ + + if((T = (float *)malloc((m/2+1)*sizeof(float))) == NULL){ + fprintf(stderr, "not enough memory to allocate buffer\n"); + exit(1); + } + + /* Initialise pointers */ + + t = T; /* T[i-2] */ + *t++ = 1.0; + u = t--; /* T[i-1] */ + *u++ = x; + v = u--; /* T[i] */ + + /* Evaluate chebyshev series formulation using iterative approach */ + + for(i=2;i<=m/2;i++) + *v++ = (2*x)*(*u++) - *t++; /* T[i] = 2*x*T[i-1] - T[i-2] */ + + sum=0.0; /* initialise sum to zero */ + t = T; /* reset pointer */ + + /* Evaluate polynomial and return value also free memory space */ + + for(i=0;i<=m/2;i++) + sum+=coef[(m/2)-i]**t++; + + free(T); + return sum; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lpc_to_lsp() + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function converts LPC coefficients to LSP coefficients. + +\*---------------------------------------------------------------------------*/ + +int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta) +/* float *a lpc coefficients */ +/* int lpcrdr order of LPC coefficients (10) */ +/* float *freq LSP frequencies in radians */ +/* int nb number of sub-intervals (4) */ +/* float delta grid spacing interval (0.02) */ +{ + float psuml,psumr,psumm,temp_xr,xl,xr,xm; + float temp_psumr; + int i,j,m,flag,k; + float *Q; /* ptrs for memory allocation */ + float *P; + float *px; /* ptrs of respective P'(z) & Q'(z) */ + float *qx; + float *p; + float *q; + float *pt; /* ptr used for cheb_poly_eval() + whether P' or Q' */ + int roots=0; /* number of roots found */ + flag = 1; + m = lpcrdr/2; /* order of P'(z) & Q'(z) polynimials */ + + /* Allocate memory space for polynomials */ + + Q = (float *) malloc((m+1)*sizeof(float)); + P = (float *) malloc((m+1)*sizeof(float)); + if( (P == NULL) || (Q == NULL) ) { + fprintf(stderr,"not enough memory to allocate buffer\n"); + exit(1); + } + + /* determine P'(z)'s and Q'(z)'s coefficients where + P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ + + px = P; /* initilaise ptrs */ + qx = Q; + p = px; + q = qx; + *px++ = 1.0; + *qx++ = 1.0; + for(i=1;i<=m;i++){ + *px++ = a[i]+a[lpcrdr+1-i]-*p++; + *qx++ = a[i]-a[lpcrdr+1-i]+*q++; + } + px = P; + qx = Q; + for(i=0;i<m;i++){ + *px = 2**px; + *qx = 2**qx; + px++; + qx++; + } + px = P; /* re-initialise ptrs */ + qx = Q; + + /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). + Keep alternating between the two polynomials as each zero is found */ + + xr = 0; /* initialise xr to zero */ + xl = 1.0; /* start at point xl = 1 */ + + + for(j=0;j<lpcrdr;j++){ + if(j%2) /* determines whether P' or Q' is eval. */ + pt = qx; + else + pt = px; + + psuml = cheb_poly_eva(pt,xl,lpcrdr); /* evals poly. at xl */ + flag = 1; + while(flag && (xr >= -1.0)){ + xr = xl - delta ; /* interval spacing */ + psumr = cheb_poly_eva(pt,xr,lpcrdr);/* poly(xl-delta_x) */ + temp_psumr = psumr; + temp_xr = xr; + + /* if no sign change increment xr and re-evaluate + poly(xr). Repeat til sign change. if a sign change has + occurred the interval is bisected and then checked again + for a sign change which determines in which interval the + zero lies in. If there is no sign change between poly(xm) + and poly(xl) set interval between xm and xr else set + interval between xl and xr and repeat till root is located + within the specified limits */ + + if((psumr*psuml)<0.0){ + roots++; + + psumm=psuml; + for(k=0;k<=nb;k++){ + xm = (xl+xr)/2; /* bisect the interval */ + psumm=cheb_poly_eva(pt,xm,lpcrdr); + if(psumm*psuml>0.){ + psuml=psumm; + xl=xm; + } + else{ + psumr=psumm; + xr=xm; + } + } + + /* once zero is found, reset initial interval to xr */ + freq[j] = (xm); + xl = xm; + flag = 0; /* reset flag for next search */ + } + else{ + psuml=temp_psumr; + xl=temp_xr; + } + } + } + free(P); /* free memory space */ + free(Q); + + /* convert from x domain to radians */ + + for(i=0; i<lpcrdr; i++) { + freq[i] = acos(freq[i]); + } + + return(roots); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lsp_to_lpc() + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function converts LSP coefficients to LPC coefficients. In the + Speex code we worked out a wayto simplify this significantly. + +\*---------------------------------------------------------------------------*/ + +void lsp_to_lpc(float *freq, float *ak, int lpcrdr) +/* float *freq array of LSP frequencies in radians */ +/* float *ak array of LPC coefficients */ +/* int lpcrdr order of LPC coefficients */ + + +{ + int i,j; + float xout1,xout2,xin1,xin2; + float *Wp; + float *pw,*n1,*n2,*n3,*n4; + int m = lpcrdr/2; + + /* convert from radians to the x=cos(w) domain */ + + for(i=0; i<lpcrdr; i++) + freq[i] = cos(freq[i]); + + if((Wp = (float *) malloc((4*m+2)*sizeof(float))) == NULL){ + printf("not enough memory to allocate buffer\n"); + exit(1); + } + pw = Wp; + + /* initialise contents of array */ + + for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ + *pw++ = 0.0; + } + + /* Set pointers up */ + + pw = Wp; + xin1 = 1.0; + xin2 = 1.0; + + /* reconstruct P(z) and Q(z) by cascading second order polynomials + in form 1 - 2xz(-1) +z(-2), where x is the LSP coefficient */ + + for(j=0;j<=lpcrdr;j++){ + for(i=0;i<m;i++){ + n1 = pw+(i*4); + n2 = n1 + 1; + n3 = n2 + 1; + n4 = n3 + 1; + xout1 = xin1 - 2*(freq[2*i]) * *n1 + *n2; + xout2 = xin2 - 2*(freq[2*i+1]) * *n3 + *n4; + *n2 = *n1; + *n4 = *n3; + *n1 = xin1; + *n3 = xin2; + xin1 = xout1; + xin2 = xout2; + } + xout1 = xin1 + *(n4+1); + xout2 = xin2 - *(n4+2); + ak[j] = (xout1 + xout2)*0.5; + *(n4+1) = xin1; + *(n4+2) = xin2; + + xin1 = 0.0; + xin2 = 0.0; + } + free(Wp); +} + diff --git a/libs/libcodec2/src/lsp.h b/libs/libcodec2/src/lsp.h new file mode 100644 index 0000000000..88eae7e46d --- /dev/null +++ b/libs/libcodec2/src/lsp.h @@ -0,0 +1,20 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lsp.c + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + + This file contains functions for LPC to LSP conversion and LSP to + LPC conversion. Note that the LSP coefficients are not in radians + format but in the x domain of the unit circle. + +\*---------------------------------------------------------------------------*/ + +#ifndef __LSP__ +#define __LSP__ + +int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta); +void lsp_to_lpc(float *freq, float *ak, int lpcrdr); + +#endif diff --git a/libs/libcodec2/src/nlp.c b/libs/libcodec2/src/nlp.c new file mode 100644 index 0000000000..193ca92109 --- /dev/null +++ b/libs/libcodec2/src/nlp.c @@ -0,0 +1,361 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: nlp.c + AUTHOR......: David Rowe + DATE CREATED: 23/3/93 + + Non Linear Pitch (NLP) estimation functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "defines.h" +#include "nlp.h" +#include "dump.h" +#include "four1.h" + +#include <assert.h> +#include <math.h> +#include <stdlib.h> + +/*---------------------------------------------------------------------------*\ + + DEFINES + +\*---------------------------------------------------------------------------*/ + +#define PMAX_M 600 /* maximum NLP analysis window size */ +#define COEFF 0.95 /* notch filter parameter */ +#define PE_FFT_SIZE 512 /* DFT size for pitch estimation */ +#define DEC 5 /* decimation factor */ +#define SAMPLE_RATE 8000 +#define PI 3.141592654 /* mathematical constant */ +#define T 0.1 /* threshold for local minima candidate */ +#define F0_MAX 500 +#define CNLP 0.3 /* post processor constant */ +#define NLP_NTAP 48 /* Decimation LPF order */ + +/*---------------------------------------------------------------------------*\ + + GLOBALS + +\*---------------------------------------------------------------------------*/ + +/* 48 tap 600Hz low pass FIR filter coefficients */ + +float nlp_fir[] = { + -1.0818124e-03, + -1.1008344e-03, + -9.2768838e-04, + -4.2289438e-04, + 5.5034190e-04, + 2.0029849e-03, + 3.7058509e-03, + 5.1449415e-03, + 5.5924666e-03, + 4.3036754e-03, + 8.0284511e-04, + -4.8204610e-03, + -1.1705810e-02, + -1.8199275e-02, + -2.2065282e-02, + -2.0920610e-02, + -1.2808831e-02, + 3.2204775e-03, + 2.6683811e-02, + 5.5520624e-02, + 8.6305944e-02, + 1.1480192e-01, + 1.3674206e-01, + 1.4867556e-01, + 1.4867556e-01, + 1.3674206e-01, + 1.1480192e-01, + 8.6305944e-02, + 5.5520624e-02, + 2.6683811e-02, + 3.2204775e-03, + -1.2808831e-02, + -2.0920610e-02, + -2.2065282e-02, + -1.8199275e-02, + -1.1705810e-02, + -4.8204610e-03, + 8.0284511e-04, + 4.3036754e-03, + 5.5924666e-03, + 5.1449415e-03, + 3.7058509e-03, + 2.0029849e-03, + 5.5034190e-04, + -4.2289438e-04, + -9.2768838e-04, + -1.1008344e-03, + -1.0818124e-03 +}; + +typedef struct { + float sq[PMAX_M]; /* squared speech samples */ + float mem_x,mem_y; /* memory for notch filter */ + float mem_fir[NLP_NTAP]; /* decimation FIR filter memory */ +} NLP; + +float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax); +float post_process_sub_multiples(COMP Fw[], + int pmin, int pmax, float gmax, int gmax_bin, + float *prev_Wo); + +/*---------------------------------------------------------------------------*\ + + nlp_create() + + Initialisation function for NLP pitch estimator. + +\*---------------------------------------------------------------------------*/ + +void *nlp_create() +{ + NLP *nlp; + int i; + + nlp = (NLP*)malloc(sizeof(NLP)); + if (nlp == NULL) + return NULL; + + for(i=0; i<PMAX_M; i++) + nlp->sq[i] = 0.0; + nlp->mem_x = 0.0; + nlp->mem_y = 0.0; + for(i=0; i<NLP_NTAP; i++) + nlp->mem_fir[i] = 0.0; + + return (void*)nlp; +} + +/*---------------------------------------------------------------------------*\ + + nlp_destory() + + Initialisation function for NLP pitch estimator. + +\*---------------------------------------------------------------------------*/ + +void nlp_destroy(void *nlp_state) +{ + assert(nlp_state != NULL); + free(nlp_state); +} + +/*---------------------------------------------------------------------------*\ + + nlp() + + Determines the pitch in samples using the Non Linear Pitch (NLP) + algorithm [1]. Returns the fundamental in Hz. Note that the actual + pitch estimate is for the centre of the M sample Sn[] vector, not + the current N sample input vector. This is (I think) a delay of 2.5 + frames with N=80 samples. You should align further analysis using + this pitch estimate to be centred on the middle of Sn[]. + + Two post processors have been tried, the MBE version (as discussed + in [1]), and a post processor that checks sub-multiples. Both + suffer occasional gross pitch errors (i.e. neither are perfect). In + the presence of background noise the sub-multiple algorithm tends + towards low F0 which leads to better sounding background noise than + the MBE post processor. + + A good way to test and develop the NLP pitch estimator is using the + tnlp (codec2/unittest) and the codec2/octave/plnlp.m Octave script. + + A pitch tracker searching a few frames forward and backward in time + would be a useful addition. + + References: + + [1] http://www.itr.unisa.edu.au/~steven/thesis/dgr.pdf Chapter 4 + +\*---------------------------------------------------------------------------*/ + +float nlp( + void *nlp_state, + float Sn[], /* input speech vector */ + int n, /* frames shift (no. new samples in Sn[]) */ + int m, /* analysis window size */ + int pmin, /* minimum pitch value */ + int pmax, /* maximum pitch value */ + float *pitch, /* estimated pitch period in samples */ + COMP Sw[], /* Freq domain version of Sn[] */ + float *prev_Wo +) +{ + NLP *nlp; + float notch; /* current notch filter output */ + COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal */ + float gmax; + int gmax_bin; + int i,j; + float best_f0; + + assert(nlp_state != NULL); + nlp = (NLP*)nlp_state; + + /* Square, notch filter at DC, and LP filter vector */ + + for(i=m-n; i<M; i++) /* square latest speech samples */ + nlp->sq[i] = Sn[i]*Sn[i]; + + for(i=m-n; i<m; i++) { /* notch filter at DC */ + notch = nlp->sq[i] - nlp->mem_x; + notch += COEFF*nlp->mem_y; + nlp->mem_x = nlp->sq[i]; + nlp->mem_y = notch; + nlp->sq[i] = notch; + } + + for(i=m-n; i<m; i++) { /* FIR filter vector */ + + for(j=0; j<NLP_NTAP-1; j++) + nlp->mem_fir[j] = nlp->mem_fir[j+1]; + nlp->mem_fir[NLP_NTAP-1] = nlp->sq[i]; + + nlp->sq[i] = 0.0; + for(j=0; j<NLP_NTAP; j++) + nlp->sq[i] += nlp->mem_fir[j]*nlp_fir[j]; + } + + /* Decimate and DFT */ + + for(i=0; i<PE_FFT_SIZE; i++) { + Fw[i].real = 0.0; + Fw[i].imag = 0.0; + } + for(i=0; i<m/DEC; i++) { + Fw[i].real = nlp->sq[i*DEC]*(0.5 - 0.5*cos(2*PI*i/(m/DEC-1))); + } + dump_dec(Fw); + four1(&Fw[-1].imag,PE_FFT_SIZE,1); + for(i=0; i<PE_FFT_SIZE; i++) + Fw[i].real = Fw[i].real*Fw[i].real + Fw[i].imag*Fw[i].imag; + + dump_sq(nlp->sq); + dump_Fw(Fw); + + /* find global peak */ + + gmax = 0.0; + gmax_bin = PE_FFT_SIZE*DEC/pmax; + for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) { + if (Fw[i].real > gmax) { + gmax = Fw[i].real; + gmax_bin = i; + } + } + + best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, + prev_Wo); + + /* Shift samples in buffer to make room for new samples */ + + for(i=0; i<m-n; i++) + nlp->sq[i] = nlp->sq[i+n]; + + /* return pitch and F0 estimate */ + + *pitch = (float)SAMPLE_RATE/best_f0; + return(best_f0); +} + +/*---------------------------------------------------------------------------*\ + + post_process_sub_multiples() + + Given the global maximma of Fw[] we search interger submultiples for + local maxima. If local maxima exist and they are above an + experimentally derived threshold (OK a magic number I pulled out of + the air) we choose the submultiple as the F0 estimate. + + The rational for this is that the lowest frequency peak of Fw[] + should be F0, as Fw[] can be considered the autocorrelation function + of Sw[] (the speech spectrum). However sometimes due to phase + effects the lowest frequency maxima may not be the global maxima. + + This works OK in practice and favours low F0 values in the presence + of background noise which means the sinusoidal codec does an OK job + of synthesising the background noise. High F0 in background noise + tends to sound more periodic introducing annoying artifacts. + +\*---------------------------------------------------------------------------*/ + +float post_process_sub_multiples(COMP Fw[], + int pmin, int pmax, float gmax, int gmax_bin, + float *prev_Wo) +{ + int min_bin, cmax_bin; + int mult; + float thresh, best_f0; + int b, bmin, bmax, lmax_bin; + float lmax, cmax; + int prev_f0_bin; + + /* post process estimate by searching submultiples */ + + mult = 2; + min_bin = PE_FFT_SIZE*DEC/pmax; + cmax_bin = gmax_bin; + prev_f0_bin = *prev_Wo*(4000.0/PI)*(PE_FFT_SIZE*DEC)/SAMPLE_RATE; + + while(gmax_bin/mult >= min_bin) { + + b = gmax_bin/mult; /* determine search interval */ + bmin = 0.8*b; + bmax = 1.2*b; + if (bmin < min_bin) + bmin = min_bin; + + /* lower threshold to favour previous frames pitch estimate, + this is a form of pitch tracking */ + + if ((prev_f0_bin > bmin) && (prev_f0_bin < bmax)) + thresh = CNLP*0.5*gmax; + else + thresh = CNLP*gmax; + + lmax = 0; + lmax_bin = bmin; + for (b=bmin; b<=bmax; b++) /* look for maximum in interval */ + if (Fw[b].real > lmax) { + lmax = Fw[b].real; + lmax_bin = b; + } + + if (lmax > thresh) + if ((lmax > Fw[lmax_bin-1].real) && (lmax > Fw[lmax_bin+1].real)) { + cmax = lmax; + cmax_bin = lmax_bin; + } + + mult++; + } + + best_f0 = (float)cmax_bin*SAMPLE_RATE/(PE_FFT_SIZE*DEC); + + return best_f0; +} + diff --git a/libs/libcodec2/src/nlp.h b/libs/libcodec2/src/nlp.h new file mode 100644 index 0000000000..eaaae97052 --- /dev/null +++ b/libs/libcodec2/src/nlp.h @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: nlp.c + AUTHOR......: David Rowe + DATE CREATED: 23/3/93 + + Non Linear Pitch (NLP) estimation functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __NLP__ +#define __NLP__ + +void *nlp_create(); +void nlp_destroy(void *nlp_state); +float nlp(void *nlp_state, float Sn[], int n, int m, int pmin, int pmax, + float *pitch, COMP Sw[], float *prev_Wo); +float test_candidate_mbe(COMP Sw[], float f0, COMP Sw_[]); + +#endif diff --git a/libs/libcodec2/src/pack.c b/libs/libcodec2/src/pack.c new file mode 100644 index 0000000000..2cbff4438a --- /dev/null +++ b/libs/libcodec2/src/pack.c @@ -0,0 +1,104 @@ +/* + Copyright (C) 2010 Perens LLC <bruce@perens.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + */ +#include "defines.h" +#include "quantise.h" +#include <stdio.h> + +/* Compile-time constants */ +/* Size of unsigned char in bits. Assumes 8 bits-per-char. */ +static const unsigned int WordSize = 8; + +/* Mask to pick the bit component out of bitIndex. */ +static const unsigned int IndexMask = 0x7; + +/* Used to pick the word component out of bitIndex. */ +static const unsigned int ShiftRight = 3; + +/** Pack a bit field into a bit string, encoding the field in Gray code. + * + * The output is an array of unsigned char data. The fields are efficiently + * packed into the bit string. The Gray coding is a naive attempt to reduce + * the effect of single-bit errors, we expect to do a better job as the + * codec develops. + * + * This code would be simpler if it just set one bit at a time in the string, + * but would hit the same cache line more often. I'm not sure the complexity + * gains us anything here. + * + * Although field is currently of int type rather than unsigned for + * compatibility with the rest of the code, indices are always expected to + * be >= 0. + */ +void +pack( + unsigned char * bitArray, /* The output bit string. */ + unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ + int field, /* The bit field to be packed. */ + unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ + ) +{ + /* Convert the field to Gray code */ + field = (field >> 1) ^ field; + + do { + unsigned int bI = *bitIndex; + unsigned int bitsLeft = WordSize - (bI & IndexMask); + unsigned int sliceWidth = + bitsLeft < fieldWidth ? bitsLeft : fieldWidth; + unsigned int wordIndex = bI >> ShiftRight; + + bitArray[wordIndex] |= + ((unsigned char)((field >> (fieldWidth - sliceWidth)) + << (bitsLeft - sliceWidth))); + + *bitIndex = bI + sliceWidth; + fieldWidth -= sliceWidth; + } while ( fieldWidth != 0 ); +} + +/** Unpack a field from a bit string, converting from Gray code to binary. + * + */ +int +unpack( + const unsigned char * bitArray, /* The input bit string. */ + unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ + unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ + ) +{ + unsigned int field = 0; + + do { + unsigned int bI = *bitIndex; + unsigned int bitsLeft = WordSize - (bI & IndexMask); + unsigned int sliceWidth = + bitsLeft < fieldWidth ? bitsLeft : fieldWidth; + + field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & ((1 << sliceWidth) - 1)) << (fieldWidth - sliceWidth)); + + *bitIndex = bI + sliceWidth; + fieldWidth -= sliceWidth; + } while ( fieldWidth != 0 ); + + /* Convert from Gray code to binary. Works for maximum 8-bit fields. */ + unsigned int t = field ^ (field >> 8); + t ^= (t >> 4); + t ^= (t >> 2); + t ^= (t >> 1); + return t; +} diff --git a/libs/libcodec2/src/phase.c b/libs/libcodec2/src/phase.c new file mode 100644 index 0000000000..83fd680e79 --- /dev/null +++ b/libs/libcodec2/src/phase.c @@ -0,0 +1,254 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: phase.c + AUTHOR......: David Rowe + DATE CREATED: 1/2/09 + + Functions for modelling and synthesising phase. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "defines.h" +#include "phase.h" +#include "four1.h" + +#include <assert.h> +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#define VTHRESH 4.0 + +/*---------------------------------------------------------------------------*\ + + aks_to_H() + + Samples the complex LPC synthesis filter spectrum at the harmonic + frequencies. + +\*---------------------------------------------------------------------------*/ + +void aks_to_H( + MODEL *model, /* model parameters */ + float aks[], /* LPC's */ + float G, /* energy term */ + COMP H[], /* complex LPC spectral samples */ + int order +) +{ + COMP Pw[FFT_DEC]; /* power spectrum */ + int i,m; /* loop variables */ + int am,bm; /* limits of current band */ + float r; /* no. rads/bin */ + float Em; /* energy in band */ + float Am; /* spectral amplitude sample */ + int b; /* centre bin of harmonic */ + float phi_; /* phase of LPC spectra */ + + r = TWO_PI/(FFT_DEC); + + /* Determine DFT of A(exp(jw)) ------------------------------------------*/ + + for(i=0; i<FFT_DEC; i++) { + Pw[i].real = 0.0; + Pw[i].imag = 0.0; + } + + for(i=0; i<=order; i++) + Pw[i].real = aks[i]; + + four1(&Pw[-1].imag,FFT_DEC,-1); + + /* Sample magnitude and phase at harmonics */ + + for(m=1; m<=model->L; m++) { + am = floor((m - 0.5)*model->Wo/r + 0.5); + bm = floor((m + 0.5)*model->Wo/r + 0.5); + b = floor(m*model->Wo/r + 0.5); + + Em = 0.0; + for(i=am; i<bm; i++) + Em += G/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); + Am = sqrt(fabs(Em/(bm-am))); + + phi_ = -atan2(Pw[b].imag,Pw[b].real); + H[m].real = Am*cos(phi_); + H[m].imag = Am*sin(phi_); + } +} + + +/*---------------------------------------------------------------------------*\ + + phase_synth_zero_order() + + Synthesises phases based on SNR and a rule based approach. No phase + parameters are required apart from the SNR (which can be reduced to a + 1 bit V/UV decision per frame). + + The phase of each harmonic is modelled as the phase of a LPC + synthesis filter excited by an impulse. Unlike the first order + model the position of the impulse is not transmitted, so we create + an excitation pulse train using a rule based approach. + + Consider a pulse train with a pulse starting time n=0, with pulses + repeated at a rate of Wo, the fundamental frequency. A pulse train + in the time domain is equivalent to harmonics in the frequency + domain. We can make an excitation pulse train using a sum of + sinsusoids: + + for(m=1; m<=L; m++) + ex[n] = cos(m*Wo*n) + + Note: the Octave script ../octave/phase.m is an example of this if + you would like to try making a pulse train. + + The phase of each excitation harmonic is: + + arg(E[m]) = mWo + + where E[m] are the complex excitation (freq domain) samples, + arg(x), just returns the phase of a complex sample x. + + As we don't transmit the pulse position for this model, we need to + synthesise it. Now the excitation pulses occur at a rate of Wo. + This means the phase of the first harmonic advances by N samples + over a synthesis frame of N samples. For example if Wo is pi/20 + (200 Hz), then over a 10ms frame (N=80 samples), the phase of the + first harmonic would advance (pi/20)*80 = 4*pi or two complete + cycles. + + We generate the excitation phase of the fundamental (first + harmonic): + + arg[E[1]] = Wo*N; + + We then relate the phase of the m-th excitation harmonic to the + phase of the fundamental as: + + arg(E[m]) = m*arg(E[1]) + + This E[m] then gets passed through the LPC synthesis filter to + determine the final harmonic phase. + + For a while there were prolems with low pitched males like hts1 + sounding "clicky". The synthesied time domain waveform also looked + clicky. Many methods were tried to improve the sounds quality of + low pitched males. Finally adding a small amount of jitter to each + harmonic worked. + + The current result sounds very close to the original phases, with + only 1 voicing bit per frame. For example hts1a using original + amplitudes and this phase model produces speech hard to distinguish + from speech synthesise with the orginal phases. The sound quality + of this patrtiallyuantised codec (nb original amplitudes) is higher + than g729, even though all the phase information has been + discarded. + + NOTES: + + 1/ This synthesis model is effectvely the same as simple LPC-10 + vocoders, and yet sounds much better. Why? + + 2/ I am pretty sure the Lincoln Lab sinusoidal coding guys (like xMBE + also from MIT) first described this zero phase model, I need to look + up the paper. + + 3/ Note that this approach could cause some discontinuities in + the phase at the edge of synthesis frames, as no attempt is made + to make sure that the phase tracks are continuous (the excitation + phases are continuous, but not the final phases after filtering + by the LPC spectra). Technically this is a bad thing. However + this may actually be a good thing, disturbing the phase tracks a + bit. More research needed, e.g. test a synthesis model that adds + a small delta-W to make phase tracks line up for voiced + harmonics. + + 4/ Why does this sound so great with 1 V/UV decision? Conventional + wisdom says mixed voicing is required for high qaulity speech. + +\*---------------------------------------------------------------------------*/ + +void phase_synth_zero_order( + MODEL *model, + float aks[], + float *ex_phase /* excitation phase of fundamental */ +) +{ + int m; + float new_phi; + COMP Ex[MAX_AMP]; /* excitation samples */ + COMP A_[MAX_AMP]; /* synthesised harmonic samples */ + COMP H[MAX_AMP]; /* LPC freq domain samples */ + float G; + float jitter; + + G = 1.0; + aks_to_H(model,aks,G,H,LPC_ORD); + + /* + Update excitation fundamental phase track, this sets the position + of each pitch pulse during voiced speech. After much experiment + I found that using just this frame Wo improved quality for UV + sounds compared to interpolating two frames Wo like this: + + ex_phase[0] += (*prev_Wo+mode->Wo)*N/2; + */ + + ex_phase[0] += (model->Wo)*N; + ex_phase[0] -= TWO_PI*floor(ex_phase[0]/TWO_PI + 0.5); + + for(m=1; m<=model->L; m++) { + + /* generate excitation */ + + if (model->voiced) { + /* This method of adding jitter really helped remove the clicky + sound in low pitched makes like hts1a. This moves the onset + of each harmonic over at +/- 0.25 of a sample. + */ + jitter = 0.25*(1.0 - 2.0*rand()/RAND_MAX); + Ex[m].real = cos(ex_phase[0]*m - jitter*model->Wo*m); + Ex[m].imag = sin(ex_phase[0]*m - jitter*model->Wo*m); + } + else { + + /* When a few samples were tested I found that LPC filter + phase is not needed in the unvoiced case, but no harm in + keeping it. + */ + float phi = TWO_PI*(float)rand()/RAND_MAX; + Ex[m].real = cos(phi); + Ex[m].imag = sin(phi); + } + + /* filter using LPC filter */ + + A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag; + A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag; + + /* modify sinusoidal phase */ + + new_phi = atan2(A_[m].imag, A_[m].real+1E-12); + model->phi[m] = new_phi; + } + +} diff --git a/libs/libcodec2/src/phase.h b/libs/libcodec2/src/phase.h new file mode 100644 index 0000000000..6dbf3fa2d6 --- /dev/null +++ b/libs/libcodec2/src/phase.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: phase.h + AUTHOR......: David Rowe + DATE CREATED: 1/2/09 + + Functions for modelling phase. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __PHASE__ +#define __PHASE__ + +void phase_synth_zero_order(MODEL *model, float aks[], float *ex_phase); + +#endif diff --git a/libs/libcodec2/src/postfilter.c b/libs/libcodec2/src/postfilter.c new file mode 100644 index 0000000000..6dad76b1e1 --- /dev/null +++ b/libs/libcodec2/src/postfilter.c @@ -0,0 +1,131 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: postfilter.c + AUTHOR......: David Rowe + DATE CREATED: 13/09/09 + + Postfilter to improve sound quality for speech with high levels of + background noise. Unlike mixed-excitation models requires no bits + to be transmitted to handle background noise. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "defines.h" +#include "dump.h" +#include "postfilter.h" + +/*---------------------------------------------------------------------------*\ + + DEFINES + +\*---------------------------------------------------------------------------*/ + +#define BG_THRESH 40.0 /* only consider low levels signals for bg_est */ +#define BG_BETA 0.1 /* averaging filter constant */ + +/*---------------------------------------------------------------------------*\ + + postfilter() + + The post filter is designed to help with speech corrupted by + background noise. The zero phase model tends to make speech with + background noise sound "clicky". With high levels of background + noise the low level inter-formant parts of the spectrum will contain + noise rather than speech harmonics, so modelling them as voiced + (i.e. a continuous, non-random phase track) is inaccurate. + + Some codecs (like MBE) have a mixed voicing model that breaks the + spectrum into voiced and unvoiced regions. Several bits/frame + (5-12) are required to transmit the frequency selective voicing + information. Mixed excitation also requires accurate voicing + estimation (parameter estimators always break occasionally under + exceptional condition). + + In our case we use a post filter approach which requires no + additional bits to be transmitted. The decoder measures the average + level of the background noise during unvoiced frames. If a harmonic + is less than this level it is made unvoiced by randomising it's + phases. + + This idea is rather experimental. Some potential problems that may + happen: + + 1/ If someone says "aaaaaaaahhhhhhhhh" will background estimator track + up to speech level? This would be a bad thing. + + 2/ If background noise suddenly dissapears from the source speech does + estimate drop quickly? What is noise suddenly re-appears? + + 3/ Background noise with a non-flat sepctrum. Current algorithm just + comsiders scpetrum as a whole, but this could be broken up into + bands, each with their own estimator. + + 4/ Males and females with the same level of background noise. Check + performance the same. Changing Wo affects width of each band, may + affect bg energy estimates. + + 5/ Not sure what happens during long periods of voiced speech + e.g. "sshhhhhhh" + +\*---------------------------------------------------------------------------*/ + +void postfilter( + MODEL *model, + float *bg_est +) +{ + int m, uv; + float e; + + /* determine average energy across spectrum */ + + e = 0.0; + for(m=1; m<=model->L; m++) + e += model->A[m]*model->A[m]; + + e = 10.0*log10(e/model->L); + + /* If beneath threhold, update bg estimate. The idea + of the threshold is to prevent updating during high level + speech. */ + + if ((e < BG_THRESH) && !model->voiced) + *bg_est = *bg_est*(1.0 - BG_BETA) + e*BG_BETA; + + /* now mess with phases during voiced frames to make any harmonics + less then our background estimate unvoiced. + */ + + uv = 0; + if (model->voiced) + for(m=1; m<=model->L; m++) + if (20.0*log10(model->A[m]) < *bg_est) { + model->phi[m] = TWO_PI*(float)rand()/RAND_MAX; + uv++; + } + + dump_bg(e, *bg_est, 100.0*uv/model->L); + +} diff --git a/libs/libcodec2/src/postfilter.h b/libs/libcodec2/src/postfilter.h new file mode 100644 index 0000000000..d4dd4ae053 --- /dev/null +++ b/libs/libcodec2/src/postfilter.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: postfilter.h + AUTHOR......: David Rowe + DATE CREATED: 13/09/09 + + Postfilter header file. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __POSTFILTER__ +#define __POSTFILTER__ + +void postfilter(MODEL *model, float *bg_est); + +#endif diff --git a/libs/libcodec2/src/quantise.c b/libs/libcodec2/src/quantise.c new file mode 100644 index 0000000000..a1cd728112 --- /dev/null +++ b/libs/libcodec2/src/quantise.c @@ -0,0 +1,868 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: quantise.c + AUTHOR......: David Rowe + DATE CREATED: 31/5/92 + + Quantisation functions for the sinusoidal coder. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "defines.h" +#include "dump.h" +#include "quantise.h" +#include "lpc.h" +#include "lsp.h" +#include "four1.h" +#include "codebook.h" + +#define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */ +#define MAX_CB 20 /* max number of codebooks */ + +/* describes each codebook */ + +typedef struct { + int k; /* dimension of vector */ + int log2m; /* number of bits in m */ + int m; /* elements in codebook */ + float *fn; /* file name of text file storing the VQ */ +} LSP_CB; + +/* lsp_q describes entire quantiser made up of several codebooks */ + +#ifdef OLDER +/* 10+10+6+6 = 32 bit LSP difference split VQ */ + +LSP_CB lsp_q[] = { + {3, 1024, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd123.txt"}, + {3, 1024, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd456.txt"}, + {2, 64, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd78.txt"}, + {2, 64, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd910.txt"}, + {0, 0, ""} +}; +#endif + +LSP_CB lsp_q[] = { + {1,4,16, codebook_lsp1 }, + {1,4,16, codebook_lsp2 }, + {1,4,16, codebook_lsp3 }, + {1,4,16, codebook_lsp4 }, + {1,4,16, codebook_lsp5 }, + {1,4,16, codebook_lsp6 }, + {1,4,16, codebook_lsp7 }, + {1,3,8, codebook_lsp8 }, + {1,3,8, codebook_lsp9 }, + {1,2,4, codebook_lsp10 }, + {0,0,0, NULL }, +}; + +/* ptr to each codebook */ + +static float *plsp_cb[MAX_CB]; + +/*---------------------------------------------------------------------------*\ + + FUNCTION HEADERS + +\*---------------------------------------------------------------------------*/ + +float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[], + int order); + +/*---------------------------------------------------------------------------*\ + + FUNCTIONS + +\*---------------------------------------------------------------------------*/ + +int lsp_bits(int i) { + return lsp_q[i].log2m; +} + +/*---------------------------------------------------------------------------*\ + + quantise_uniform + + Simulates uniform quantising of a float. + +\*---------------------------------------------------------------------------*/ + +void quantise_uniform(float *val, float min, float max, int bits) +{ + int levels = 1 << (bits-1); + float norm; + int index; + + /* hard limit to quantiser range */ + + printf("min: %f max: %f val: %f ", min, max, val[0]); + if (val[0] < min) val[0] = min; + if (val[0] > max) val[0] = max; + + norm = (*val - min)/(max-min); + printf("%f norm: %f ", val[0], norm); + index = fabs(levels*norm + 0.5); + + *val = min + index*(max-min)/levels; + + printf("index %d val_: %f\n", index, val[0]); +} + +/*---------------------------------------------------------------------------*\ + + lspd_quantise + + Simulates differential lsp quantiser + +\*---------------------------------------------------------------------------*/ + +void lsp_quantise( + float lsp[], + float lsp_[], + int order +) +{ + int i; + float dlsp[LPC_MAX]; + float dlsp_[LPC_MAX]; + + dlsp[0] = lsp[0]; + for(i=1; i<order; i++) + dlsp[i] = lsp[i] - lsp[i-1]; + + for(i=0; i<order; i++) + dlsp_[i] = dlsp[i]; + + quantise_uniform(&dlsp_[0], 0.1, 0.5, 5); + + lsp_[0] = dlsp_[0]; + for(i=1; i<order; i++) + lsp_[i] = lsp_[i-1] + dlsp_[i]; +} + +/*---------------------------------------------------------------------------*\ + + scan_line() + + This function reads a vector of floats from a line in a text file. + +\*---------------------------------------------------------------------------*/ + +void scan_line(FILE *fp, float f[], int n) +/* FILE *fp; file ptr to text file */ +/* float f[]; array of floats to return */ +/* int n; number of floats in line */ +{ + char s[MAX_STR]; + char *ps,*pe; + int i; + + fgets(s,MAX_STR,fp); + ps = pe = s; + for(i=0; i<n; i++) { + while( isspace(*pe)) pe++; + while( !isspace(*pe)) pe++; + sscanf(ps,"%f",&f[i]); + ps = pe; + } +} + +/*---------------------------------------------------------------------------*\ + + load_cb + + Loads a single codebook (LSP vector quantiser) into memory. + +\*---------------------------------------------------------------------------*/ + +void load_cb(float *source, float *cb, int k, int m) +{ + int lines; + int i; + + lines = 0; + for(i=0; i<m; i++) { + cb[k*lines++] = source[i]; + } +} + +/*---------------------------------------------------------------------------*\ + + quantise_init + + Loads the entire LSP quantiser comprised of several vector quantisers + (codebooks). + +\*---------------------------------------------------------------------------*/ + +void quantise_init() +{ + int i,k,m; + + i = 0; + while(lsp_q[i].k) { + k = lsp_q[i].k; + m = lsp_q[i].m; + plsp_cb[i] = (float*)malloc(sizeof(float)*k*m); + assert(plsp_cb[i] != NULL); + load_cb(lsp_q[i].fn, plsp_cb[i], k, m); + i++; + assert(i < MAX_CB); + } +} + +/*---------------------------------------------------------------------------*\ + + quantise + + Quantises vec by choosing the nearest vector in codebook cb, and + returns the vector index. The squared error of the quantised vector + is added to se. + +\*---------------------------------------------------------------------------*/ + +long quantise(float cb[], float vec[], float w[], int k, int m, float *se) +/* float cb[][K]; current VQ codebook */ +/* float vec[]; vector to quantise */ +/* float w[]; weighting vector */ +/* int k; dimension of vectors */ +/* int m; size of codebook */ +/* float *se; accumulated squared error */ +{ + float e; /* current error */ + long besti; /* best index so far */ + float beste; /* best error so far */ + long j; + int i; + + besti = 0; + beste = 1E32; + for(j=0; j<m; j++) { + e = 0.0; + for(i=0; i<k; i++) + e += pow((cb[j*k+i]-vec[i])*w[i],2.0); + if (e < beste) { + beste = e; + besti = j; + } + } + + *se += beste; + + return(besti); +} + +static float gmin=PI; + +float get_gmin(void) { return gmin; } + +void min_lsp_dist(float lsp[], int order) +{ + int i; + + for(i=1; i<order; i++) + if ((lsp[i]-lsp[i-1]) < gmin) + gmin = lsp[i]-lsp[i-1]; +} + +void check_lsp_order(float lsp[], int lpc_order) +{ + int i; + float tmp; + + for(i=1; i<lpc_order; i++) + if (lsp[i] < lsp[i-1]) { + printf("swap %d\n",i); + tmp = lsp[i-1]; + lsp[i-1] = lsp[i]-0.05; + lsp[i] = tmp+0.05; + } +} + +void force_min_lsp_dist(float lsp[], int lpc_order) +{ + int i; + + for(i=1; i<lpc_order; i++) + if ((lsp[i]-lsp[i-1]) < 0.01) { + lsp[i] += 0.01; + } +} + +/*---------------------------------------------------------------------------*\ + + lpc_model_amplitudes + + Derive a LPC model for amplitude samples then estimate amplitude samples + from this model with optional LSP quantisation. + + Returns the spectral distortion for this frame. + +\*---------------------------------------------------------------------------*/ + +float lpc_model_amplitudes( + float Sn[], /* Input frame of speech samples */ + float w[], + MODEL *model, /* sinusoidal model parameters */ + int order, /* LPC model order */ + int lsp_quant, /* optional LSP quantisation if non-zero */ + float ak[] /* output aks */ +) +{ + float Wn[M]; + float R[LPC_MAX+1]; + float E; + int i,j; + float snr; + float lsp[LPC_MAX]; + float lsp_hz[LPC_MAX]; + float lsp_[LPC_MAX]; + int roots; /* number of LSP roots found */ + int index; + float se; + int k,m; + float *cb; + float wt[LPC_MAX]; + + for(i=0; i<M; i++) + Wn[i] = Sn[i]*w[i]; + autocorrelate(Wn,R,M,order); + levinson_durbin(R,ak,order); + + E = 0.0; + for(i=0; i<=order; i++) + E += ak[i]*R[i]; + + for(i=0; i<order; i++) + wt[i] = 1.0; + + if (lsp_quant) { + roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); + if (roots != order) + printf("LSP roots not found\n"); + + /* convert from radians to Hz to make quantisers more + human readable */ + + for(i=0; i<order; i++) + lsp_hz[i] = (4000.0/PI)*lsp[i]; + + /* simple uniform scalar quantisers */ + + for(i=0; i<10; i++) { + k = lsp_q[i].k; + m = lsp_q[i].m; + cb = plsp_cb[i]; + index = quantise(cb, &lsp_hz[i], wt, k, m, &se); + lsp_hz[i] = cb[index*k]; + } + + /* experiment: simulating uniform quantisation error + for(i=0; i<order; i++) + lsp[i] += PI*(12.5/4000.0)*(1.0 - 2.0*(float)rand()/RAND_MAX); + */ + + for(i=0; i<order; i++) + lsp[i] = (PI/4000.0)*lsp_hz[i]; + + /* Bandwidth Expansion (BW). Prevents any two LSPs getting too + close together after quantisation. We know from experiment + that LSP quantisation errors < 12.5Hz (25Hz setp size) are + inaudible so we use that as the minimum LSP separation. + */ + + for(i=1; i<5; i++) { + if (lsp[i] - lsp[i-1] < PI*(12.5/4000.0)) + lsp[i] = lsp[i-1] + PI*(12.5/4000.0); + } + + /* as quantiser gaps increased, larger BW expansion was required + to prevent twinkly noises */ + + for(i=5; i<8; i++) { + if (lsp[i] - lsp[i-1] < PI*(25.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(25.0/4000.0); + } + for(i=8; i<order; i++) { + if (lsp[i] - lsp[i-1] < PI*(75.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(75.0/4000.0); + } + + for(j=0; j<order; j++) + lsp_[j] = lsp[j]; + + lsp_to_lpc(lsp_, ak, order); + dump_lsp(lsp); + } + + dump_E(E); + #ifdef SIM_QUANT + /* simulated LPC energy quantisation */ + { + float e = 10.0*log10(E); + e += 2.0*(1.0 - 2.0*(float)rand()/RAND_MAX); + E = pow(10.0,e/10.0); + } + #endif + + aks_to_M2(ak,order,model,E,&snr, 1); /* {ak} -> {Am} LPC decode */ + + return snr; +} + +/*---------------------------------------------------------------------------*\ + + aks_to_M2() + + Transforms the linear prediction coefficients to spectral amplitude + samples. This function determines A(m) from the average energy per + band using an FFT. + +\*---------------------------------------------------------------------------*/ + +void aks_to_M2( + float ak[], /* LPC's */ + int order, + MODEL *model, /* sinusoidal model parameters for this frame */ + float E, /* energy term */ + float *snr, /* signal to noise ratio for this frame in dB */ + int dump /* true to dump sample to dump file */ +) +{ + COMP Pw[FFT_DEC]; /* power spectrum */ + int i,m; /* loop variables */ + int am,bm; /* limits of current band */ + float r; /* no. rads/bin */ + float Em; /* energy in band */ + float Am; /* spectral amplitude sample */ + float signal, noise; + + r = TWO_PI/(FFT_DEC); + + /* Determine DFT of A(exp(jw)) --------------------------------------------*/ + + for(i=0; i<FFT_DEC; i++) { + Pw[i].real = 0.0; + Pw[i].imag = 0.0; + } + + for(i=0; i<=order; i++) + Pw[i].real = ak[i]; + four1(&Pw[-1].imag,FFT_DEC,1); + + /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/ + + for(i=0; i<FFT_DEC/2; i++) + Pw[i].real = E/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); + if (dump) + dump_Pw(Pw); + + /* Determine magnitudes by linear interpolation of P(w) -------------------*/ + + signal = noise = 0.0; + for(m=1; m<=model->L; m++) { + am = floor((m - 0.5)*model->Wo/r + 0.5); + bm = floor((m + 0.5)*model->Wo/r + 0.5); + Em = 0.0; + + for(i=am; i<bm; i++) + Em += Pw[i].real; + Am = sqrt(Em); + + signal += pow(model->A[m],2.0); + noise += pow(model->A[m] - Am,2.0); + model->A[m] = Am; + } + *snr = 10.0*log10(signal/noise); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_Wo() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Encodes Wo using a WO_LEVELS quantiser. + +\*---------------------------------------------------------------------------*/ + +int encode_Wo(float Wo) +{ + int index; + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + float norm; + + norm = (Wo - Wo_min)/(Wo_max - Wo_min); + index = floor(WO_LEVELS * norm + 0.5); + if (index < 0 ) index = 0; + if (index > (WO_LEVELS-1)) index = WO_LEVELS-1; + + return index; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_Wo() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Decodes Wo using a WO_LEVELS quantiser. + +\*---------------------------------------------------------------------------*/ + +float decode_Wo(int index) +{ + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + float step; + float Wo; + + step = (Wo_max - Wo_min)/WO_LEVELS; + Wo = Wo_min + step*(index); + + return Wo; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: speech_to_uq_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Analyse a windowed frame of time domain speech to determine LPCs + which are the converted to LSPs for quantisation and transmission + over the channel. + +\*---------------------------------------------------------------------------*/ + +float speech_to_uq_lsps(float lsp[], + float ak[], + float Sn[], + float w[], + int order +) +{ + int i, roots; + float Wn[M]; + float R[LPC_MAX+1]; + float E; + + for(i=0; i<M; i++) + Wn[i] = Sn[i]*w[i]; + autocorrelate(Wn, R, M, order); + levinson_durbin(R, ak, order); + + E = 0.0; + for(i=0; i<=order; i++) + E += ak[i]*R[i]; + + roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); + // assert(roots == order); + + return E; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + From a vector of unquantised (floating point) LSPs finds the quantised + LSP indexes. + +\*---------------------------------------------------------------------------*/ + +void encode_lsps(int indexes[], float lsp[], int order) +{ + int i,k,m; + float wt[1]; + float lsp_hz[LPC_MAX]; + float *cb, se; + + /* convert from radians to Hz so we can use human readable + frequencies */ + + for(i=0; i<order; i++) + lsp_hz[i] = (4000.0/PI)*lsp[i]; + + /* simple uniform scalar quantisers */ + + wt[0] = 1.0; + for(i=0; i<order; i++) { + k = lsp_q[i].k; + m = lsp_q[i].m; + cb = plsp_cb[i]; + indexes[i] = quantise(cb, &lsp_hz[i], wt, k, m, &se); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + From a vector of quantised LSP indexes, returns the quantised + (floating point) LSPs. + +\*---------------------------------------------------------------------------*/ + +void decode_lsps(float lsp[], int indexes[], int order) +{ + int i,k; + float lsp_hz[LPC_MAX]; + float *cb; + + for(i=0; i<order; i++) { + k = lsp_q[i].k; + cb = plsp_cb[i]; + lsp_hz[i] = cb[indexes[i]*k]; + } + + /* convert back to radians */ + + for(i=0; i<order; i++) + lsp[i] = (PI/4000.0)*lsp_hz[i]; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: bw_expand_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Applies Bandwidth Expansion (BW) to a vector of LSPs. Prevents any + two LSPs getting too close together after quantisation. We know + from experiment that LSP quantisation errors < 12.5Hz (25Hz setp + size) are inaudible so we use that as the minimum LSP separation. + +\*---------------------------------------------------------------------------*/ + +void bw_expand_lsps(float lsp[], + int order +) +{ + int i; + + for(i=1; i<5; i++) { + if (lsp[i] - lsp[i-1] < PI*(12.5/4000.0)) + lsp[i] = lsp[i-1] + PI*(12.5/4000.0); + } + + /* As quantiser gaps increased, larger BW expansion was required + to prevent twinkly noises. This may need more experiment for + different quanstisers. + */ + + for(i=5; i<8; i++) { + if (lsp[i] - lsp[i-1] < PI*(25.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(25.0/4000.0); + } + for(i=8; i<order; i++) { + if (lsp[i] - lsp[i-1] < PI*(75.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(75.0/4000.0); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: need_lpc_correction() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Determine if we need LPC correction of first harmonic. + +\*---------------------------------------------------------------------------*/ + +int need_lpc_correction(MODEL *model, float ak[], float E) +{ + MODEL tmp; + float snr,E1; + + /* Find amplitudes so we can check if we need LPC correction. + TODO: replace call to aks_to_M2() by a single DFT calculation + of E/A(exp(jWo)) to make much more efficient. We only need + A[1]. + */ + + memcpy(&tmp, model, sizeof(MODEL)); + aks_to_M2(ak, LPC_ORD, &tmp, E, &snr, 0); + + /* + Attenuate fundamental by 30dB if F0 < 150 Hz and LPC modelling + error for A[1] is larger than 6dB. + + LPC modelling often makes big errors on 1st harmonic, for example + when the fundamental has been removed by analog high pass + filtering before sampling. However on unfiltered speech from + high quality sources we would like to keep the fundamental to + maintain the speech quality. So we check the error in A[1] and + attenuate it if the error is large to avoid annoying low + frequency energy after LPC modelling. + + This requires a single bit to quantise, on top of the other + spectral magnitude bits (i.e. LSP bits + 1 total). + */ + + E1 = fabs(20.0*log10(model->A[1]) - 20.0*log10(tmp.A[1])); + if (E1 > 6.0) + return 1; + else + return 0; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: apply_lpc_correction() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Apply first harmonic LPC correction at decoder. + +\*---------------------------------------------------------------------------*/ + +void apply_lpc_correction(MODEL *model, int lpc_correction) +{ + if (lpc_correction) { + if (model->Wo < (PI*150.0/4000)) { + model->A[1] *= 0.032; + } + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_energy() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Encodes LPC energy using an E_LEVELS quantiser. + +\*---------------------------------------------------------------------------*/ + +int encode_energy(float e) +{ + int index; + float e_min = E_MIN_DB; + float e_max = E_MAX_DB; + float norm; + + e = 10.0*log10(e); + norm = (e - e_min)/(e_max - e_min); + index = floor(E_LEVELS * norm + 0.5); + if (index < 0 ) index = 0; + if (index > (E_LEVELS-1)) index = E_LEVELS-1; + + return index; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_energy() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Decodes energy using a WO_BITS quantiser. + +\*---------------------------------------------------------------------------*/ + +float decode_energy(int index) +{ + float e_min = E_MIN_DB; + float e_max = E_MAX_DB; + float step; + float e; + + step = (e_max - e_min)/E_LEVELS; + e = e_min + step*(index); + e = pow(10.0,e/10.0); + + return e; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_amplitudes() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Time domain LPC is used model the amplitudes which are then + converted to LSPs and quantised. So we don't actually encode the + amplitudes directly, rather we derive an equivalent representation + from the time domain speech. + +\*---------------------------------------------------------------------------*/ + +void encode_amplitudes(int lsp_indexes[], + int *lpc_correction, + int *energy_index, + MODEL *model, + float Sn[], + float w[]) +{ + float lsps[LPC_ORD]; + float ak[LPC_ORD+1]; + float e; + + e = speech_to_uq_lsps(lsps, ak, Sn, w, LPC_ORD); + encode_lsps(lsp_indexes, lsps, LPC_ORD); + *lpc_correction = need_lpc_correction(model, ak, e); + *energy_index = encode_energy(e); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_amplitudes() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Given the amplitude quantiser indexes recovers the harmonic + amplitudes. + +\*---------------------------------------------------------------------------*/ + +float decode_amplitudes(MODEL *model, + float ak[], + int lsp_indexes[], + int lpc_correction, + int energy_index +) +{ + float lsps[LPC_ORD]; + float e; + float snr; + + decode_lsps(lsps, lsp_indexes, LPC_ORD); + bw_expand_lsps(lsps, LPC_ORD); + lsp_to_lpc(lsps, ak, LPC_ORD); + e = decode_energy(energy_index); + aks_to_M2(ak, LPC_ORD, model, e, &snr, 1); + apply_lpc_correction(model, lpc_correction); + + return snr; +} diff --git a/libs/libcodec2/src/quantise.h b/libs/libcodec2/src/quantise.h new file mode 100644 index 0000000000..ded7645381 --- /dev/null +++ b/libs/libcodec2/src/quantise.h @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: quantise.h + AUTHOR......: David Rowe + DATE CREATED: 31/5/92 + + Quantisation functions for the sinusoidal coder. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __QUANTISE__ +#define __QUANTISE__ + +#define WO_BITS 7 +#define WO_LEVELS (1<<WO_BITS) +#define E_BITS 5 +#define E_LEVELS (1<<E_BITS) +#define E_MIN_DB -10.0 +#define E_MAX_DB 40.0 + +void quantise_init(); +float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order, + int lsp,float ak[]); +void aks_to_M2(float ak[], int order, MODEL *model, float E, float *snr, + int dump); +float get_gmin(void); + +int encode_Wo(float Wo); +float decode_Wo(int index); + +void encode_lsps(int indexes[], float lsp[], int order); +void decode_lsps(float lsp[], int indexes[], int order); + +int encode_energy(float e); +float decode_energy(int index); + +void encode_amplitudes(int lsp_indexes[], + int *lpc_correction, + int *energy_index, + MODEL *model, + float Sn[], + float w[]); + +float decode_amplitudes(MODEL *model, + float ak[], + int lsp_indexes[], + int lpc_correction, + int energy_index); + +void pack(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits); +int unpack(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits); + +int lsp_bits(int i); + +int need_lpc_correction(MODEL *model, float ak[], float E); +void apply_lpc_correction(MODEL *model, int lpc_correction); +float speech_to_uq_lsps(float lsp[], + float ak[], + float Sn[], + float w[], + int order + ); +void bw_expand_lsps(float lsp[], + int order + ); +void decode_lsps(float lsp[], int indexes[], int order); + +#endif diff --git a/libs/libcodec2/src/sim.sh b/libs/libcodec2/src/sim.sh new file mode 100755 index 0000000000..ed298e34f3 --- /dev/null +++ b/libs/libcodec2/src/sim.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# sim.sh +# David Rowe 10 Sep 2009 + +# Process a source file using the codec 2 simulation. An output +# speech file is generated for each major processing step, from the +# unquantised siusoidal model to fully quantised. This way we can +# listen to the effect of each processing step. Use listensim.sh to +# test the output files. + +../src/c2sim ../raw/$1.raw -o $1_uq.raw +../src/c2sim ../raw/$1.raw --phase0 -o $1_phase0.raw --postfilter +../src/c2sim ../raw/$1.raw --lpc 10 -o $1_lpc10.raw +../src/c2sim ../raw/$1.raw --lpc 10 --lsp -o $1_lsp.raw +../src/c2sim ../raw/$1.raw --phase0 --lpc 10 -o $1_phase0_lpc10.raw --postfilter +../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp.raw --postfilter +../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp_dec.raw --postfilter --dec + diff --git a/libs/libcodec2/src/sine.c b/libs/libcodec2/src/sine.c new file mode 100644 index 0000000000..9263151b7b --- /dev/null +++ b/libs/libcodec2/src/sine.c @@ -0,0 +1,530 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: sine.c + AUTHOR......: David Rowe + DATE CREATED: 19/8/2010 + + Sinusoidal analysis and synthesis functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 1990-2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/*---------------------------------------------------------------------------*\ + + INCLUDES + +\*---------------------------------------------------------------------------*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "defines.h" +#include "sine.h" +#include "four1.h" + +/*---------------------------------------------------------------------------*\ + + HEADERS + +\*---------------------------------------------------------------------------*/ + +void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, + float pstep); + +/*---------------------------------------------------------------------------*\ + + FUNCTIONS + +\*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: make_analysis_window + AUTHOR......: David Rowe + DATE CREATED: 11/5/94 + + Init function that generates the time domain analysis window and it's DFT. + +\*---------------------------------------------------------------------------*/ + +void make_analysis_window(float w[],COMP W[]) +{ + float m; + COMP temp; + int i,j; + + /* + Generate Hamming window centered on M-sample pitch analysis window + + 0 M/2 M-1 + |-------------|-------------| + |-------|-------| + NW samples + + All our analysis/synthsis is centred on the M/2 sample. + */ + + m = 0.0; + for(i=0; i<M/2-NW/2; i++) + w[i] = 0.0; + for(i=M/2-NW/2,j=0; i<M/2+NW/2; i++,j++) { + w[i] = 0.5 - 0.5*cos(TWO_PI*j/(NW-1)); + m += w[i]*w[i]; + } + for(i=M/2+NW/2; i<M; i++) + w[i] = 0.0; + + /* Normalise - makes freq domain amplitude estimation straight + forward */ + + m = 1.0/sqrt(m*FFT_ENC); + for(i=0; i<M; i++) { + w[i] *= m; + } + + /* + Generate DFT of analysis window, used for later processing. Note + we modulo FFT_ENC shift the time domain window w[], this makes the + imaginary part of the DFT W[] equal to zero as the shifted w[] is + even about the n=0 time axis if NW is odd. Having the imag part + of the DFT W[] makes computation easier. + + 0 FFT_ENC-1 + |-------------------------| + + ----\ /---- + \ / + \ / <- shifted version of window w[n] + \ / + \ / + ------- + + |---------| |---------| + NW/2 NW/2 + */ + + for(i=0; i<FFT_ENC; i++) { + W[i].real = 0.0; + W[i].imag = 0.0; + } + for(i=0; i<NW/2; i++) + W[i].real = w[i+M/2]; + for(i=FFT_ENC-NW/2,j=M/2-NW/2; i<FFT_ENC; i++,j++) + W[i].real = w[j]; + + four1(&W[-1].imag,FFT_ENC,-1); /* "Numerical Recipes in C" FFT */ + + /* + Re-arrange W[] to be symmetrical about FFT_ENC/2. Makes later + analysis convenient. + + Before: + + + 0 FFT_ENC-1 + |----------|---------| + __ _ + \ / + \_______________/ + + After: + + 0 FFT_ENC-1 + |----------|---------| + ___ + / \ + ________/ \_______ + + */ + + + for(i=0; i<FFT_ENC/2; i++) { + temp.real = W[i].real; + temp.imag = W[i].imag; + W[i].real = W[i+FFT_ENC/2].real; + W[i].imag = W[i+FFT_ENC/2].imag; + W[i+FFT_ENC/2].real = temp.real; + W[i+FFT_ENC/2].imag = temp.imag; + } + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: dft_speech + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Finds the DFT of the current speech input speech frame. + +\*---------------------------------------------------------------------------*/ + +void dft_speech(COMP Sw[], float Sn[], float w[]) +{ + int i; + + for(i=0; i<FFT_ENC; i++) { + Sw[i].real = 0.0; + Sw[i].imag = 0.0; + } + + /* Centre analysis window on time axis, we need to arrange input + to FFT this way to make FFT phases correct */ + + /* move 2nd half to start of FFT input vector */ + + for(i=0; i<NW/2; i++) + Sw[i].real = Sn[i+M/2]*w[i+M/2]; + + /* move 1st half to end of FFT input vector */ + + for(i=0; i<NW/2; i++) + Sw[FFT_ENC-NW/2+i].real = Sn[i+M/2-NW/2]*w[i+M/2-NW/2]; + + four1(&Sw[-1].imag,FFT_ENC,-1); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: two_stage_pitch_refinement + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Refines the current pitch estimate using the harmonic sum pitch + estimation technique. + +\*---------------------------------------------------------------------------*/ + +void two_stage_pitch_refinement(MODEL *model, COMP Sw[]) +{ + float pmin,pmax,pstep; /* pitch refinment minimum, maximum and step */ + + /* Coarse refinement */ + + pmax = TWO_PI/model->Wo + 5; + pmin = TWO_PI/model->Wo - 5; + pstep = 1.0; + hs_pitch_refinement(model,Sw,pmin,pmax,pstep); + + /* Fine refinement */ + + pmax = TWO_PI/model->Wo + 1; + pmin = TWO_PI/model->Wo - 1; + pstep = 0.25; + hs_pitch_refinement(model,Sw,pmin,pmax,pstep); + + /* Limit range */ + + if (model->Wo < TWO_PI/P_MAX) + model->Wo = TWO_PI/P_MAX; + if (model->Wo > TWO_PI/P_MIN) + model->Wo = TWO_PI/P_MIN; + + model->L = floor(PI/model->Wo); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: hs_pitch_refinement + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Harmonic sum pitch refinement function. + + pmin pitch search range minimum + pmax pitch search range maximum + step pitch search step size + model current pitch estimate in model.Wo + + model refined pitch estimate in model.Wo + +\*---------------------------------------------------------------------------*/ + +void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float pstep) +{ + int m; /* loop variable */ + int b; /* bin for current harmonic centre */ + float E; /* energy for current pitch*/ + float Wo; /* current "test" fundamental freq. */ + float Wom; /* Wo that maximises E */ + float Em; /* mamimum energy */ + float r; /* number of rads/bin */ + float p; /* current pitch */ + + /* Initialisation */ + + model->L = PI/model->Wo; /* use initial pitch est. for L */ + Wom = model->Wo; + Em = 0.0; + r = TWO_PI/FFT_ENC; + + /* Determine harmonic sum for a range of Wo values */ + + for(p=pmin; p<=pmax; p+=pstep) { + E = 0.0; + Wo = TWO_PI/p; + + /* Sum harmonic magnitudes */ + + for(m=1; m<=model->L; m++) { + b = floor(m*Wo/r + 0.5); + E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag; + } + + /* Compare to see if this is a maximum */ + + if (E > Em) { + Em = E; + Wom = Wo; + } + } + + model->Wo = Wom; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: estimate_amplitudes + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Estimates the complex amplitudes of the harmonics. + +\*---------------------------------------------------------------------------*/ + +void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[]) +{ + int i,m; /* loop variables */ + int am,bm; /* bounds of current harmonic */ + int b; /* DFT bin of centre of current harmonic */ + float den; /* denominator of amplitude expression */ + float r; /* number of rads/bin */ + int offset; + COMP Am; + + r = TWO_PI/FFT_ENC; + + for(m=1; m<=model->L; m++) { + den = 0.0; + am = floor((m - 0.5)*model->Wo/r + 0.5); + bm = floor((m + 0.5)*model->Wo/r + 0.5); + b = floor(m*model->Wo/r + 0.5); + + /* Estimate ampltude of harmonic */ + + den = 0.0; + Am.real = Am.imag = 0.0; + for(i=am; i<bm; i++) { + den += Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag; + offset = i + FFT_ENC/2 - floor(m*model->Wo/r + 0.5); + Am.real += Sw[i].real*W[offset].real; + Am.imag += Sw[i].imag*W[offset].real; + } + + model->A[m] = sqrt(den); + + /* Estimate phase of harmonic */ + + model->phi[m] = atan2(Sw[b].imag,Sw[b].real); + } +} + +/*---------------------------------------------------------------------------*\ + + est_voicing_mbe() + + Returns the error of the MBE cost function for a fiven F0. + + Note: I think a lot of the operations below can be simplified as + W[].imag = 0 and has been normalised such that den always equals 1. + +\*---------------------------------------------------------------------------*/ + +float est_voicing_mbe( + MODEL *model, + COMP Sw[], + COMP W[], + float f0, + COMP Sw_[] /* DFT of all voiced synthesised signal for f0 */ + /* useful for debugging/dump file */ +) +{ + int i,l,al,bl,m; /* loop variables */ + COMP Am; /* amplitude sample for this band */ + int offset; /* centers Hw[] about current harmonic */ + float den; /* denominator of Am expression */ + float error; /* accumulated error between originl and synthesised */ + float Wo; /* current "test" fundamental freq. */ + int L; + float sig, snr; + + sig = 0.0; + for(l=1; l<=model->L/4; l++) { + sig += model->A[l]*model->A[l]; + } + + for(i=0; i<FFT_ENC; i++) { + Sw_[i].real = 0.0; + Sw_[i].imag = 0.0; + } + + L = floor((FS/2.0)/f0); + Wo = f0*(TWO_PI/FS); + + error = 0.0; + + /* Just test across the harmonics in the first 1000 Hz (L/4) */ + + for(l=1; l<=L/4; l++) { + Am.real = 0.0; + Am.imag = 0.0; + den = 0.0; + al = ceil((l - 0.5)*Wo*FFT_ENC/TWO_PI); + bl = ceil((l + 0.5)*Wo*FFT_ENC/TWO_PI); + + /* Estimate amplitude of harmonic assuming harmonic is totally voiced */ + + for(m=al; m<bl; m++) { + offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; + Am.real += Sw[m].real*W[offset].real + Sw[m].imag*W[offset].imag; + Am.imag += Sw[m].imag*W[offset].real - Sw[m].real*W[offset].imag; + den += W[offset].real*W[offset].real + W[offset].imag*W[offset].imag; + } + + Am.real = Am.real/den; + Am.imag = Am.imag/den; + + /* Determine error between estimated harmonic and original */ + + for(m=al; m<bl; m++) { + offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; + Sw_[m].real = Am.real*W[offset].real - Am.imag*W[offset].imag; + Sw_[m].imag = Am.real*W[offset].imag + Am.imag*W[offset].real; + error += (Sw[m].real - Sw_[m].real)*(Sw[m].real - Sw_[m].real); + error += (Sw[m].imag - Sw_[m].imag)*(Sw[m].imag - Sw_[m].imag); + } + } + + snr = 10.0*log10(sig/error); + if (snr > V_THRESH) + model->voiced = 1; + else + model->voiced = 0; + + return snr; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: make_synthesis_window + AUTHOR......: David Rowe + DATE CREATED: 11/5/94 + + Init function that generates the trapezoidal (Parzen) sythesis window. + +\*---------------------------------------------------------------------------*/ + +void make_synthesis_window(float Pn[]) +{ + int i; + float win; + + /* Generate Parzen window in time domain */ + + win = 0.0; + for(i=0; i<N/2-TW; i++) + Pn[i] = 0.0; + win = 0.0; + for(i=N/2-TW; i<N/2+TW; win+=1.0/(2*TW), i++ ) + Pn[i] = win; + for(i=N/2+TW; i<3*N/2-TW; i++) + Pn[i] = 1.0; + win = 1.0; + for(i=3*N/2-TW; i<3*N/2+TW; win-=1.0/(2*TW), i++) + Pn[i] = win; + for(i=3*N/2+TW; i<2*N; i++) + Pn[i] = 0.0; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: synthesise + AUTHOR......: David Rowe + DATE CREATED: 20/2/95 + + Synthesise a speech signal in the frequency domain from the + sinusodal model parameters. Uses overlap-add a triangular window to + smoothly interpolate betwen frames. + +\*---------------------------------------------------------------------------*/ + +void synthesise( + float Sn_[], /* time domain synthesised signal */ + MODEL *model, /* ptr to model parameters for this frame */ + float Pn[], /* time domain Parzen window */ + int shift /* used to handle transition frames */ +) +{ + int i,l,j,b; /* loop variables */ + COMP Sw_[FFT_DEC]; /* DFT of synthesised signal */ + + if (shift) { + /* Update memories */ + + for(i=0; i<N-1; i++) { + Sn_[i] = Sn_[i+N]; + } + Sn_[N-1] = 0.0; + } + + for(i=0; i<FFT_DEC; i++) { + Sw_[i].real = 0.0; + Sw_[i].imag = 0.0; + } + + /* Now set up frequency domain synthesised speech */ + + for(l=1; l<=model->L; l++) { + b = floor(l*model->Wo*FFT_DEC/TWO_PI + 0.5); + Sw_[b].real = model->A[l]*cos(model->phi[l]); + Sw_[b].imag = model->A[l]*sin(model->phi[l]); + Sw_[FFT_DEC-b].real = Sw_[b].real; + Sw_[FFT_DEC-b].imag = -Sw_[b].imag; + } + + /* Perform inverse DFT */ + + four1(&Sw_[-1].imag,FFT_DEC,1); + + /* Overlap add to previous samples */ + + for(i=0; i<N-1; i++) { + Sn_[i] += Sw_[FFT_DEC-N+1+i].real*Pn[i]; + } + + if (shift) + for(i=N-1,j=0; i<2*N; i++,j++) + Sn_[i] = Sw_[j].real*Pn[i]; + else + for(i=N-1,j=0; i<2*N; i++,j++) + Sn_[i] += Sw_[j].real*Pn[i]; +} + diff --git a/libs/libcodec2/src/sine.h b/libs/libcodec2/src/sine.h new file mode 100644 index 0000000000..9cdfbcfbc1 --- /dev/null +++ b/libs/libcodec2/src/sine.h @@ -0,0 +1,40 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: sine.h + AUTHOR......: David Rowe + DATE CREATED: 1/11/94 + + Header file for sinusoidal analysis and synthesis functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SINE__ +#define __SINE__ + +void make_analysis_window(float w[], COMP W[]); +void dft_speech(COMP Sw[], float Sn[], float w[]); +void two_stage_pitch_refinement(MODEL *model, COMP Sw[]); +void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[]); +float est_voicing_mbe(MODEL *model, COMP Sw[], COMP W[], float f0, COMP Sw_[]); +void make_synthesis_window(float Pn[]); +void synthesise(float Sn_[], MODEL *model, float Pn[], int shift); + +#endif diff --git a/libs/libcodec2/unittest/Makefile.am b/libs/libcodec2/unittest/Makefile.am new file mode 100644 index 0000000000..81d546307b --- /dev/null +++ b/libs/libcodec2/unittest/Makefile.am @@ -0,0 +1,41 @@ +AM_CFLAGS = -I../src -g -DFLOATING_POINT -DVAR_ARRAYS +AUTOMAKE_OPTS = gnu +NAME = libcodec2 +AM_CPPFLAGS = $(AM_CFLAGS) + +bin_PROGRAMS = genres genlsp extract vqtrain tnlp tinterp tquant tcodec2 + + +genres_SOURCES = genres.c ../src/lpc.c ../src/codebook.c +genres_LDADD = $(lib_LTLIBRARIES) +genres_LDFLAGS = $(LIBS) + +genlsp_SOURCES = genlsp.c ../src/lpc.c ../src/lsp.c ../src/codebook.c +genlsp_LDADD = $(lib_LTLIBRARIES) +genlsp_LDFLAGS = $(LIBS) + +extract_SOURCES = extract.c ../src/codebook.c +extract_LDADD = $(lib_LTLIBRARIES) +extract_LDFLAGS = $(LIBS) + +vqtrain_SOURCES = vqtrain.c ../src/codebook.c +vqtrain_LDADD = $(lib_LTLIBRARIES) +vqtrain_LDFLAGS = $(LIBS) + +tnlp_SOURCES = tnlp.c ../src/sine.c ../src/nlp.c ../src/four1.c ../src/dump.c ../src/codebook.c +tnlp_LDADD = $(lib_LTLIBRARIES) +tnlp_LDFLAGS = $(LIBS) + +tinterp_SOURCES = tinterp.c ../src/sine.c ../src/four1.c ../src/interp.c ../src/codebook.c +tinterp_LDADD = $(lib_LTLIBRARIES) +tinterp_LDFLAGS = $(LIBS) + +tquant_SOURCES = tquant.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/four1.c ../src/codebook.c +tquant_LDADD = $(lib_LTLIBRARIES) +tquant_LDFLAGS = $(LIBS) + +tcodec2_SOURCES = tcodec2.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/four1.c \ +../src/codec2.c ../src/sine.c ../src/nlp.c ../src/postfilter.c ../src/phase.c ../src/interp.c ../src/pack.c ../src/codebook.c +tcodec2_LDADD = $(lib_LTLIBRARIES) +tcodec2_LDFLAGS = $(LIBS) + diff --git a/libs/libcodec2/unittest/extract.c b/libs/libcodec2/unittest/extract.c new file mode 100644 index 0000000000..b7544edf3a --- /dev/null +++ b/libs/libcodec2/unittest/extract.c @@ -0,0 +1,121 @@ +/*--------------------------------------------------------------------------*\ + + FILE........: extract.c + AUTHOR......: David Rowe + DATE CREATED: 23/2/95 + + This program extracts a float file of vectors from a text file + of vectors. The float files are easier to process quickly + during VQ training. A subset of the text file VQ may be + extracted to faciltate split VQ of scaler VQ design. + +\*--------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define MAX_STR 256 /* maximum string length */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +void scan_line(FILE *fp, float f[], int n); + +int main(int argc, char *argv[]) { + FILE *ftext; /* text file of vectors */ + FILE *ffloat; /* float file of vectors */ + int st,en; /* start and end values of vector to copy */ + float *buf; /* ptr to vector read from ftext */ + long lines; /* lines read so far */ + + if (argc != 5) { + printf("usage: extract TextFile FloatFile start end\n"); + exit(0); + } + + /* read command line arguments and open files */ + + ftext = fopen(argv[1],"rt"); + if (ftext == NULL) { + printf("Error opening text file: %s\n",argv[1]); + exit(1); + } + + ffloat = fopen(argv[2],"wb"); + if (ffloat == NULL) { + printf("Error opening float file: %s\n",argv[2]); + exit(1); + } + + st = atoi(argv[3]); + en = atoi(argv[4]); + + buf = (float*)malloc(en*sizeof(float)); + if (buf == NULL) { + printf("Error in malloc()\n"); + exit(1); + } + + lines = 0; + while(!feof(ftext)) { + scan_line(ftext, buf, en); + fwrite(&buf[st-1], sizeof(float), en-st+1, ffloat); + printf("\r%ld lines",lines++); + } + printf("\n"); + + /* clean up and exit */ + + free(buf); + fclose(ftext); + fclose(ffloat); + + return 0; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: scan_line() + + AUTHOR......: David Rowe + DATE CREATED: 20/2/95 + + This function reads a vector of floats from a line in a text file. + +\*---------------------------------------------------------------------------*/ + +void scan_line(FILE *fp, float f[], int n) +/* FILE *fp; file ptr to text file */ +/* float f[]; array of floats to return */ +/* int n; number of floats in line */ +{ + char s[MAX_STR]; + char *ps,*pe; + int i; + + fgets(s,MAX_STR,fp); + ps = pe = s; + for(i=0; i<n; i++) { + while( isspace(*pe)) pe++; + while( !isspace(*pe)) pe++; + sscanf(ps,"%f",&f[i]); + ps = pe; + } +} + diff --git a/libs/libcodec2/unittest/genlsp.c b/libs/libcodec2/unittest/genlsp.c new file mode 100644 index 0000000000..8340e2fe16 --- /dev/null +++ b/libs/libcodec2/unittest/genlsp.c @@ -0,0 +1,149 @@ +/*--------------------------------------------------------------------------*\ + + FILE........: genlsp.c + AUTHOR......: David Rowe + DATE CREATED: 23/2/95 + + This program genrates a text file of LSP vectors from an input + speech file. + +\*--------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define P 10 /* LP order */ +#define LSP_DELTA1 0.05 /* grid spacing for LSP root searches */ +#define NW 279 /* frame size in samples */ +#define N 80 /* frame to frame shift */ +#define THRESH 40.0 /* threshold energy/sample for frame inclusion */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "lpc.h" /* LPC analysis functions */ +#include "lsp.h" /* LSP encode/decode functions */ + +int switch_present(sw,argc,argv) + char sw[]; /* switch in string form */ + int argc; /* number of command line arguments */ + char *argv[]; /* array of command line arguments in string form */ +{ + int i; /* loop variable */ + + for(i=1; i<argc; i++) + if (!strcmp(sw,argv[i])) + return(i); + + return 0; +} + +int main(int argc, char *argv[]) { + FILE *fspc; /* input file ptr for test database */ + FILE *flsp; /* output text file of LSPs */ + short buf[N]; /* input frame of speech samples */ + float Sn[NW]; /* float input speech samples */ + float ak[P+1]; /* LPCs for current frame */ + float lsp[P]; /* LSPs for current frame */ + float E; /* frame energy */ + long af; /* number frames with "active" speech */ + float Eres; /* LPC residual energy */ + int i; + int roots; + int unstables; + int lspd; + + /* Initialise ------------------------------------------------------*/ + + if (argc < 3) { + printf("usage: gentest RawFile LSPTextFile [--lspd]\n"); + exit(0); + } + + /* Open files */ + + fspc = fopen(argv[1],"rb"); + if (fspc == NULL) { + printf("Error opening input SPC file: %s",argv[1]); + exit(1); + } + + flsp = fopen(argv[2],"wt"); + if (flsp == NULL) { + printf("Error opening output LSP file: %s",argv[2]); + exit(1); + } + + lspd = switch_present("--lspd", argc, argv); + + for(i=0; i<NW; i++) + Sn[i] = 0.0; + + /* Read SPC file, and determine aks[] for each frame ------------------*/ + + af = 0; + unstables = 0; + while(fread(buf,sizeof(short),N,fspc) == N) { + + for(i=0; i<NW-N; i++) + Sn[i] = Sn[i+N]; + E = 0.0; + for(i=0; i<N; i++) { + Sn[i+NW-N] = buf[i]; + E += Sn[i]*Sn[i]; + } + + E = 0.0; + for(i=0; i<NW; i++) { + E += Sn[i]*Sn[i]; + } + E = 10.0*log10(E/NW); + + /* If energy high enough, include this frame */ + + if (E > THRESH) { + af++; + printf("Active Frame: %ld unstables: %d\n",af, unstables); + + find_aks(Sn, ak, NW, P, &Eres); + roots = lpc_to_lsp(&ak[1], P , lsp, 5, LSP_DELTA1); + if (roots == P) { + if (lspd) { + fprintf(flsp,"%f ",lsp[0]); + for(i=1; i<P; i++) + fprintf(flsp,"%f ",lsp[i]-lsp[i-1]); + fprintf(flsp,"\n"); + } + else { + for(i=0; i<P; i++) + fprintf(flsp,"%f ",lsp[i]); + fprintf(flsp,"\n"); + } + } + else + unstables++; + } + } + + fclose(fspc); + fclose(flsp); + + return 0; +} + diff --git a/libs/libcodec2/unittest/genres.c b/libs/libcodec2/unittest/genres.c new file mode 100644 index 0000000000..8e5a266e82 --- /dev/null +++ b/libs/libcodec2/unittest/genres.c @@ -0,0 +1,92 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: genres.c + AUTHOR......: David Rowe + DATE CREATED: 24/8/09 + + Generates a file of LPC residual samples from original speech. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <lpc.h> + +#define N 160 +#define P 10 + +int main(int argc, char *argv[]) +{ + FILE *fin,*fres; /* input and output files */ + short buf[N]; /* buffer of 16 bit speech samples */ + float Sn[P+N]; /* input speech samples */ + float res[N]; /* residual after LPC filtering */ + float E; + float ak[P+1]; /* LP coeffs */ + + int frames; /* frames processed so far */ + int i; /* loop variables */ + + if (argc < 3) { + printf("usage: %s InputFile ResidualFile\n", argv[0]); + exit(0); + } + + /* Open files */ + + if ((fin = fopen(argv[1],"rb")) == NULL) { + printf("Error opening input file: %s\n",argv[1]); + exit(0); + } + + if ((fres = fopen(argv[2],"wb")) == NULL) { + printf("Error opening output residual file: %s\n",argv[2]); + exit(0); + } + + /* Initialise */ + + frames = 0; + for(i=0; i<P; i++) { + Sn[i] = 0.0; + } + + /* Main loop */ + + while( (fread(buf,sizeof(short),N,fin)) == N) { + frames++; + for(i=0; i<N; i++) + Sn[P+i] = (float)buf[i]; + + /* Determine {ak} and filter to find residual */ + + find_aks(&Sn[P], ak, N, P, &E); + inverse_filter(&Sn[P], ak, N, res, P); + for(i=0; i<N; i++) + buf[i] = (short)res[i]; + fwrite(buf,sizeof(short),N,fres); + } + + fclose(fin); + fclose(fres); + + return 0; +} diff --git a/libs/libcodec2/unittest/lsp1.txt b/libs/libcodec2/unittest/lsp1.txt new file mode 100644 index 0000000000..88995dea09 --- /dev/null +++ b/libs/libcodec2/unittest/lsp1.txt @@ -0,0 +1,16 @@ +225 +250 +275 +300 +325 +350 +375 +400 +425 +450 +475 +500 +525 +550 +575 +600 diff --git a/libs/libcodec2/unittest/lsp10.txt b/libs/libcodec2/unittest/lsp10.txt new file mode 100644 index 0000000000..1f1129b8f1 --- /dev/null +++ b/libs/libcodec2/unittest/lsp10.txt @@ -0,0 +1,5 @@ +2900 +3100 +3300 +3500 + diff --git a/libs/libcodec2/unittest/lsp2.txt b/libs/libcodec2/unittest/lsp2.txt new file mode 100644 index 0000000000..a5d9860b96 --- /dev/null +++ b/libs/libcodec2/unittest/lsp2.txt @@ -0,0 +1,16 @@ +325 +350 +375 +400 +425 +450 +475 +500 +525 +550 +575 +600 +625 +650 +675 +700 diff --git a/libs/libcodec2/unittest/lsp3.txt b/libs/libcodec2/unittest/lsp3.txt new file mode 100644 index 0000000000..6fde10c878 --- /dev/null +++ b/libs/libcodec2/unittest/lsp3.txt @@ -0,0 +1,16 @@ +500 +550 +600 +650 +700 +750 +800 +850 +900 +950 +1000 +1050 +1100 +1150 +1200 +1250 diff --git a/libs/libcodec2/unittest/lsp4.txt b/libs/libcodec2/unittest/lsp4.txt new file mode 100644 index 0000000000..7eae7f8b4d --- /dev/null +++ b/libs/libcodec2/unittest/lsp4.txt @@ -0,0 +1,16 @@ +700 +800 +900 +1000 +1100 +1200 +1300 +1400 +1500 +1600 +1700 +1800 +1900 +2000 +2100 +2200 diff --git a/libs/libcodec2/unittest/lsp5.txt b/libs/libcodec2/unittest/lsp5.txt new file mode 100644 index 0000000000..05d72210ac --- /dev/null +++ b/libs/libcodec2/unittest/lsp5.txt @@ -0,0 +1,18 @@ + 950 +1050 +1150 +1250 +1350 +1450 +1550 +1650 +1750 +1850 +1950 +2050 +2150 +2250 +2350 +2450 + + diff --git a/libs/libcodec2/unittest/lsp6.txt b/libs/libcodec2/unittest/lsp6.txt new file mode 100644 index 0000000000..d1207ffe85 --- /dev/null +++ b/libs/libcodec2/unittest/lsp6.txt @@ -0,0 +1,18 @@ +1100 +1200 +1300 +1400 +1500 +1600 +1700 +1800 +1900 +2000 +2100 +2200 +2300 +2400 +2500 +2600 + + diff --git a/libs/libcodec2/unittest/lsp7.txt b/libs/libcodec2/unittest/lsp7.txt new file mode 100644 index 0000000000..1f6eaa665b --- /dev/null +++ b/libs/libcodec2/unittest/lsp7.txt @@ -0,0 +1,18 @@ +1500 +1600 +1700 +1800 +1900 +2000 +2100 +2200 +2300 +2400 +2500 +2600 +2700 +2800 +2900 +3000 + + diff --git a/libs/libcodec2/unittest/lsp8.txt b/libs/libcodec2/unittest/lsp8.txt new file mode 100644 index 0000000000..89607c8c01 --- /dev/null +++ b/libs/libcodec2/unittest/lsp8.txt @@ -0,0 +1,10 @@ +2300 +2400 +2500 +2600 +2700 +2800 +2900 +3000 + + diff --git a/libs/libcodec2/unittest/lsp9.txt b/libs/libcodec2/unittest/lsp9.txt new file mode 100644 index 0000000000..82be58c0de --- /dev/null +++ b/libs/libcodec2/unittest/lsp9.txt @@ -0,0 +1,10 @@ +2500 +2600 +2700 +2800 +2900 +3000 +3100 +3200 + + diff --git a/libs/libcodec2/unittest/lspd123.txt b/libs/libcodec2/unittest/lspd123.txt new file mode 100644 index 0000000000..423871c699 --- /dev/null +++ b/libs/libcodec2/unittest/lspd123.txt @@ -0,0 +1,1024 @@ +0.263308 0.108769 0.321376 +0.258448 0.055984 0.230859 +0.266067 0.060719 0.217388 +0.280055 0.057994 0.244228 +0.266912 0.064695 0.265145 +0.271651 0.079610 0.259575 +0.226822 0.156621 0.158998 +0.156949 0.052659 0.212653 +0.166041 0.209329 0.265886 +0.308633 0.053423 0.276948 +0.332112 0.035457 0.286972 +0.339533 0.040123 0.272290 +0.330792 0.023602 0.274813 +0.316456 0.037932 0.249650 +0.287286 0.046071 0.242200 +0.261514 0.049979 0.284344 +0.214376 0.103675 0.338804 +0.188651 0.116868 0.328440 +0.177177 0.072134 0.154176 +0.199766 0.183234 0.706565 +0.350628 0.229826 0.529061 +0.297560 0.045946 0.288017 +0.314602 0.041640 0.200681 +0.348282 0.038714 0.240448 +0.381632 0.043026 0.229469 +0.401854 0.029415 0.202430 +0.408573 0.044563 0.177371 +0.424312 0.067150 0.184192 +0.428423 0.056620 0.165082 +0.443482 0.038789 0.168832 +0.432034 0.046019 0.195869 +0.472514 0.052971 0.175566 +0.445147 0.060539 0.186875 +0.447305 0.043459 0.217896 +0.418837 0.064057 0.224309 +0.394427 0.072473 0.216686 +0.372086 0.031878 0.245392 +0.335537 0.047914 0.232315 +0.307720 0.076985 0.263440 +0.212588 0.199799 0.241274 +0.177978 0.061936 0.419219 +0.184726 0.071514 0.295235 +0.179928 0.120561 0.197113 +0.194093 0.091120 0.307566 +0.238704 0.088264 0.256089 +0.256704 0.056376 0.272029 +0.245826 0.056285 0.221666 +0.252157 0.069875 0.209436 +0.293844 0.058822 0.205688 +0.333145 0.032022 0.198412 +0.374122 0.058501 0.198354 +0.388622 0.055018 0.174356 +0.402915 0.069231 0.171417 +0.409007 0.055048 0.195699 +0.393180 0.068521 0.192734 +0.378148 0.042573 0.211319 +0.364531 0.032711 0.200555 +0.346684 0.053755 0.199507 +0.303076 0.088318 0.231307 +0.308105 0.120302 0.271168 +0.275060 0.183236 0.280609 +0.191607 0.254478 0.333707 +0.415869 0.157513 0.330550 +0.466958 0.126641 0.345873 +0.393315 0.137590 0.278630 +0.367297 0.215695 0.295962 +0.209423 0.343791 0.353190 +0.239247 0.069127 0.351070 +0.219601 0.067725 0.316134 +0.183085 0.108910 0.288046 +0.141405 0.106410 0.374917 +0.340773 0.180383 0.280306 +0.324313 0.206337 0.392025 +0.377497 0.310052 0.251511 +0.369942 0.206976 0.403513 +0.391822 0.165248 0.458238 +0.402392 0.132235 0.391573 +0.363609 0.109018 0.385179 +0.393092 0.150649 0.690282 +0.248424 0.072260 0.403322 +0.258842 0.062838 0.331583 +0.277543 0.023397 0.334487 +0.259767 0.019332 0.283729 +0.277333 0.022787 0.286736 +0.278562 0.034487 0.253401 +0.294439 0.029548 0.223983 +0.306420 0.021466 0.246669 +0.311799 0.029621 0.232167 +0.314573 0.026307 0.211228 +0.322046 0.036979 0.185969 +0.340920 0.051908 0.181885 +0.378651 0.100615 0.150541 +0.362534 0.107177 0.127000 +0.366188 0.118540 0.096115 +0.335906 0.123585 0.100436 +0.289660 0.136844 0.121618 +0.234449 0.115458 0.142944 +0.234687 0.112186 0.213379 +0.218786 0.097113 0.246862 +0.230751 0.090415 0.225856 +0.249914 0.071568 0.228974 +0.239316 0.089091 0.205158 +0.235823 0.092666 0.179934 +0.260464 0.077785 0.193877 +0.245534 0.073180 0.169632 +0.285464 0.081401 0.206102 +0.272122 0.072806 0.177335 +0.256928 0.066768 0.151148 +0.259615 0.074334 0.119038 +0.285004 0.089415 0.117455 +0.326626 0.085390 0.097219 +0.322959 0.072295 0.114366 +0.342931 0.060610 0.112868 +0.349890 0.057216 0.138586 +0.347363 0.058881 0.164623 +0.358032 0.064472 0.175272 +0.357807 0.072462 0.156002 +0.336895 0.066119 0.134206 +0.337276 0.073707 0.151129 +0.326144 0.057722 0.152109 +0.287242 0.055461 0.172280 +0.233531 0.070892 0.220511 +0.247128 0.049358 0.274502 +0.224586 0.046013 0.357086 +0.229675 0.045704 0.405370 +0.272311 0.072851 0.349441 +0.262378 0.048277 0.301490 +0.272410 0.052304 0.234698 +0.296903 0.047644 0.225221 +0.308756 0.052127 0.222936 +0.336122 0.044504 0.193011 +0.365030 0.064659 0.137103 +0.372444 0.036236 0.135129 +0.379957 0.052989 0.104509 +0.395033 0.063805 0.099117 +0.395331 0.016167 0.079401 +0.361374 0.077860 0.067214 +0.366584 0.051942 0.030922 +0.417962 0.076156 0.084209 +0.376593 0.111196 0.068356 +0.321411 0.091882 0.063007 +0.335365 0.070341 0.082301 +0.348707 0.075437 0.099469 +0.292758 0.061200 0.121062 +0.277998 0.061337 0.145208 +0.272000 0.072048 0.230783 +0.206511 0.121757 0.280188 +0.162259 0.031322 0.393199 +0.200906 0.088613 0.124277 +0.184134 0.084894 0.197393 +0.290246 0.077754 0.223919 +0.263962 0.059362 0.091101 +0.317773 0.055238 0.129435 +0.356413 0.042508 0.107483 +0.365057 0.023078 0.085620 +0.411914 0.048078 0.093016 +0.419049 0.030016 0.101357 +0.436160 0.024666 0.066348 +0.436704 0.046967 0.092223 +0.494088 0.068777 0.102742 +0.470076 0.075909 0.074128 +0.451110 0.088014 0.089431 +0.487849 0.092611 0.051933 +0.533716 0.041322 0.035398 +0.457297 0.061196 0.094392 +0.434718 0.062690 0.099115 +0.432830 0.099336 0.064658 +0.445522 0.032508 0.029007 +0.435059 0.064532 0.071763 +0.400424 0.095239 0.052280 +0.394880 0.061922 0.073728 +0.341705 0.050045 0.060238 +0.382169 0.078170 0.085591 +0.375733 0.095367 0.086298 +0.367753 0.093088 0.107387 +0.355679 0.126981 0.119866 +0.183195 0.178369 0.154227 +0.215939 0.281661 0.137611 +0.255382 0.232429 0.090575 +0.294261 0.198828 0.092855 +0.358379 0.158423 0.138468 +0.380219 0.176473 0.110948 +0.305047 0.161007 0.139954 +0.262435 0.236041 0.144567 +0.354204 0.222414 0.107065 +0.345190 0.184018 0.124352 +0.338177 0.204525 0.067254 +0.305092 0.238787 0.094788 +0.351980 0.224928 0.156944 +0.345016 0.185595 0.192659 +0.337844 0.184025 0.160326 +0.359544 0.217341 0.327157 +0.357648 0.230240 0.366907 +0.395642 0.165926 0.261342 +0.343546 0.156618 0.223511 +0.361635 0.096729 0.184236 +0.415440 0.076743 0.154942 +0.431066 0.076513 0.121105 +0.451174 0.082936 0.112437 +0.495682 0.125322 0.083250 +0.457920 0.105206 0.069372 +0.428288 0.096431 0.099719 +0.402112 0.089533 0.102279 +0.374406 0.069315 0.151993 +0.341303 0.072495 0.181235 +0.288181 0.130601 0.149994 +0.437823 0.194847 0.236998 +0.517891 0.162410 0.219232 +0.458004 0.239400 0.097958 +0.500390 0.177654 0.095729 +0.362675 0.278449 0.190598 +0.273868 0.085220 0.143261 +0.337997 0.064583 0.239703 +0.368143 0.045688 0.271347 +0.379949 0.029454 0.196794 +0.353352 0.028491 0.129485 +0.352112 0.017867 0.185794 +0.346936 0.025652 0.201147 +0.313751 0.022409 0.193629 +0.310985 0.028334 0.172877 +0.224772 0.055169 0.272269 +0.241855 0.030040 0.280276 +0.228564 0.021920 0.257200 +0.227718 0.054195 0.234162 +0.238926 0.054818 0.264076 +0.237314 0.075502 0.320709 +0.270880 0.085558 0.331728 +0.256455 0.080580 0.308559 +0.287309 0.097558 0.267753 +0.290763 0.080224 0.284406 +0.283022 0.068509 0.295506 +0.275270 0.069930 0.316990 +0.303843 0.092797 0.344720 +0.295250 0.075062 0.317300 +0.304161 0.067487 0.286738 +0.324174 0.057767 0.264031 +0.327890 0.076403 0.220917 +0.357965 0.072263 0.193322 +0.369869 0.059126 0.176957 +0.380683 0.051077 0.189741 +0.377526 0.045779 0.169338 +0.362044 0.051634 0.203021 +0.349094 0.041532 0.208466 +0.350344 0.021300 0.239499 +0.325966 0.026791 0.230178 +0.322013 0.042984 0.214929 +0.290199 0.049255 0.255248 +0.268860 0.057260 0.292111 +0.254110 0.065897 0.262323 +0.240555 0.081414 0.242131 +0.214107 0.099448 0.291511 +0.227603 0.116971 0.293158 +0.242687 0.099576 0.273347 +0.212057 0.080928 0.206493 +0.216818 0.054102 0.208481 +0.244560 0.059543 0.241185 +0.244893 0.055478 0.253047 +0.252424 0.044367 0.250846 +0.232805 0.046411 0.221492 +0.259503 0.030997 0.257981 +0.258163 0.036285 0.290086 +0.255400 0.060582 0.318764 +0.231850 0.078839 0.288307 +0.236986 0.070470 0.304299 +0.213303 0.073593 0.296093 +0.205272 0.040867 0.334217 +0.186676 0.036373 0.251392 +0.217783 0.043270 0.241924 +0.214511 0.052788 0.255946 +0.208572 0.053861 0.286926 +0.242888 0.106360 0.347276 +0.288960 0.124946 0.201239 +0.342775 0.093960 0.144984 +0.377197 0.085376 0.129922 +0.412166 0.088434 0.132108 +0.390249 0.076679 0.114031 +0.383989 0.062449 0.122055 +0.387523 0.079554 0.156435 +0.379580 0.077513 0.179594 +0.314430 0.087760 0.175421 +0.294579 0.101436 0.212711 +0.307017 0.089327 0.197301 +0.305232 0.075488 0.208874 +0.313937 0.065084 0.223413 +0.318828 0.066585 0.241867 +0.319064 0.044985 0.234334 +0.327293 0.054936 0.224270 +0.313956 0.059037 0.208250 +0.320067 0.067497 0.178744 +0.325844 0.051785 0.249839 +0.291419 0.140846 0.176356 +0.304736 0.257499 0.321206 +0.412538 0.193653 0.527310 +0.464326 0.177155 0.484639 +0.388370 0.247578 0.270502 +0.309708 0.243245 0.219685 +0.267637 0.120670 0.182524 +0.333329 0.064619 0.195862 +0.337853 0.035063 0.182235 +0.363054 0.041039 0.161560 +0.346506 0.045356 0.166242 +0.343175 0.032640 0.168740 +0.329834 0.040738 0.160952 +0.327688 0.025263 0.170543 +0.337286 0.032068 0.148672 +0.352876 0.027518 0.154928 +0.355731 0.040489 0.143599 +0.360021 0.052552 0.125346 +0.379432 0.019637 0.116855 +0.389556 0.033257 0.172091 +0.388615 0.005982 0.167184 +0.380871 0.031560 0.161735 +0.370428 0.034266 0.174805 +0.364127 0.028565 0.187409 +0.354946 0.032953 0.173018 +0.355197 0.019611 0.169606 +0.317361 0.028988 0.147085 +0.272330 0.043511 0.120042 +0.266965 0.057786 0.178702 +0.218195 0.094896 0.158774 +0.210802 0.102337 0.189513 +0.233979 0.076536 0.270353 +0.202083 0.169732 0.380558 +0.239441 0.172991 0.265931 +0.276190 0.226470 0.297090 +0.261790 0.365551 0.166357 +0.291971 0.099794 0.304947 +0.299131 0.063916 0.222310 +0.286582 0.041561 0.230600 +0.291056 0.054960 0.304060 +0.275948 0.057784 0.330696 +0.309766 0.028970 0.340314 +0.294102 0.043690 0.317927 +0.309171 0.030830 0.307374 +0.307411 0.020232 0.279361 +0.330913 0.034844 0.243337 +0.332192 0.027616 0.212354 +0.350338 0.039211 0.192995 +0.354502 0.055994 0.189121 +0.341296 0.073283 0.165587 +0.313181 0.094281 0.118029 +0.258194 0.134394 0.161487 +0.211766 0.110672 0.388399 +0.180619 0.089602 0.393854 +0.207652 0.057423 0.402186 +0.248737 0.121119 0.265945 +0.257647 0.145656 0.128647 +0.273116 0.146530 0.091939 +0.258193 0.186626 0.065391 +0.306617 0.177781 0.064168 +0.347651 0.163069 0.074409 +0.357362 0.133103 0.066344 +0.284876 0.117297 0.059904 +0.329676 0.124514 0.067178 +0.347508 0.100037 0.082550 +0.223342 0.163723 0.106806 +0.242615 0.106352 0.107873 +0.278081 0.104596 0.093439 +0.308805 0.106582 0.092192 +0.299730 0.076828 0.096766 +0.240110 0.112476 0.067117 +0.231410 0.073181 0.088404 +0.187246 0.100727 0.078664 +0.193716 0.126844 0.159078 +0.094366 0.454024 0.291647 +0.440203 0.228612 0.310365 +0.456753 0.186484 0.299839 +0.308520 0.205526 0.313406 +0.228109 0.069024 0.190235 +0.251018 0.045216 0.163280 +0.273421 0.051226 0.164458 +0.293630 0.030524 0.175355 +0.298281 0.027483 0.155763 +0.301235 0.032609 0.127618 +0.295114 0.036459 0.089043 +0.321284 0.052688 0.103598 +0.323611 0.031672 0.118877 +0.338816 0.045778 0.089024 +0.310812 0.060414 0.075229 +0.277050 0.068429 0.061631 +0.331845 0.057911 0.166403 +0.357599 0.078369 0.229133 +0.267510 0.109542 0.134427 +0.288685 0.206571 0.249532 +0.359999 0.229179 0.199289 +0.400078 0.178102 0.233727 +0.416741 0.100494 0.304150 +0.427570 0.154323 0.369992 +0.256414 0.275755 0.244236 +0.175186 0.345607 0.170933 +0.324895 0.207437 0.260709 +0.314928 0.217055 0.179225 +0.375454 0.184067 0.158251 +0.461676 0.155360 0.119282 +0.421915 0.134009 0.232978 +0.373661 0.177682 0.207681 +0.135194 0.242891 0.321398 +0.321335 0.077009 0.197895 +0.338990 0.031707 0.225496 +0.324230 0.087363 0.236806 +0.270364 0.162874 0.154703 +0.241859 0.198105 0.177328 +0.257345 0.254782 0.195962 +0.199872 0.236295 0.186694 +0.245869 0.190731 0.141457 +0.335308 0.137010 0.136606 +0.408226 0.106606 0.149159 +0.428609 0.091994 0.166467 +0.472127 0.089046 0.165746 +0.498132 0.086762 0.208918 +0.481551 0.029402 0.264176 +0.482803 0.039294 0.214899 +0.446093 0.026027 0.128251 +0.407029 0.046922 0.066767 +0.365305 0.060238 0.090360 +0.383768 0.048819 0.140115 +0.370504 0.054257 0.143952 +0.358656 0.050846 0.152415 +0.343721 0.051667 0.150554 +0.352689 0.037849 0.181895 +0.387896 0.023860 0.226017 +0.385152 0.026671 0.273998 +0.389716 0.042722 0.253226 +0.390426 0.060857 0.236081 +0.391309 0.070621 0.271022 +0.365299 0.052628 0.227580 +0.349302 0.056899 0.217929 +0.334019 0.044267 0.204909 +0.322675 0.052532 0.195847 +0.331578 0.059559 0.211188 +0.337346 0.044211 0.217457 +0.349988 0.042267 0.223684 +0.349544 0.052704 0.234279 +0.362448 0.055041 0.249180 +0.361727 0.044749 0.216369 +0.348153 0.069352 0.209682 +0.337217 0.045887 0.252731 +0.331050 0.046309 0.303014 +0.315984 0.081682 0.302052 +0.284402 0.070739 0.237853 +0.160928 0.095527 0.301120 +0.243864 0.253123 0.323982 +0.277572 0.092148 0.227598 +0.287300 0.089141 0.248731 +0.266347 0.080300 0.293693 +0.251289 0.087932 0.356317 +0.229821 0.046012 0.383514 +0.211823 0.052236 0.376683 +0.227721 0.066729 0.381682 +0.211191 0.099568 0.361644 +0.250163 0.058192 0.302916 +0.238782 0.062404 0.276585 +0.226470 0.067801 0.245403 +0.201436 0.085254 0.282160 +0.219802 0.088189 0.275429 +0.195729 0.096373 0.259539 +0.239596 0.069924 0.258877 +0.252931 0.058961 0.285795 +0.198265 0.083733 0.337224 +0.154613 0.036968 0.351381 +0.177337 0.021450 0.364380 +0.179088 0.025299 0.334012 +0.159295 0.027232 0.308317 +0.188645 0.046948 0.354951 +0.239592 0.093448 0.325226 +0.260247 0.055024 0.254124 +0.271796 0.061114 0.279167 +0.277210 0.043283 0.292067 +0.285919 0.056460 0.283294 +0.294039 0.048722 0.271710 +0.284689 0.041537 0.264456 +0.295141 0.036382 0.263883 +0.297060 0.034184 0.245546 +0.293229 0.029850 0.279750 +0.281186 0.022593 0.265907 +0.277293 0.025365 0.243586 +0.258324 0.031845 0.190247 +0.259675 0.040360 0.270911 +0.247039 0.037888 0.299431 +0.208028 0.109870 0.417382 +0.143955 0.352665 0.276035 +0.219494 0.404511 0.278305 +0.352442 0.182051 0.309356 +0.405915 0.135088 0.307030 +0.369146 0.162615 0.410960 +0.433703 0.099514 0.369783 +0.285682 0.219583 0.351837 +0.205221 0.076512 0.429524 +0.209111 0.064178 0.357358 +0.213614 0.027846 0.368032 +0.211762 0.020177 0.348034 +0.239715 0.025079 0.308549 +0.181970 0.021514 0.274842 +0.207709 0.021261 0.265212 +0.224222 0.023951 0.292046 +0.205208 0.035452 0.292259 +0.228577 0.040117 0.304294 +0.185628 0.027511 0.302807 +0.208356 0.024577 0.316996 +0.164632 0.053682 0.299398 +0.154684 0.059791 0.276709 +0.163141 0.113219 0.252962 +0.145021 0.179019 0.408733 +0.214761 0.213412 0.297524 +0.308714 0.266575 0.390462 +0.419920 0.278106 0.288387 +0.436034 0.199545 0.357313 +0.451619 0.349524 0.419884 +0.351454 0.399809 0.460027 +0.360729 0.263047 0.612763 +0.418659 0.158631 0.284739 +0.456406 0.261108 0.373714 +0.424203 0.185874 0.316636 +0.400414 0.220266 0.453220 +0.368427 0.288074 0.412510 +0.343373 0.311195 0.490064 +0.395724 0.120734 0.436366 +0.344054 0.121619 0.347531 +0.272067 0.060489 0.198795 +0.301511 0.071935 0.185958 +0.309917 0.058524 0.190423 +0.300737 0.068082 0.171283 +0.295951 0.070752 0.150988 +0.296628 0.093980 0.139509 +0.302790 0.088637 0.162273 +0.289209 0.107492 0.167687 +0.257493 0.099688 0.159880 +0.265074 0.094624 0.181755 +0.266152 0.102270 0.207499 +0.269178 0.081363 0.277388 +0.234937 0.089620 0.382405 +0.183980 0.071956 0.466773 +0.219287 0.038089 0.431341 +0.202243 0.025685 0.466386 +0.158633 0.040859 0.449110 +0.165286 0.038598 0.497265 +0.170922 0.081097 0.523174 +0.255371 0.073482 0.249855 +0.294450 0.061848 0.264223 +0.304183 0.048479 0.179739 +0.310850 0.055590 0.165979 +0.311457 0.049670 0.147335 +0.330971 0.043725 0.142906 +0.338014 0.047764 0.127744 +0.367458 0.069305 0.112055 +0.365012 0.080855 0.169084 +0.360471 0.123986 0.145022 +0.219106 0.213898 0.129019 +0.206939 0.158987 0.242265 +0.246130 0.209339 0.215908 +0.281650 0.212707 0.204391 +0.368421 0.137607 0.310718 +0.416555 0.186663 0.125862 +0.490086 0.115875 0.145587 +0.582071 0.084161 0.206439 +0.516409 0.100131 0.260412 +0.209178 0.109586 0.221433 +0.269122 0.077905 0.211916 +0.300134 0.057524 0.238951 +0.303992 0.045603 0.260036 +0.322399 0.041910 0.267995 +0.316911 0.039992 0.287154 +0.327515 0.024597 0.301819 +0.326525 0.038109 0.322430 +0.341705 0.034554 0.344489 +0.315359 0.057607 0.326479 +0.311192 0.052833 0.302654 +0.297687 0.053640 0.333832 +0.310295 0.070962 0.376051 +0.287143 0.033181 0.414809 +0.248935 0.044304 0.319914 +0.246203 0.096450 0.292594 +0.203226 0.299903 0.287677 +0.450787 0.226937 0.192194 +0.429364 0.129302 0.269024 +0.457446 0.111038 0.290750 +0.498339 0.083336 0.319890 +0.424246 0.121867 0.333939 +0.180169 0.212830 0.368602 +0.241118 0.059711 0.365439 +0.224747 0.101688 0.488165 +0.246281 0.034903 0.465119 +0.214101 0.041638 0.545771 +0.172272 0.040285 0.598901 +0.204244 0.073643 0.382078 +0.146978 0.063294 0.389213 +0.382561 0.211691 0.242082 +0.362189 0.175671 0.247243 +0.318033 0.195181 0.218764 +0.318069 0.292363 0.228042 +0.255232 0.340570 0.247263 +0.224048 0.079338 0.358775 +0.236448 0.054617 0.310908 +0.239437 0.046635 0.344813 +0.243703 0.031212 0.389996 +0.226767 0.019507 0.406603 +0.238177 0.018267 0.376086 +0.218586 0.029858 0.389601 +0.197366 0.025585 0.402150 +0.181994 0.030716 0.427478 +0.190316 0.080557 0.359194 +0.190657 0.107271 0.458600 +0.155050 0.289997 0.417618 +0.187166 0.466579 0.426216 +0.327820 0.426769 0.326883 +0.298164 0.333603 0.351558 +0.222925 0.307747 0.580913 +0.198007 0.195365 0.578080 +0.210838 0.132715 0.542845 +0.231681 0.145101 0.436671 +0.232264 0.139358 0.387084 +0.255424 0.134975 0.350235 +0.269033 0.107837 0.261451 +0.321432 0.091599 0.275752 +0.380638 0.048055 0.299763 +0.405177 0.039883 0.236148 +0.423159 0.034218 0.181764 +0.453693 0.035502 0.198420 +0.464601 0.056361 0.119659 +0.481653 0.094843 0.109332 +0.543887 0.077760 0.119617 +0.510174 0.067882 0.146075 +0.506307 0.045510 0.174226 +0.488336 0.037550 0.110817 +0.414503 0.071944 0.106334 +0.383441 0.044148 0.118702 +0.368264 0.023699 0.150335 +0.307715 0.072824 0.135304 +0.294683 0.031017 0.196791 +0.275515 0.032364 0.181864 +0.235271 0.050178 0.178346 +0.215182 0.042335 0.185990 +0.209160 0.034271 0.223795 +0.228156 0.042936 0.260040 +0.223438 0.035509 0.277441 +0.180634 0.048455 0.281545 +0.197426 0.043630 0.273470 +0.205039 0.042828 0.313134 +0.223919 0.042287 0.320436 +0.223789 0.049071 0.285841 +0.214087 0.074972 0.257980 +0.221706 0.055601 0.498696 +0.248886 0.066833 0.445954 +0.213931 0.250226 0.256738 +0.405740 0.215131 0.170840 +0.328009 0.225653 0.293796 +0.402298 0.209079 0.214184 +0.399981 0.190690 0.264499 +0.363176 0.143635 0.492934 +0.411671 0.175359 0.406973 +0.483187 0.170802 0.394002 +0.431046 0.230553 0.250015 +0.389736 0.164181 0.297007 +0.397937 0.264402 0.341441 +0.395597 0.192289 0.302742 +0.343285 0.064916 0.354126 +0.350910 0.048799 0.290592 +0.347107 0.053302 0.266173 +0.361248 0.035141 0.231596 +0.353263 0.036751 0.257156 +0.332918 0.021247 0.255062 +0.360739 0.026445 0.281881 +0.367061 0.033022 0.325980 +0.350245 0.030285 0.303678 +0.327460 0.062073 0.283904 +0.264953 0.154809 0.315348 +0.324552 0.162784 0.438341 +0.429845 0.118138 0.486718 +0.437485 0.201399 0.415841 +0.427985 0.188146 0.278007 +0.298482 0.166884 0.350707 +0.267071 0.100408 0.291668 +0.274139 0.048797 0.268746 +0.281772 0.064356 0.267733 +0.214424 0.106076 0.312509 +0.331917 0.145161 0.280800 +0.354727 0.078392 0.279286 +0.371871 0.063102 0.214163 +0.396773 0.045559 0.209831 +0.421855 0.036944 0.214993 +0.420483 0.038557 0.160983 +0.436158 0.046191 0.146786 +0.453173 0.052302 0.137395 +0.481122 0.055096 0.145895 +0.465610 0.080732 0.136565 +0.449280 0.063650 0.159070 +0.438899 0.073552 0.140745 +0.432289 0.052628 0.119653 +0.420075 0.055923 0.142166 +0.415632 0.042002 0.128100 +0.412222 0.024997 0.139031 +0.391770 0.036632 0.146635 +0.393909 0.035907 0.188207 +0.368782 0.042784 0.188583 +0.363114 0.026468 0.218028 +0.375379 0.033356 0.364183 +0.345201 0.072563 0.316474 +0.306150 0.169779 0.294978 +0.484261 0.214170 0.267057 +0.406809 0.237896 0.384323 +0.392655 0.344627 0.332547 +0.326695 0.369933 0.207731 +0.407366 0.219126 0.278777 +0.398951 0.222770 0.323388 +0.464580 0.171047 0.338723 +0.397575 0.158165 0.591424 +0.420764 0.281705 0.506598 +0.473997 0.277563 0.218714 +0.336638 0.220260 0.461195 +0.342381 0.160051 0.377158 +0.246975 0.040158 0.263418 +0.239553 0.054919 0.205493 +0.252654 0.036861 0.224388 +0.253305 0.022395 0.239997 +0.271057 0.036266 0.237408 +0.273993 0.028386 0.214558 +0.242393 0.034220 0.204126 +0.236256 0.038163 0.247591 +0.209356 0.079325 0.234462 +0.194870 0.063640 0.214830 +0.244111 0.043255 0.236907 +0.264016 0.045660 0.223915 +0.260253 0.048634 0.207679 +0.251574 0.057245 0.189983 +0.263437 0.063508 0.241134 +0.271436 0.069219 0.251311 +0.261483 0.087406 0.246475 +0.250589 0.076269 0.277050 +0.244799 0.069765 0.292298 +0.232217 0.055247 0.331780 +0.216197 0.056278 0.342299 +0.176402 0.053897 0.380149 +0.224991 0.078406 0.337659 +0.231780 0.062395 0.422354 +0.189766 0.154959 0.437237 +0.204459 0.136309 0.307237 +0.260264 0.045977 0.240046 +0.269789 0.046212 0.252599 +0.274164 0.035012 0.302447 +0.230060 0.090744 0.305382 +0.166096 0.140832 0.294885 +0.154169 0.268532 0.226818 +0.349563 0.262265 0.343630 +0.354489 0.268911 0.296625 +0.375822 0.171148 0.332545 +0.476794 0.136744 0.259507 +0.399929 0.118339 0.259498 +0.271716 0.130588 0.469224 +0.305172 0.032898 0.454218 +0.308690 0.042473 0.417566 +0.288698 0.024952 0.300569 +0.290810 0.015293 0.221283 +0.268986 0.033267 0.147285 +0.237334 0.048825 0.120734 +0.228777 0.055634 0.150103 +0.204334 0.073034 0.174915 +0.208027 0.057339 0.236310 +0.198897 0.066784 0.271433 +0.202506 0.057603 0.300680 +0.222788 0.058041 0.300819 +0.233042 0.055613 0.290225 +0.246512 0.042508 0.284706 +0.260946 0.032017 0.314281 +0.280743 0.031362 0.358053 +0.305375 0.031854 0.387510 +0.269256 0.025479 0.381275 +0.245952 0.040037 0.364854 +0.268189 0.040204 0.323075 +0.275163 0.050477 0.311422 +0.265688 0.064899 0.301225 +0.239306 0.268505 0.378907 +0.312398 0.266259 0.164624 +0.480542 0.174554 0.171654 +0.552172 0.158933 0.144993 +0.458784 0.141655 0.212248 +0.428648 0.163482 0.164911 +0.350278 0.208056 0.235462 +0.359219 0.250780 0.234338 +0.336572 0.248935 0.259563 +0.293959 0.257267 0.267935 +0.238555 0.202335 0.370163 +0.245646 0.069245 0.336645 +0.261452 0.055228 0.352020 +0.268939 0.054326 0.369767 +0.286819 0.048101 0.382083 +0.271280 0.052949 0.401336 +0.248193 0.051118 0.385676 +0.239973 0.026597 0.429200 +0.214644 0.060995 0.454583 +0.220676 0.083808 0.406302 +0.250805 0.126260 0.297366 +0.334644 0.192200 0.346535 +0.381125 0.159560 0.367527 +0.340438 0.157087 0.328361 +0.277244 0.160062 0.390717 +0.292870 0.052195 0.355769 +0.345623 0.035855 0.396258 +0.374273 0.031225 0.447159 +0.276809 0.033552 0.581647 +0.224359 0.099923 0.647568 +0.333303 0.049949 0.516785 +0.312970 0.123739 0.396509 +0.238621 0.146067 0.231297 +0.165305 0.049204 0.329040 +0.278324 0.199829 0.426235 +0.253210 0.337113 0.436856 +0.206203 0.578084 0.277516 +0.309249 0.169748 0.538897 +0.332333 0.091215 0.435451 +0.279107 0.030067 0.502383 +0.259234 0.086196 0.546189 +0.267603 0.068953 0.484586 +0.265845 0.064849 0.423640 +0.281793 0.086538 0.401598 +0.264889 0.079521 0.377251 +0.266400 0.115068 0.375961 +0.205215 0.130153 0.360079 +0.229061 0.160330 0.306438 +0.189984 0.185082 0.324728 +0.229945 0.128947 0.326026 +0.253837 0.089731 0.266618 +0.255704 0.088487 0.224765 +0.286792 0.092177 0.188518 +0.320841 0.097300 0.214002 +0.333689 0.106637 0.185748 +0.333838 0.086680 0.174199 +0.319590 0.093878 0.148540 +0.340092 0.115413 0.159425 +0.351543 0.092448 0.163319 +0.342527 0.091358 0.203951 +0.331816 0.119469 0.305761 +0.280244 0.128802 0.290044 +0.304101 0.105074 0.248131 +0.338603 0.080077 0.255476 +0.309197 0.057247 0.254671 +0.300156 0.070286 0.244369 +0.286353 0.065888 0.254045 +0.258600 0.108479 0.234651 +0.224997 0.109225 0.266261 +0.195413 0.126245 0.250545 +0.281750 0.062811 0.213758 +0.303917 0.051829 0.203332 +0.317902 0.072075 0.155470 +0.327787 0.081576 0.130690 +0.355867 0.073091 0.127604 +0.358901 0.085628 0.142860 +0.347105 0.087525 0.122878 +0.333158 0.110155 0.130534 +0.305063 0.115625 0.125246 +0.311381 0.117013 0.156404 +0.308163 0.112438 0.188106 +0.269326 0.130721 0.245640 +0.216982 0.085835 0.320106 +0.212607 0.057787 0.321804 +0.198387 0.073638 0.315780 +0.186044 0.054189 0.321956 +0.163325 0.054977 0.246522 +0.182868 0.034089 0.225316 +0.180488 0.047224 0.190814 +0.157011 0.029435 0.267719 +0.233375 0.081439 0.132706 +0.274801 0.044742 0.195953 +0.306673 0.028692 0.261583 +0.305705 0.037574 0.221126 +0.303135 0.045524 0.239984 +0.282405 0.040832 0.282276 +0.283758 0.040311 0.339897 +0.234144 0.030246 0.331245 +0.216669 0.066311 0.278480 +0.190170 0.097245 0.230782 +0.168054 0.072931 0.353984 +0.179260 0.077851 0.328143 +0.174966 0.076302 0.231521 +0.175667 0.078095 0.272008 +0.189384 0.067503 0.247983 +0.214139 0.046101 0.272932 +0.233914 0.045467 0.277783 +0.244588 0.049198 0.296792 +0.256730 0.043153 0.334920 +0.257759 0.032742 0.347498 +0.285465 0.026853 0.316266 +0.271270 0.033933 0.272250 +0.276680 0.045231 0.220594 +0.288564 0.042172 0.209508 +0.292675 0.047892 0.190494 +0.308407 0.037952 0.274706 +0.318522 0.038643 0.364714 +0.247803 0.111933 0.190722 +0.233404 0.144416 0.275805 +0.249166 0.193532 0.320038 +0.310797 0.319086 0.285728 +0.360867 0.217696 0.267229 +0.373286 0.186187 0.279616 +0.387949 0.127631 0.343667 +0.415183 0.073517 0.405553 +0.454532 0.127629 0.417735 +0.448768 0.149562 0.299421 +0.512886 0.163940 0.302645 +0.392881 0.193813 0.357648 +0.261675 0.259539 0.466201 +0.234490 0.096500 0.443213 +0.258238 0.062531 0.385246 +0.260465 0.035885 0.401811 +0.261667 0.036601 0.432964 +0.281564 0.058277 0.447718 +0.247830 0.105619 0.413321 +0.195343 0.165737 0.277588 +0.216014 0.219408 0.421047 +0.169087 0.221263 0.482537 +0.227429 0.183042 0.484872 +0.260935 0.291958 0.298961 +0.224112 0.158830 0.343758 +0.284726 0.056334 0.226615 +0.294599 0.051973 0.149180 +0.325047 0.051628 0.179937 +0.356402 0.049165 0.175911 +0.376165 0.058355 0.163522 +0.397813 0.057225 0.144147 +0.393141 0.044994 0.129534 +0.402884 0.044005 0.110816 +0.407746 0.063560 0.121868 +0.403282 0.071499 0.138498 +0.406901 0.052769 0.156323 +0.400491 0.038429 0.161151 +0.391847 0.058654 0.157748 +0.385015 0.067309 0.137188 +0.377336 0.045050 0.152108 +0.362722 0.055345 0.162513 +0.315826 0.042890 0.168139 +0.283083 0.080878 0.165981 +0.285489 0.067464 0.191727 +0.145248 0.070726 0.324069 +0.399799 0.255914 0.214022 +0.429920 0.159068 0.250011 +0.439445 0.183575 0.202417 +0.398499 0.258210 0.143533 +0.465245 0.169443 0.256422 +0.422318 0.358987 0.185421 +0.253220 0.222325 0.265472 +0.210594 0.307630 0.214541 +0.175040 0.446152 0.193737 +0.226217 0.379009 0.100408 +0.340833 0.306077 0.113355 +0.265242 0.294847 0.105075 +0.276714 0.304171 0.186038 +0.390551 0.100132 0.539154 +0.297133 0.125853 0.333330 +0.196927 0.178243 0.197378 +0.257580 0.128441 0.214041 +0.229792 0.130115 0.182553 +0.170106 0.162513 0.231148 +0.164595 0.106934 0.342563 +0.175852 0.127587 0.392165 +0.157779 0.134743 0.489792 +0.152201 0.097943 0.432539 +0.162413 0.153705 0.347737 +0.277299 0.150900 0.266126 +0.266806 0.172668 0.234574 +0.318579 0.167283 0.249262 +0.347916 0.107363 0.231007 +0.372857 0.090140 0.210306 +0.384342 0.113638 0.196678 +0.404131 0.095394 0.183804 +0.384612 0.121810 0.167672 +0.322944 0.132564 0.210257 +0.290364 0.146204 0.223432 +0.264192 0.157656 0.193948 +0.233485 0.163743 0.200412 +0.207187 0.138320 0.212342 +0.225556 0.124901 0.244775 +0.239106 0.105732 0.239571 +0.287733 0.114294 0.228538 +0.340176 0.100254 0.107080 +0.389066 0.103998 0.122846 +0.444975 0.102241 0.133970 +0.415860 0.114565 0.114926 +0.453877 0.120214 0.107920 +0.403927 0.096306 0.080457 +0.421740 0.122693 0.079588 +0.450640 0.144936 0.071884 +0.393762 0.136866 0.060204 +0.381369 0.180962 0.064094 +0.417859 0.160286 0.072990 +0.381221 0.146156 0.087738 +0.393977 0.119086 0.094996 +0.414356 0.146006 0.109031 +0.435031 0.134052 0.138616 +0.396483 0.123711 0.134754 +0.382302 0.141141 0.123735 +0.353663 0.145826 0.104587 +0.332036 0.171052 0.104051 +0.311513 0.199338 0.131723 +0.285181 0.190876 0.163180 +0.274455 0.184371 0.123920 +0.301600 0.169794 0.109397 +0.311406 0.141832 0.086234 +0.321738 0.140580 0.119486 +0.327427 0.145551 0.158359 +0.310737 0.168048 0.174012 +0.297873 0.175289 0.197738 +0.319909 0.123865 0.237833 +0.344952 0.122697 0.263042 +0.371611 0.111286 0.281178 +0.378247 0.099648 0.307710 +0.394570 0.079100 0.338162 +0.416351 0.038242 0.333196 +0.417830 0.042111 0.293185 +0.430829 0.039852 0.251519 +0.427375 0.079094 0.261696 +0.452757 0.101221 0.232921 +0.431060 0.088368 0.204739 +0.384616 0.086474 0.244279 +0.416919 0.124304 0.189584 +0.448928 0.116694 0.166079 +0.402548 0.157029 0.204021 +0.405248 0.099612 0.223420 +0.394667 0.126257 0.226234 +0.393587 0.155514 0.157489 +0.388278 0.150483 0.241885 +0.363290 0.151279 0.275569 +0.369461 0.131040 0.246673 +0.365592 0.135952 0.213237 +0.355959 0.141295 0.179707 +0.320616 0.134892 0.181918 diff --git a/libs/libcodec2/unittest/lspd456.txt b/libs/libcodec2/unittest/lspd456.txt new file mode 100644 index 0000000000..4cc5ab8fcd --- /dev/null +++ b/libs/libcodec2/unittest/lspd456.txt @@ -0,0 +1,1024 @@ +0.347624 0.090959 0.454834 +0.446215 0.124000 0.370817 +0.409839 0.143155 0.295004 +0.440759 0.090281 0.296885 +0.465214 0.048451 0.542712 +0.471598 0.086037 0.483358 +0.372213 0.179217 0.438123 +0.592442 0.166741 0.433982 +0.399563 0.151320 0.400160 +0.479513 0.108517 0.258405 +0.485953 0.066923 0.193914 +0.548002 0.077271 0.152336 +0.565599 0.143205 0.140294 +0.558550 0.201462 0.109620 +0.607051 0.211633 0.152670 +0.670273 0.190261 0.139432 +0.430187 0.478301 0.135903 +0.148336 0.680821 0.114594 +0.185120 0.925628 0.147625 +0.249453 0.196637 0.241588 +0.179636 0.162617 0.313756 +0.586115 0.159387 0.307418 +0.472213 0.142351 0.245426 +0.384650 0.125831 0.240183 +0.332192 0.095235 0.255403 +0.300937 0.083633 0.239104 +0.282901 0.084036 0.324663 +0.264823 0.053630 0.355336 +0.262817 0.057144 0.308867 +0.235162 0.063366 0.290788 +0.225952 0.074491 0.259080 +0.250763 0.056393 0.263298 +0.261983 0.035121 0.221390 +0.232025 0.071049 0.211475 +0.251247 0.084420 0.177652 +0.317549 0.092361 0.194930 +0.376276 0.108869 0.213490 +0.407707 0.134249 0.200956 +0.324354 0.161579 0.180522 +0.155666 0.212650 0.191861 +0.276764 0.149348 0.164832 +0.232067 0.140034 0.296200 +0.202557 0.227413 0.232181 +0.213631 0.254317 0.286816 +0.230290 0.348972 0.223799 +0.073922 0.234044 0.444311 +0.165732 0.157286 0.377940 +0.143741 0.116266 0.367517 +0.170743 0.108278 0.335489 +0.204941 0.105478 0.323687 +0.232372 0.096166 0.294273 +0.249692 0.106680 0.233431 +0.247681 0.098716 0.205549 +0.285627 0.093674 0.181026 +0.273729 0.071657 0.199517 +0.324046 0.078751 0.174477 +0.320316 0.099534 0.141530 +0.305721 0.138944 0.194222 +0.307697 0.112445 0.306832 +0.263996 0.168409 0.279904 +0.209440 0.206560 0.352981 +0.207167 0.322235 0.237881 +0.248742 0.300747 0.244987 +0.244240 0.372015 0.250098 +0.311161 0.424673 0.225040 +0.297068 0.321411 0.313296 +0.379598 0.254957 0.371188 +0.432562 0.150907 0.250569 +0.490914 0.159011 0.203063 +0.459581 0.210629 0.184517 +0.365981 0.161992 0.242609 +0.273934 0.337911 0.234642 +0.303721 0.505646 0.388642 +0.245707 0.638533 0.280329 +0.225268 0.652879 0.192438 +0.258619 0.514447 0.279012 +0.316225 0.442602 0.335354 +0.376736 0.486777 0.308274 +0.327223 0.324066 0.242576 +0.485431 0.280997 0.355045 +0.572007 0.122510 0.240640 +0.616966 0.130938 0.227853 +0.513791 0.196874 0.180058 +0.466626 0.182542 0.223111 +0.402779 0.115602 0.343902 +0.375184 0.115227 0.402459 +0.273038 0.096940 0.441549 +0.286064 0.098337 0.549602 +0.246440 0.074548 0.556880 +0.236129 0.064941 0.588188 +0.209837 0.057975 0.532197 +0.259255 0.105430 0.407552 +0.302610 0.088086 0.382011 +0.330261 0.083490 0.318869 +0.339807 0.116430 0.207260 +0.296092 0.172928 0.144366 +0.253885 0.186664 0.166529 +0.277668 0.172442 0.196902 +0.314677 0.169787 0.285051 +0.278732 0.261731 0.151343 +0.192094 0.380939 0.072290 +0.164268 0.445241 0.088517 +0.213885 0.495691 0.078607 +0.244315 0.538432 0.099402 +0.213845 0.607105 0.091577 +0.286835 0.597563 0.087259 +0.318522 0.532846 0.080556 +0.284601 0.472920 0.105552 +0.326441 0.404994 0.109082 +0.361786 0.342944 0.134275 +0.405219 0.182087 0.266692 +0.339703 0.133107 0.349810 +0.318105 0.105264 0.418487 +0.268618 0.127749 0.519300 +0.210097 0.094867 0.551063 +0.184708 0.182810 0.698480 +0.158544 0.111449 0.634672 +0.170413 0.071464 0.657281 +0.171397 0.082903 0.699070 +0.201223 0.064064 0.627255 +0.180269 0.136502 0.501476 +0.221574 0.070933 0.434092 +0.211382 0.073149 0.481703 +0.114169 0.100113 0.915283 +0.146052 0.246456 0.633652 +0.275922 0.245082 0.498471 +0.266161 0.247382 0.434042 +0.302721 0.126115 0.373389 +0.300980 0.138225 0.249755 +0.290909 0.136927 0.286352 +0.350897 0.109421 0.304023 +0.386165 0.088656 0.245381 +0.382333 0.105625 0.151256 +0.421477 0.091637 0.128128 +0.404884 0.121558 0.102941 +0.322205 0.220312 0.077762 +0.283695 0.260465 0.065194 +0.383440 0.199544 0.094240 +0.480839 0.209932 0.141564 +0.441391 0.230279 0.141240 +0.362251 0.290803 0.099062 +0.301174 0.368993 0.092277 +0.377409 0.363282 0.091280 +0.337772 0.461506 0.076775 +0.373032 0.519469 0.124106 +0.314757 0.552002 0.139769 +0.250607 0.492442 0.145557 +0.335493 0.328724 0.166487 +0.534645 0.644574 0.182718 +0.488781 0.353657 0.328925 +0.554548 0.233808 0.376737 +0.492450 0.553839 0.367700 +0.394815 0.210972 0.142784 +0.238589 0.303384 0.080013 +0.224147 0.255123 0.068313 +0.256497 0.235171 0.099373 +0.297511 0.154648 0.113728 +0.305673 0.117198 0.107972 +0.290657 0.090218 0.126335 +0.258861 0.096775 0.145361 +0.259983 0.099517 0.110715 +0.118646 0.148765 0.076387 +0.145023 0.105727 0.109695 +0.181102 0.134847 0.077805 +0.211445 0.088585 0.101849 +0.198248 0.105956 0.172142 +0.180296 0.129252 0.141319 +0.221042 0.083049 0.144665 +0.212791 0.063744 0.179816 +0.167506 0.115897 0.208529 +0.205822 0.062715 0.241237 +0.172651 0.083940 0.183620 +0.124447 0.084470 0.196419 +0.186739 0.063095 0.269351 +0.160093 0.104677 0.295459 +0.143447 0.142741 0.276552 +0.123263 0.196627 0.476282 +0.108325 0.605694 0.334137 +0.285290 0.315781 0.362135 +0.353244 0.270895 0.333924 +0.263653 0.300345 0.291813 +0.208575 0.465618 0.269759 +0.220467 0.418879 0.223504 +0.146022 0.320151 0.302772 +0.183727 0.325046 0.366600 +0.171236 0.313334 0.429997 +0.247905 0.276696 0.319839 +0.127071 0.396634 0.387451 +0.073374 0.373431 0.434696 +0.210963 0.363358 0.326782 +0.268129 0.366304 0.302607 +0.276157 0.386117 0.406186 +0.340781 0.360413 0.321075 +0.431904 0.276036 0.404829 +0.495040 0.225348 0.450453 +0.262250 0.219954 0.192843 +0.261002 0.142204 0.241314 +0.278943 0.115884 0.204352 +0.260726 0.138775 0.101751 +0.183464 0.210049 0.109076 +0.162266 0.261270 0.088046 +0.236604 0.196725 0.126686 +0.316678 0.196107 0.179685 +0.243299 0.306025 0.151947 +0.400615 0.162590 0.232750 +0.372639 0.216589 0.209970 +0.140820 0.222509 0.129726 +0.097670 0.184209 0.193834 +0.193869 0.127067 0.282177 +0.208523 0.142275 0.352114 +0.126584 0.151378 0.342813 +0.235628 0.172984 0.215508 +0.249437 0.175207 0.390557 +0.255433 0.127918 0.372391 +0.359147 0.151917 0.290168 +0.351722 0.205430 0.115799 +0.267453 0.279897 0.108704 +0.350766 0.239207 0.087893 +0.318117 0.273230 0.085462 +0.381113 0.237724 0.065900 +0.219080 0.256349 0.369571 +0.196609 0.194954 0.411062 +0.213051 0.139071 0.398959 +0.244873 0.146332 0.435157 +0.235630 0.181860 0.511397 +0.292860 0.209424 0.147620 +0.331811 0.148006 0.093985 +0.293049 0.144326 0.069176 +0.281985 0.195922 0.077879 +0.228381 0.205538 0.080972 +0.235938 0.163446 0.071037 +0.168487 0.195102 0.072566 +0.199465 0.163509 0.108306 +0.255681 0.174779 0.108553 +0.302851 0.083047 0.155297 +0.321466 0.113845 0.176969 +0.338191 0.096339 0.224480 +0.360544 0.065938 0.241459 +0.378601 0.057338 0.276674 +0.368373 0.076055 0.310651 +0.344437 0.070848 0.286673 +0.376329 0.104163 0.278687 +0.355476 0.110470 0.243634 +0.362002 0.085143 0.260003 +0.411330 0.051881 0.247678 +0.414240 0.068326 0.276653 +0.410484 0.082208 0.354845 +0.418149 0.061438 0.388696 +0.433860 0.142628 0.438577 +0.495950 0.091923 0.413338 +0.434164 0.131070 0.325030 +0.347126 0.153569 0.402577 +0.458076 0.093458 0.443701 +0.495375 0.120909 0.562539 +0.589514 0.080183 0.512524 +0.531194 0.063220 0.328711 +0.499017 0.059249 0.243179 +0.530991 0.079568 0.259341 +0.585658 0.077791 0.416801 +0.536002 0.122366 0.473100 +0.511945 0.062231 0.459896 +0.486451 0.116847 0.370233 +0.481843 0.144265 0.420622 +0.407554 0.241229 0.282167 +0.320925 0.282038 0.252246 +0.225131 0.374849 0.479590 +0.228011 0.237458 0.622277 +0.261961 0.179596 0.806264 +0.076218 0.139692 1.043456 +0.151340 0.328626 0.887716 +0.337210 0.198192 0.379580 +0.460842 0.167548 0.160717 +0.477628 0.229247 0.072684 +0.451350 0.203095 0.091994 +0.420022 0.110903 0.058632 +0.449733 0.161924 0.093239 +0.411145 0.163560 0.078750 +0.435222 0.142044 0.126205 +0.420083 0.099757 0.203874 +0.370276 0.131184 0.131964 +0.354905 0.098162 0.185357 +0.354880 0.098109 0.151202 +0.355875 0.081150 0.202714 +0.329850 0.070604 0.206228 +0.326647 0.063899 0.235204 +0.330171 0.045901 0.207938 +0.329941 0.047031 0.176438 +0.337293 0.074879 0.140863 +0.368014 0.066698 0.168744 +0.300423 0.104975 0.266224 +0.156403 0.547850 0.093121 +0.288125 0.304080 0.176781 +0.210923 0.180445 0.267334 +0.236880 0.217374 0.275212 +0.213759 0.376162 0.184946 +0.372297 0.209676 0.309731 +0.445389 0.226789 0.291673 +0.519740 0.112223 0.265429 +0.472434 0.174961 0.115646 +0.417682 0.274453 0.070003 +0.458596 0.258372 0.047548 +0.455272 0.274496 0.086373 +0.444215 0.318398 0.074804 +0.427749 0.360899 0.081827 +0.369149 0.335197 0.063361 +0.408385 0.324949 0.072860 +0.384052 0.298347 0.060899 +0.373725 0.264760 0.080748 +0.352145 0.176148 0.080707 +0.310910 0.188712 0.108730 +0.250319 0.151051 0.140139 +0.238071 0.144852 0.173219 +0.228573 0.106294 0.172491 +0.217371 0.097639 0.248280 +0.253003 0.069144 0.233568 +0.256968 0.055968 0.160406 +0.235219 0.115044 0.075964 +0.336525 0.077151 0.097771 +0.295976 0.059336 0.123351 +0.324309 0.059429 0.397350 +0.348266 0.106120 0.501358 +0.340380 0.127511 0.440305 +0.275937 0.136374 0.468843 +0.266087 0.282816 0.379226 +0.228482 0.306643 0.416738 +0.246227 0.200955 0.450023 +0.318533 0.209335 0.569205 +0.413909 0.089360 0.618461 +0.382377 0.110800 0.185218 +0.298919 0.076922 0.206253 +0.295486 0.062198 0.170334 +0.220572 0.123944 0.132661 +0.199126 0.138104 0.199012 +0.150799 0.164435 0.128584 +0.141718 0.112651 0.157620 +0.218667 0.109546 0.215544 +0.255989 0.086240 0.259903 +0.300656 0.046011 0.269817 +0.291157 0.059173 0.236624 +0.310810 0.077525 0.293206 +0.314641 0.049528 0.310313 +0.279240 0.086840 0.353600 +0.165264 0.103047 0.417338 +0.208135 0.117070 0.429435 +0.232791 0.103415 0.462895 +0.271864 0.129281 0.319815 +0.366981 0.141852 0.212178 +0.373262 0.242359 0.117112 +0.422067 0.278600 0.123501 +0.338944 0.345572 0.098531 +0.308216 0.428668 0.066433 +0.271454 0.398601 0.070491 +0.278913 0.492798 0.060932 +0.247776 0.441372 0.071561 +0.343570 0.386117 0.081017 +0.461654 0.239819 0.108222 +0.430485 0.272031 0.176591 +0.408685 0.297320 0.097183 +0.485213 0.284632 0.069179 +0.461397 0.373449 0.100410 +0.671420 0.378029 0.088090 +0.808405 0.276010 0.102934 +0.704869 0.430068 0.070162 +0.554941 0.507594 0.125272 +0.359919 0.301913 0.230542 +0.251847 0.314817 0.199777 +0.293156 0.307596 0.224547 +0.356977 0.402190 0.240191 +0.290117 0.743767 0.395678 +0.392248 0.703453 0.280630 +0.476220 0.520924 0.129796 +0.527212 0.411812 0.063633 +0.542919 0.358453 0.095274 +0.556482 0.315834 0.117993 +0.482078 0.326051 0.096336 +0.420379 0.426709 0.088736 +0.369052 0.415845 0.093306 +0.437630 0.334794 0.118496 +0.466644 0.293770 0.233791 +0.508918 0.228596 0.222776 +0.484639 0.121415 0.212331 +0.443499 0.096268 0.231387 +0.511197 0.174015 0.270205 +0.352556 0.283611 0.272015 +0.293392 0.425947 0.162990 +0.332821 0.275494 0.174376 +0.298858 0.241340 0.192968 +0.305188 0.294785 0.139588 +0.375530 0.449251 0.144064 +0.292345 0.781183 0.254538 +0.358461 0.243978 0.182222 +0.415777 0.244409 0.238222 +0.467064 0.146980 0.298146 +0.416339 0.232371 0.189786 +0.191873 0.319957 0.083328 +0.203436 0.360141 0.135797 +0.374532 0.135837 0.364913 +0.268287 0.102231 0.714801 +0.254501 0.146265 0.649860 +0.218848 0.270739 0.467287 +0.188426 0.170744 0.462937 +0.245247 0.107864 0.332378 +0.122418 0.152546 0.533111 +0.079016 0.314882 0.596442 +0.126964 0.240808 0.550476 +0.075791 0.140645 0.502026 +0.093230 0.113111 0.626546 +0.172159 0.080636 0.831021 +0.068199 0.206815 0.906033 +0.062132 0.233971 0.778223 +0.074593 0.142563 0.751383 +0.109526 0.088462 0.775006 +0.124547 0.075148 0.714916 +0.219269 0.045432 0.388959 +0.127591 0.145316 0.230824 +0.075140 0.099358 0.462657 +0.064338 0.123266 0.563272 +0.078238 0.117014 0.688975 +0.084643 0.135331 0.834358 +0.139739 0.180181 0.788226 +0.146212 0.130036 0.742469 +0.142021 0.071166 0.618520 +0.264581 0.062830 0.446908 +0.320084 0.063118 0.350973 +0.396868 0.104191 0.308665 +0.464396 0.100744 0.190844 +0.474587 0.135638 0.122223 +0.505265 0.164031 0.083774 +0.508671 0.149050 0.116783 +0.494586 0.165303 0.148019 +0.472521 0.133399 0.178996 +0.472105 0.087004 0.224228 +0.446638 0.121806 0.273503 +0.367261 0.095789 0.337281 +0.359383 0.069161 0.376118 +0.283834 0.061745 0.401507 +0.233699 0.158991 0.567659 +0.131424 0.169028 0.614621 +0.073539 0.165230 0.608024 +0.084229 0.293229 0.506663 +0.148758 0.720830 0.237339 +0.256384 0.243042 0.348749 +0.395262 0.183863 0.343968 +0.381026 0.153580 0.322679 +0.344857 0.169307 0.357051 +0.180931 0.274934 0.267210 +0.133417 0.315317 0.364657 +0.184162 0.267604 0.330168 +0.220026 0.283042 0.231767 +0.259555 0.237606 0.232106 +0.276933 0.249820 0.287878 +0.349980 0.282625 0.421991 +0.481016 0.212218 0.325727 +0.458797 0.184528 0.274070 +0.484482 0.148105 0.341873 +0.526047 0.155385 0.400111 +0.526136 0.175193 0.328794 +0.556038 0.116326 0.373700 +0.437912 0.183108 0.320129 +0.154855 0.684819 0.527786 +0.142128 0.492151 0.711010 +0.062256 0.311531 0.691655 +0.180612 0.307234 0.730728 +0.152739 0.786052 0.357275 +0.421748 0.155971 0.355152 +0.513427 0.140653 0.180397 +0.503293 0.090152 0.226204 +0.470923 0.079454 0.290961 +0.458356 0.094363 0.377705 +0.447899 0.062986 0.355100 +0.490749 0.048144 0.340535 +0.490854 0.079767 0.368968 +0.568302 0.078153 0.271815 +0.574387 0.098205 0.200963 +0.644881 0.089413 0.208920 +0.636596 0.088651 0.058559 +0.553118 0.323894 0.063352 +0.583298 0.295978 0.091612 +0.606749 0.318066 0.058865 +0.487005 0.454915 0.177572 +0.329222 0.315592 0.285150 +0.299399 0.277718 0.282728 +0.302006 0.358174 0.148859 +0.334243 0.327319 0.350426 +0.291480 0.333984 0.274831 +0.383078 0.333489 0.255643 +0.406396 0.413215 0.258302 +0.479588 0.360631 0.169112 +0.594135 0.255844 0.137076 +0.847445 0.093619 0.248967 +0.810961 0.161433 0.181118 +0.732094 0.308294 0.140083 +0.623878 0.379968 0.070210 +0.567617 0.374818 0.060450 +0.664229 0.294886 0.104059 +0.645906 0.246204 0.135086 +0.673058 0.227775 0.100138 +0.659455 0.250925 0.067423 +0.627904 0.283712 0.067938 +0.581249 0.267066 0.063458 +0.617716 0.219403 0.068390 +0.599018 0.303403 0.166919 +0.450459 0.568624 0.270030 +0.497221 0.226918 0.270466 +0.411324 0.232483 0.331049 +0.320406 0.443850 0.269652 +0.187291 0.561422 0.165638 +0.294572 0.343681 0.200707 +0.326397 0.258546 0.286441 +0.279400 0.306226 0.260735 +0.193123 0.385992 0.258247 +0.342327 0.381838 0.147491 +0.433089 0.378484 0.207774 +0.362956 0.347448 0.222551 +0.361638 0.480201 0.226996 +0.384522 0.377667 0.186341 +0.427881 0.296866 0.282612 +0.563327 0.229524 0.304696 +0.567170 0.247155 0.202733 +0.585411 0.220038 0.115594 +0.519250 0.229429 0.071582 +0.466406 0.348495 0.062605 +0.474052 0.430997 0.059085 +0.456952 0.434321 0.092489 +0.443242 0.479322 0.066114 +0.424170 0.532398 0.074007 +0.394911 0.475416 0.086889 +0.452632 0.411710 0.140813 +0.403571 0.307690 0.141199 +0.330609 0.309675 0.202639 +0.162152 0.333000 0.246273 +0.104212 0.372786 0.256919 +0.136824 0.521324 0.228461 +0.104865 0.608493 0.187863 +0.112234 0.499159 0.140580 +0.103176 0.394350 0.106114 +0.097342 0.431118 0.194462 +0.199846 0.166342 0.150206 +0.257308 0.138618 0.204462 +0.377777 0.076428 0.214777 +0.396461 0.078672 0.186686 +0.412491 0.083042 0.157354 +0.409492 0.113963 0.166822 +0.402656 0.132414 0.136860 +0.384318 0.169269 0.141277 +0.379760 0.142363 0.169790 +0.434051 0.125795 0.180081 +0.291493 0.229394 0.111634 +0.413319 0.193400 0.112837 +0.413655 0.226896 0.114264 +0.433596 0.176677 0.130118 +0.324845 0.251559 0.120351 +0.359504 0.214180 0.154811 +0.415838 0.197748 0.221624 +0.330767 0.232694 0.237892 +0.283703 0.199163 0.276558 +0.402389 0.264705 0.562024 +0.405915 0.068161 0.722076 +0.408789 0.081683 0.224705 +0.412949 0.070850 0.318290 +0.383543 0.088037 0.376585 +0.413842 0.087764 0.457480 +0.394697 0.085379 0.526908 +0.326022 0.124012 0.545103 +0.360363 0.103599 0.573651 +0.374875 0.071392 0.577138 +0.426542 0.064067 0.485994 +0.414344 0.062295 0.436129 +0.357597 0.053368 0.442984 +0.352690 0.061527 0.481466 +0.435965 0.091560 0.330005 +0.452104 0.173696 0.389629 +0.240811 0.227686 0.399164 +0.387054 0.212876 0.250823 +0.348481 0.199112 0.239045 +0.406692 0.124037 0.262865 +0.364589 0.130457 0.265840 +0.418494 0.152965 0.158070 +0.525395 0.176045 0.224438 +0.649496 0.162294 0.265624 +0.577476 0.087708 0.311571 +0.635120 0.080693 0.336377 +0.695460 0.066421 0.421660 +0.621358 0.149936 0.353147 +0.567838 0.187842 0.239684 +0.610053 0.188465 0.189601 +0.290729 0.370305 0.245506 +0.474752 0.256582 0.192554 +0.523264 0.281951 0.174076 +0.487445 0.266791 0.140722 +0.418187 0.308871 0.224831 +0.542461 0.339261 0.179909 +0.660046 0.325237 0.064232 +0.699190 0.263381 0.081222 +0.771760 0.141829 0.114068 +0.849307 0.167518 0.110492 +0.768620 0.215479 0.101016 +0.943168 0.112917 0.126022 +0.700213 0.207371 0.114043 +0.520214 0.355040 0.056977 +0.501121 0.416740 0.097933 +0.413408 0.446710 0.207348 +0.316233 0.501402 0.172782 +0.422015 0.299620 0.334807 +0.467201 0.278473 0.294606 +0.449356 0.314132 0.169959 +0.383191 0.318048 0.185054 +0.263466 0.409830 0.258522 +0.344203 0.180472 0.319223 +0.362266 0.169616 0.180383 +0.341699 0.182702 0.146822 +0.335987 0.174976 0.210809 +0.395083 0.165288 0.194206 +0.465646 0.099187 0.323536 +0.462006 0.053739 0.310921 +0.455068 0.081078 0.262737 +0.418012 0.119395 0.233351 +0.345448 0.135789 0.188425 +0.351492 0.162596 0.117706 +0.344759 0.149410 0.147248 +0.314307 0.134967 0.151339 +0.286415 0.116093 0.164754 +0.277756 0.126139 0.130984 +0.361188 0.110945 0.070191 +0.361209 0.201107 0.056536 +0.284536 0.314088 0.069545 +0.432086 0.300442 0.045010 +0.395858 0.449191 0.053920 +0.358265 0.503243 0.063399 +0.373607 0.577103 0.071048 +0.277978 0.673759 0.088057 +0.361589 0.613722 0.123032 +0.384724 0.684712 0.091070 +0.459571 0.724691 0.081391 +0.440636 0.611416 0.071085 +0.491405 0.544525 0.066202 +0.495390 0.482599 0.069217 +0.585200 0.253363 0.096585 +0.538917 0.276943 0.073936 +0.500464 0.315306 0.054544 +0.664338 0.150817 0.196704 +0.500195 0.080074 0.282262 +0.530558 0.067443 0.375424 +0.440087 0.352641 0.277248 +0.390681 0.267263 0.209143 +0.359333 0.241690 0.261267 +0.370447 0.247920 0.308405 +0.336215 0.226039 0.305830 +0.195785 0.339497 0.283349 +0.151348 0.445352 0.258280 +0.266713 0.219848 0.307969 +0.218114 0.294964 0.285277 +0.174107 0.381064 0.212437 +0.155914 0.377087 0.116389 +0.134386 0.253742 0.304443 +0.151029 0.213087 0.353221 +0.217483 0.140058 0.241820 +0.242753 0.116518 0.270671 +0.285332 0.068762 0.270927 +0.317498 0.078582 0.264060 +0.277862 0.110739 0.250417 +0.308456 0.109889 0.221582 +0.276315 0.089684 0.226545 +0.333980 0.135929 0.231792 +0.334591 0.166897 0.259283 +0.397876 0.537888 0.188209 +0.290878 0.394567 0.198465 +0.163752 0.435990 0.173066 +0.191115 0.481622 0.133956 +0.260636 0.377095 0.197277 +0.338080 0.235880 0.426527 +0.378463 0.127767 0.454089 +0.385046 0.056905 0.498118 +0.374068 0.049953 0.405294 +0.271022 0.098818 0.289459 +0.182680 0.217988 0.292618 +0.225435 0.235809 0.318205 +0.177229 0.103515 0.463042 +0.175834 0.055640 0.486987 +0.183210 0.062875 0.440837 +0.226003 0.097193 0.366732 +0.251396 0.070201 0.393377 +0.234201 0.074576 0.326442 +0.223004 0.066314 0.353857 +0.186211 0.106789 0.245913 +0.151535 0.094840 0.253435 +0.195080 0.089425 0.287492 +0.162720 0.067083 0.227111 +0.196415 0.076298 0.212223 +0.180505 0.083889 0.141164 +0.246234 0.066099 0.131760 +0.282666 0.087223 0.081269 +0.340580 0.122366 0.117784 +0.376555 0.091363 0.111974 +0.393102 0.087543 0.417517 +0.297217 0.163487 0.549749 +0.362450 0.174227 0.634258 +0.323933 0.627863 0.231764 +0.327261 0.458545 0.128228 +0.345717 0.429564 0.187171 +0.260069 0.337062 0.335170 +0.306881 0.385334 0.293359 +0.271898 0.457259 0.215823 +0.259289 0.441347 0.303200 +0.363305 0.398019 0.291679 +0.291795 0.279053 0.324220 +0.294547 0.262771 0.399943 +0.371243 0.306137 0.366069 +0.382008 0.339743 0.307443 +0.438316 0.228950 0.367986 +0.537463 0.298231 0.257224 +0.645494 0.307091 0.289935 +0.669328 0.320508 0.177252 +0.616771 0.434999 0.131058 +0.565925 0.511230 0.217275 +0.568203 0.409220 0.089091 +0.577548 0.394258 0.217345 +0.648943 0.237348 0.200174 +0.599721 0.237036 0.256373 +0.754878 0.197561 0.266084 +0.714487 0.175657 0.200087 +0.710745 0.237411 0.165014 +0.720827 0.339743 0.072832 +0.545081 0.459358 0.071144 +0.346804 0.807739 0.104644 +0.216743 0.762837 0.120249 +0.197697 0.658146 0.387627 +0.165912 0.499878 0.549502 +0.241754 0.317091 0.529186 +0.169200 0.553212 0.416930 +0.320751 0.621112 0.366138 +0.337485 0.556049 0.269330 +0.250664 0.574848 0.514561 +0.140209 0.430307 0.459246 +0.162363 0.246323 0.477493 +0.381402 0.092797 0.469234 +0.459381 0.155970 0.481903 +0.442539 0.088546 0.414977 +0.408686 0.121373 0.498045 +0.329248 0.153610 0.482630 +0.331997 0.142511 0.315883 +0.221799 0.396419 0.292101 +0.176966 0.273274 0.211951 +0.203478 0.286430 0.129390 +0.216827 0.258314 0.184043 +0.234488 0.175930 0.313819 +0.311501 0.270429 0.211948 +0.294432 0.162487 0.229611 +0.329328 0.117112 0.277223 +0.416641 0.099298 0.274074 +0.554873 0.155235 0.201501 +0.569426 0.189358 0.155950 +0.539367 0.241198 0.105444 +0.501517 0.357700 0.084370 +0.545573 0.281564 0.125541 +0.514425 0.301811 0.096910 +0.460345 0.293995 0.114532 +0.487409 0.345311 0.229900 +0.412521 0.355808 0.145545 +0.509374 0.347915 0.128813 +0.629454 0.215821 0.104369 +0.658561 0.176420 0.084630 +0.700668 0.136656 0.112851 +0.667071 0.122890 0.157514 +0.612182 0.148628 0.155034 +0.539605 0.176739 0.090625 +0.590039 0.124542 0.106912 +0.629817 0.100757 0.139713 +0.604716 0.105384 0.173581 +0.720555 0.111138 0.330763 +0.245112 0.336634 0.265337 +0.226689 0.424271 0.348303 +0.329654 0.359100 0.261678 +0.379459 0.286999 0.299860 +0.342863 0.299943 0.318446 +0.330710 0.371149 0.198420 +0.285053 0.275836 0.238793 +0.361749 0.196487 0.281140 +0.406042 0.191956 0.297341 +0.445690 0.223770 0.237164 +0.393133 0.274606 0.262027 +0.544286 0.142320 0.276324 +0.619365 0.107015 0.281186 +0.607150 0.081004 0.243243 +0.678787 0.091345 0.263915 +0.734877 0.105834 0.242728 +0.694254 0.100473 0.181406 +0.758976 0.109087 0.167450 +0.565683 0.217978 0.071529 +0.445274 0.395501 0.058069 +0.484692 0.379794 0.062350 +0.214619 0.245836 0.117895 +0.246969 0.229441 0.150311 +0.385481 0.258270 0.151377 +0.353085 0.290950 0.141139 +0.535642 0.170306 0.146284 +0.446113 0.090546 0.161019 +0.348613 0.118759 0.163942 +0.256859 0.116937 0.175945 +0.095533 0.124223 0.128081 +0.104333 0.215306 0.075249 +0.100294 0.187881 0.135738 +0.148622 0.275139 0.167339 +0.078452 0.360587 0.329967 +0.127610 0.289917 0.238589 +0.148272 0.316966 0.121487 +0.085461 0.330668 0.163259 +0.142401 0.216090 0.250904 +0.175731 0.166076 0.233510 +0.152278 0.156198 0.181459 +0.193328 0.210638 0.148227 +0.207811 0.191064 0.188672 +0.296438 0.161485 0.325233 +0.306068 0.199688 0.322695 +0.342566 0.219355 0.346721 +0.291750 0.188465 0.494566 +0.352065 0.234211 0.491138 +0.383860 0.596099 0.458394 +0.386344 0.202868 0.380113 +0.399359 0.282461 0.474285 +0.322622 0.279134 0.358938 +0.347701 0.262331 0.223429 +0.424998 0.191838 0.164353 +0.451151 0.131623 0.217203 +0.456273 0.120859 0.149404 +0.490554 0.108928 0.157243 +0.517816 0.130242 0.142810 +0.500090 0.217505 0.103504 +0.514504 0.191274 0.118656 +0.554806 0.122508 0.163126 +0.442524 0.162708 0.199911 +0.388949 0.157852 0.109288 +0.504477 0.095186 0.125173 +0.477591 0.066576 0.138585 +0.452216 0.100773 0.107700 +0.485286 0.127587 0.074852 +0.488827 0.194629 0.066040 +0.426576 0.237428 0.067677 +0.340727 0.291206 0.061076 +0.243435 0.361855 0.071906 +0.382323 0.324483 0.098684 +0.414425 0.354228 0.048282 +0.401390 0.400107 0.040249 +0.403756 0.393196 0.073045 +0.357685 0.422727 0.054290 +0.376221 0.373641 0.056815 +0.334172 0.375680 0.054225 +0.296174 0.361326 0.050408 +0.326273 0.330339 0.064557 +0.420692 0.255904 0.094806 +0.421944 0.199537 0.068849 +0.326830 0.232006 0.153704 +0.301454 0.201485 0.233060 +0.258842 0.191789 0.343414 +0.294282 0.195861 0.362979 +0.286399 0.234317 0.360778 +0.319442 0.214047 0.274131 +0.333404 0.220264 0.204146 +0.386995 0.195077 0.182131 +0.404880 0.215968 0.423836 +0.477146 0.435211 0.260239 +0.532189 0.227684 0.146512 +0.568278 0.159946 0.110703 +0.605267 0.174809 0.088477 +0.624009 0.142924 0.112772 +0.652905 0.148818 0.139204 +0.714256 0.157313 0.148093 +0.720760 0.199261 0.080657 +0.741518 0.278514 0.083257 +0.566298 0.527298 0.062699 +0.445052 0.597589 0.130277 +0.526449 0.626948 0.074424 +0.801938 0.367141 0.075543 +0.916524 0.255963 0.112835 +0.645568 0.521635 0.064144 +0.608913 0.448818 0.064142 +0.629099 0.328544 0.099333 +0.620582 0.182449 0.132128 +0.590707 0.148356 0.186809 +0.543143 0.102875 0.300062 +0.527847 0.116107 0.336959 +0.499887 0.117763 0.297680 +0.508919 0.134512 0.236929 +0.531706 0.109558 0.239043 +0.541620 0.120673 0.208110 +0.517661 0.098274 0.183512 +0.449983 0.054085 0.247178 +0.575793 0.062186 0.355346 +0.489231 0.203337 0.380285 +0.340551 0.340643 0.414281 +0.210167 0.526078 0.337705 +0.284920 0.525512 0.222620 +0.208797 0.499630 0.207868 +0.267127 0.583546 0.176083 +0.228186 0.428672 0.171167 +0.258450 0.355455 0.160617 +0.273653 0.409657 0.120028 +0.264098 0.344696 0.111979 +0.222486 0.415597 0.112772 +0.199350 0.325482 0.185961 +0.294632 0.157878 0.367064 +0.346967 0.102272 0.381014 +0.324707 0.101328 0.346674 +0.300669 0.154767 0.427674 +0.297977 0.190730 0.402531 +0.322781 0.242743 0.378056 +0.419505 0.654624 0.200084 +0.318601 0.692538 0.162850 +0.178499 0.579044 0.270280 +0.195204 0.388057 0.398083 +0.241827 0.349617 0.379452 +0.315199 0.303795 0.489292 +0.380392 0.178450 0.504430 +0.414296 0.143625 0.555054 +0.339645 0.110851 0.633101 +0.315159 0.082478 0.583218 +0.337965 0.059219 0.531018 +0.321096 0.080831 0.498225 +0.307444 0.107476 0.461283 +0.278693 0.093535 0.490594 +0.252057 0.083619 0.514079 +0.224412 0.111350 0.505414 +0.169223 0.083911 0.512845 +0.208880 0.083504 0.402948 +0.187837 0.073111 0.335010 +0.206755 0.055269 0.311264 +0.156291 0.062835 0.298062 +0.156028 0.064082 0.415247 +0.129754 0.074279 0.474540 +0.183725 0.101044 0.375452 +0.181248 0.060180 0.378248 +0.178353 0.183494 0.547763 +0.303398 0.241676 0.322364 +0.263082 0.269825 0.205102 +0.295290 0.241493 0.251070 +0.310143 0.206645 0.446008 +0.249752 0.262630 0.261739 +0.225039 0.305225 0.344815 +0.153658 0.404495 0.314509 +0.142025 0.474338 0.358307 +0.228656 0.455858 0.431304 +0.360261 0.434834 0.461602 +0.432447 0.356868 0.399441 +0.405888 0.423867 0.341787 +0.307752 0.379122 0.354664 +0.495951 0.255588 0.098194 +0.590320 0.364141 0.130834 +0.523157 0.411325 0.142398 +0.622815 0.267082 0.098576 +0.586226 0.337718 0.086861 +0.396476 0.396958 0.127666 +0.278385 0.309875 0.439028 +0.210412 0.240403 0.530267 +0.142154 0.341782 0.515974 +0.236712 0.330636 0.302147 +0.313995 0.313085 0.102247 +0.536878 0.123790 0.095432 +0.546579 0.066696 0.222251 +0.528723 0.046496 0.288028 +0.490438 0.079978 0.328045 +0.416715 0.108530 0.389254 +0.350888 0.083964 0.417653 +0.307331 0.062124 0.473629 +0.274119 0.115537 0.597408 +0.226906 0.099518 0.609696 +0.147094 0.067376 0.550921 +0.178994 0.061997 0.585308 +0.132607 0.110425 0.587137 +0.110327 0.099682 0.549983 +0.068912 0.202205 0.534312 +0.065072 0.231313 0.620174 +0.080325 0.190639 0.689245 +0.127351 0.125355 0.674554 +0.110891 0.072596 0.663783 +0.097157 0.070549 0.589126 +0.106411 0.082418 0.509171 +0.125632 0.088198 0.439270 +0.126006 0.083980 0.396385 +0.144132 0.069483 0.352444 +0.105337 0.088013 0.358993 +0.119785 0.099438 0.312550 +0.070842 0.142954 0.331889 +0.071861 0.089577 0.402256 +0.108923 0.084005 0.258422 +0.092866 0.123378 0.193507 +0.088292 0.071041 0.315009 +0.063561 0.165270 0.420738 +0.074840 0.133173 0.262739 +0.089400 0.194231 0.262021 +0.079851 0.205849 0.344821 +0.157143 0.146865 0.421765 +0.125245 0.208011 0.414350 +0.174337 0.251983 0.396703 +0.084886 0.272191 0.354568 +0.110693 0.292372 0.436834 +0.211165 0.375835 0.619400 +0.062966 0.412899 0.552075 +0.081388 0.529721 0.443287 +0.081245 0.483334 0.304728 +0.138084 0.348639 0.182624 +0.103443 0.309738 0.080859 +0.104109 0.260851 0.123996 +0.091414 0.251910 0.196193 +0.076304 0.263206 0.278157 +0.134332 0.188036 0.301992 +0.107220 0.138757 0.409882 +0.128381 0.129478 0.471249 +0.160195 0.115412 0.544945 +0.191115 0.149126 0.609196 +0.184568 0.103795 0.587575 +0.248953 0.058854 0.636286 +0.192984 0.081624 0.751367 +0.220001 0.099182 0.668267 +0.223085 0.059316 0.689244 +0.276099 0.046871 0.774911 +0.314266 0.073942 0.676716 +0.296234 0.076044 0.626027 +0.279541 0.049108 0.565247 +0.285398 0.057887 0.519502 +0.243492 0.048975 0.483027 +0.309314 0.059143 0.435497 +0.387586 0.051625 0.354348 +0.397104 0.047268 0.326093 +0.434850 0.059475 0.193227 diff --git a/libs/libcodec2/unittest/lspd78.txt b/libs/libcodec2/unittest/lspd78.txt new file mode 100644 index 0000000000..13ee29c3b3 --- /dev/null +++ b/libs/libcodec2/unittest/lspd78.txt @@ -0,0 +1,64 @@ +0.281245 0.072824 +0.339645 0.060014 +0.409277 0.064576 +0.523095 0.061305 +0.230096 0.211887 +0.207683 0.332701 +0.284308 0.308783 +0.140378 0.711570 +0.174527 0.127827 +0.352952 0.235323 +0.370502 0.190103 +0.402932 0.159641 +0.347927 0.146360 +0.296583 0.131013 +0.223266 0.153607 +0.197020 0.420964 +0.116898 0.516163 +0.119488 0.109699 +0.111778 0.278792 +0.578302 0.202919 +0.414620 0.214613 +0.305886 0.397131 +0.332819 0.101995 +0.378387 0.086890 +0.382898 0.121331 +0.453255 0.063910 +0.426851 0.114357 +0.460512 0.099039 +0.479185 0.134529 +0.496434 0.084061 +0.573538 0.071989 +0.531672 0.120071 +0.591529 0.134458 +0.511033 0.180023 +0.448004 0.171478 +0.322286 0.187786 +0.297869 0.238597 +0.242424 0.263223 +0.175075 0.260064 +0.201034 0.074025 +0.268571 0.522305 +0.344104 0.296771 +0.409613 0.271732 +0.173676 0.190087 +0.115603 0.193700 +0.115269 0.373202 +0.407643 0.637929 +0.439428 0.478964 +0.567749 0.389060 +0.551502 0.271892 +0.639284 0.075639 +0.665511 0.286926 +0.720983 0.084070 +0.795786 0.214436 +0.832583 0.095102 +0.671796 0.164706 +0.983554 0.136778 +0.812831 0.368808 +0.644281 0.515306 +0.480389 0.316998 +0.403689 0.360441 +0.476736 0.232898 +0.248084 0.111421 +0.273953 0.180184 diff --git a/libs/libcodec2/unittest/lspd910.txt b/libs/libcodec2/unittest/lspd910.txt new file mode 100644 index 0000000000..99c4b8d578 --- /dev/null +++ b/libs/libcodec2/unittest/lspd910.txt @@ -0,0 +1,64 @@ +0.678062 0.043120 +0.472775 0.257353 +0.522878 0.127961 +0.628034 0.038788 +0.480545 0.057725 +0.437201 0.064479 +0.327854 0.073645 +0.308168 0.135691 +0.390919 0.172150 +0.362940 0.121889 +0.384688 0.065511 +0.419078 0.117947 +0.468913 0.116759 +0.507838 0.089601 +0.555567 0.052196 +0.521040 0.052787 +0.589645 0.043616 +0.985285 0.088227 +0.724020 0.177911 +0.129928 0.130564 +0.120671 0.249971 +0.266520 0.077658 +0.685157 0.083387 +0.673088 0.130951 +0.726463 0.107217 +0.779587 0.130439 +0.652097 0.060232 +0.616365 0.062903 +0.614893 0.095188 +0.671203 0.264629 +0.657805 0.188243 +0.647995 0.095077 +0.581225 0.110398 +0.573894 0.254912 +0.531176 0.201073 +0.544230 0.353796 +0.621094 0.138556 +0.717028 0.053894 +0.890269 0.071236 +1.100420 0.115118 +0.492946 0.167302 +0.387836 0.249419 +0.929411 0.210459 +0.389735 0.351413 +0.273341 0.443161 +0.453321 0.457227 +0.303206 0.300360 +0.563261 0.148813 +0.789479 0.244432 +0.817080 0.062843 +0.852058 0.150352 +0.760492 0.059787 +0.711233 0.355546 +0.598869 0.189758 +0.583624 0.073653 +0.548949 0.089569 +0.445394 0.183962 +0.333115 0.197087 +0.246232 0.142290 +0.263973 0.216087 +0.185969 0.192135 +0.205425 0.302232 +0.195923 0.088343 +0.148277 0.406699 diff --git a/libs/libcodec2/unittest/lsptest.c b/libs/libcodec2/unittest/lsptest.c new file mode 100644 index 0000000000..8a610a18f4 --- /dev/null +++ b/libs/libcodec2/unittest/lsptest.c @@ -0,0 +1,177 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lsptest.c + AUTHOR......: David Rowe + DATE CREATED: 24/8/09 + + Test Speech LPC to LSP conversion and quantisation. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <lpc.h> +#include <lsp.h> +#include <sd.h> + +#define N 160 +#define P 10 + +#define LPC_FLOOR 0.0002 /* autocorrelation floor */ +#define LSP_DELTA1 0.2 /* grid spacing for LSP root searches */ +#define NDFT 256 /* DFT size for SD calculation */ + +/* Speex lag window */ + +const float lag_window[11] = { + 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, + 0.83367, 0.79434, 0.75258 +}; + +/*---------------------------------------------------------------------------*\ + + find_aks_for_lsp() + + This function takes a frame of samples, and determines the linear + prediction coefficients for that frame of samples. Modified version of + find_aks from lpc.c to include autocorrelation noise floor and lag window + to match Speex processing steps prior to LSP conversion. + +\*---------------------------------------------------------------------------*/ + +void find_aks_for_lsp( + float Sn[], /* Nsam samples with order sample memory */ + float a[], /* order+1 LPCs with first coeff 1.0 */ + int Nsam, /* number of input speech samples */ + int order, /* order of the LPC analysis */ + float *E /* residual energy */ +) +{ + float Wn[N]; /* windowed frame of Nsam speech samples */ + float R[P+1]; /* order+1 autocorrelation values of Sn[] */ + int i; + + hanning_window(Sn,Wn,Nsam); + + autocorrelate(Wn,R,Nsam,order); + R[0] += LPC_FLOOR; + assert(order == 10); /* lag window only defined for order == 10 */ + for(i=0; i<=order; i++) + R[i] *= lag_window[i]; + levinson_durbin(R,a,order); + + *E = 0.0; + for(i=0; i<=order; i++) + *E += a[i]*R[i]; + if (*E < 0.0) + *E = 1E-12; +} + +/*---------------------------------------------------------------------------*\ + + MAIN + +\*---------------------------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + FILE *fin; /* input speech files */ + short buf[N]; /* buffer of 16 bit speech samples */ + float Sn[P+N]; /* input speech samples */ + float E; + float ak[P+1]; /* LP coeffs */ + float ak_[P+1]; /* quantised LP coeffs */ + float lsp[P]; + float lsp_[P]; /* quantised LSPs */ + int roots; /* number of LSP roots found */ + int frames; /* frames processed so far */ + int i; /* loop variables */ + + SpeexBits bits; + + float sd; /* SD for this frame */ + float totsd; /* accumulated SD so far */ + int gt2,gt4; /* number of frames > 2 and 4 dB SD */ + int unstables; /* number of unstable LSP frames */ + + if (argc < 2) { + printf("usage: %s InputFile\n", argv[0]); + exit(0); + } + + /* Open files */ + + if ((fin = fopen(argv[1],"rb")) == NULL) { + printf("Error opening input file: %s\n",argv[1]); + exit(0); + } + + /* Initialise */ + + frames = 0; + for(i=0; i<P; i++) { + Sn[i] = 0.0; + } + ak_[0] = 1.0; + + speex_bits_init(&bits); + + totsd = 0.0; + unstables = 0; + gt2 = 0; gt4 = 0; + + /* Main loop */ + + while( (fread(buf,sizeof(short),N,fin)) == N) { + frames++; + for(i=0; i<N; i++) + Sn[P+i] = (float)buf[i]; + + /* convert to LSP domain and back */ + + find_aks(&Sn[P], ak, N, P, &E); + roots = lpc_to_lsp(&ak[1], P , lsp, 10, LSP_DELTA1, NULL); + if (roots == P) { + + speex_bits_reset(&bits); + lsp_quant_lbr(lsp, lsp_, P, &bits); + lsp_to_lpc(lsp_, &ak_[1], P, NULL); + + /* measure spectral distortion */ + sd = spectral_dist(ak, ak_, P, NDFT); + if (sd > 2.0) gt2++; + if (sd > 4.0) gt4++; + totsd += sd; + } + else + unstables++; + } + + fclose(fin); + + printf("frames = %d Av sd = %3.2f dB", frames, totsd/frames); + printf(" >2 dB %3.2f%% >4 dB %3.2f%% unstables: %d\n",gt2*100.0/frames, + gt4*100.0/frames, unstables); + + return 0; +} + diff --git a/libs/libcodec2/unittest/sd.c b/libs/libcodec2/unittest/sd.c new file mode 100644 index 0000000000..f77b5099d5 --- /dev/null +++ b/libs/libcodec2/unittest/sd.c @@ -0,0 +1,84 @@ +/*--------------------------------------------------------------------------*\ + + FILE........: sd.c + AUTHOR......: David Rowe + DATE CREATED: 20/7/93 + + Function to determine spectral distortion between two sets of LPCs. + +\*--------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define MAX_N 2048 /* maximum DFT size */ + +#include <math.h> +#include "four1.h" +#include "comp.h" +#include "sd.h" + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: spectral_dist() + + AUTHOR......: David Rowe + DATE CREATED: 20/7/93 + + This function returns the soectral distoertion between two + sets of LPCs. + +\*---------------------------------------------------------------------------*/ + +float spectral_dist(float ak1[], float ak2[], int p, int n) +/* float ak1[]; unquantised set of p+1 LPCs */ +/* float ak2[]; quantised set of p+1 LPCs */ +/* int p; LP order */ +/* int n; DFT size to use for SD calculations (power of 2) */ +{ + COMP A1[MAX_N]; /* DFT of ak1[] */ + COMP A2[MAX_N]; /* DFT of ak2[] */ + float P1,P2; /* power of current bin */ + float sd; + int i; + + for(i=0; i<n; i++) { + A1[i].real = 0.0; + A1[i].imag = 0.0; + A2[i].real = 0.0; + A2[i].imag = 0.0; + } + + for(i=0; i<p+1; i++) { + A1[i].real = ak1[i]; + A2[i].real = ak2[i]; + } + + four1(&A1[-1].imag,n,-1); + four1(&A2[-1].imag,n,-1); + + sd = 0.0; + for(i=0; i<n; i++) { + P1 = A1[i].real*A1[i].real + A1[i].imag*A1[i].imag; + P2 = A2[i].real*A2[i].real + A2[i].imag*A2[i].imag; + sd += pow(log10(P2/P1),2.0); + } + sd = 10.0*sqrt(sd/n); /* sd in dB */ + + return(sd); +} diff --git a/libs/libcodec2/unittest/tcodec2.c b/libs/libcodec2/unittest/tcodec2.c new file mode 100644 index 0000000000..33806fc7d3 --- /dev/null +++ b/libs/libcodec2/unittest/tcodec2.c @@ -0,0 +1,215 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: tcodec2.c + AUTHOR......: David Rowe + DATE CREATED: 24/8/10 + + Test program for codec2.c functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include "defines.h" +#include "codec2.h" +#include "quantise.h" +#include "interp.h" + +/* CODEC2 struct copies from codec2.c to help with testing */ + +typedef struct { + float Sn[M]; /* input speech */ + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn_[2*N]; /* synthesised speech */ + float prev_Wo; /* previous frame's pitch estimate */ + float ex_phase; /* excitation model phase track */ + float bg_est; /* background noise estimate for post filter */ + MODEL prev_model; /* model parameters from 20ms ago */ +} CODEC2; + +void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]); +void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[]); + +int test1() +{ + FILE *fin, *fout; + short buf[N]; + void *c2; + CODEC2 *c3; + MODEL model; + float ak[LPC_ORD+1]; + float lsps[LPC_ORD]; + + c2 = codec2_create(); + c3 = (CODEC2*)c2; + + fin = fopen("../raw/hts1a.raw", "rb"); + assert(fin != NULL); + fout = fopen("hts1a_test.raw", "wb"); + assert(fout != NULL); + + while(fread(buf, sizeof(short), N, fin) == N) { + analyse_one_frame(c3, &model, buf); + speech_to_uq_lsps(lsps, ak, c3->Sn, c3->w, LPC_ORD); + synthesise_one_frame(c3, buf, &model, ak); + fwrite(buf, sizeof(short), N, fout); + } + + codec2_destroy(c2); + + fclose(fin); + fclose(fout); + + return 0; +} + +int test2() +{ + FILE *fin, *fout; + short buf[2*N]; + void *c2; + CODEC2 *c3; + MODEL model, model_interp; + float ak[LPC_ORD+1]; + int voiced1, voiced2; + int lsp_indexes[LPC_ORD]; + int lpc_correction; + int energy_index; + int Wo_index; + char bits[CODEC2_BITS_PER_FRAME]; + int nbit; + int i; + + c2 = codec2_create(); + c3 = (CODEC2*)c2; + + fin = fopen("../raw/hts1a.raw", "rb"); + assert(fin != NULL); + fout = fopen("hts1a_test.raw", "wb"); + assert(fout != NULL); + + while(fread(buf, sizeof(short), 2*N, fin) == 2*N) { + /* first 10ms analysis frame - we just want voicing */ + + analyse_one_frame(c3, &model, buf); + voiced1 = model.voiced; + + /* second 10ms analysis frame */ + + analyse_one_frame(c3, &model, &buf[N]); + voiced2 = model.voiced; + + Wo_index = encode_Wo(model.Wo); + encode_amplitudes(lsp_indexes, + &lpc_correction, + &energy_index, + &model, + c3->Sn, + c3->w); + nbit = 0; + pack(bits, &nbit, Wo_index, WO_BITS); + for(i=0; i<LPC_ORD; i++) { + pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); + } + pack(bits, &nbit, lpc_correction, 1); + pack(bits, &nbit, energy_index, E_BITS); + pack(bits, &nbit, voiced1, 1); + pack(bits, &nbit, voiced2, 1); + + nbit = 0; + Wo_index = unpack(bits, &nbit, WO_BITS); + for(i=0; i<LPC_ORD; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + lpc_correction = unpack(bits, &nbit, 1); + energy_index = unpack(bits, &nbit, E_BITS); + voiced1 = unpack(bits, &nbit, 1); + voiced2 = unpack(bits, &nbit, 1); + + model.Wo = decode_Wo(Wo_index); + model.L = PI/model.Wo; + decode_amplitudes(&model, + ak, + lsp_indexes, + lpc_correction, + energy_index); + + model.voiced = voiced2; + model_interp.voiced = voiced1; + interpolate(&model_interp, &c3->prev_model, &model); + + synthesise_one_frame(c3, buf, &model_interp, ak); + synthesise_one_frame(c3, &buf[N], &model, ak); + + memcpy(&c3->prev_model, &model, sizeof(MODEL)); + fwrite(buf, sizeof(short), 2*N, fout); + } + + codec2_destroy(c2); + + fclose(fin); + fclose(fout); + + return 0; +} + +int test3() +{ + FILE *fin, *fout, *fbits; + short buf1[2*N]; + short buf2[2*N]; + char bits[CODEC2_BITS_PER_FRAME]; + void *c2; + + c2 = codec2_create(); + + fin = fopen("../raw/hts1a.raw", "rb"); + assert(fin != NULL); + fout = fopen("hts1a_test.raw", "wb"); + assert(fout != NULL); + fbits = fopen("hts1a_test3.bit", "wb"); + assert(fout != NULL); + + while(fread(buf1, sizeof(short), 2*N, fin) == 2*N) { + codec2_encode(c2, bits, buf1); + fwrite(bits, sizeof(char), CODEC2_BITS_PER_FRAME, fbits); + codec2_decode(c2, buf2, bits); + fwrite(buf2, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout); + } + + codec2_destroy(c2); + + fclose(fin); + fclose(fout); + fclose(fbits); + + return 0; +} + +int main() { + test3(); + return 0; +} diff --git a/libs/libcodec2/unittest/tcontphase.c b/libs/libcodec2/unittest/tcontphase.c new file mode 100644 index 0000000000..ee2f662a48 --- /dev/null +++ b/libs/libcodec2/unittest/tcontphase.c @@ -0,0 +1,187 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: tcontphase.c + AUTHOR......: David Rowe + DATE CREATED: 11/9/09 + + Test program for developing continuous phase track synthesis algorithm. + However while developing this it was discovered that synthesis_mixed() + worked just as well. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define N 80 /* frame size */ +#define F 160 /* frames to synthesis */ +#define P 10 /* LPC order */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include "sine.h" +#include "dump.h" +#include "synth.h" +#include "phase.h" + +int frames; + +float ak[] = { + 1.000000, +-1.455836, + 1.361841, +-0.879267, + 0.915985, +-1.002202, + 0.944103, +-0.743094, + 1.053356, +-0.817491, + 0.431222 +}; + + +/*---------------------------------------------------------------------------*\ + + switch_present() + + Searches the command line arguments for a "switch". If the switch is + found, returns the command line argument where it ws found, else returns + NULL. + +\*---------------------------------------------------------------------------*/ + +int switch_present(sw,argc,argv) + char sw[]; /* switch in string form */ + int argc; /* number of command line arguments */ + char *argv[]; /* array of command line arguments in string form */ +{ + int i; /* loop variable */ + + for(i=1; i<argc; i++) + if (!strcmp(sw,argv[i])) + return(i); + + return 0; +} + +/*---------------------------------------------------------------------------*\ + + MAIN + +\*---------------------------------------------------------------------------*/ + +int main(argc,argv) +int argc; +char *argv[]; +{ + FILE *fout; + short buf[N]; + int i,j; + int dump; + float phi_prev[MAX_AMP]; + float Wo_prev, ex_phase, G; + //float ak[P+1]; + COMP H[MAX_AMP]; + float f0; + + if (argc < 3) { + printf("\nusage: tcontphase OutputRawSpeechFile F0\n"); + exit(0); + } + + /* Output file */ + + if ((fout = fopen(argv[1],"wb")) == NULL) { + printf("Error opening output speech file: %s\n",argv[1]); + exit(1); + } + + f0 = atof(argv[2]); + + dump = switch_present("--dump",argc,argv); + if (dump) + dump_on(argv[dump+1]); + + init_decoder(); + + for(i=0; i<MAX_AMP; i++) + phi_prev[i] = 0.0; + Wo_prev = 0.0; + + model.Wo = PI*(f0/4000.0); + G = 1000.0; + model.L = floor(PI/model.Wo); + + //aks_to_H(&model, ak, G , H, P); + //for(i=1; i<=model.L; i++) + model.A[i] = sqrt(H[i].real*H[i].real + H[i].imag*H[i].imag); + //printf("L = %d\n", model.L); + //model.L = 10; + for(i=1; i<=model.L; i++) { + model.A[i] = 1000/model.L; + model.phi[i] = 0; + H[i].real = 1.0; H[i].imag = 0.0; + } + + //ak[0] = 1.0; + //for(i=1; i<=P; i++) + // ak[i] = 0.0; + + frames = 0; + for(j=0; j<F; j++) { + frames++; + + #ifdef SWAP + /* lets make phases bounce around from frame to frame. This + could happen if H[m] is varying, for example due to frame + to frame Wo variations, or non-stationary speech. + Continous model generally results in smooth phase track + under these circumstances. */ + if (j%2){ + H[1].real = 1.0; H[1].imag = 0.0; + model.phi[1] = 0.0; + } + else { + H[1].real = 0.0; H[1].imag = 1.0; + model.phi[1] = PI/2; + } + #endif + + //#define CONT + #ifdef CONT + synthesise_continuous_phase(Pn, &model, Sn_, 1, &Wo_prev, phi_prev); + #else + phase_synth_zero_order(5.0, H, &Wo_prev, &ex_phase); + synthesise_mixed(Pn,&model,Sn_,1); + #endif + + for(i=0; i<N; i++) + buf[i] = Sn_[i]; + fwrite(buf,sizeof(short),N,fout); + } + + fclose(fout); + if (dump) dump_off(); + + return 0; +} + + diff --git a/libs/libcodec2/unittest/tinterp.c b/libs/libcodec2/unittest/tinterp.c new file mode 100644 index 0000000000..7bb37c5258 --- /dev/null +++ b/libs/libcodec2/unittest/tinterp.c @@ -0,0 +1,128 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: tinterp.c + AUTHOR......: David Rowe + DATE CREATED: 22/8/10 + + Tests interpolation functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <ctype.h> + +#include "defines.h" +#include "sine.h" +#include "interp.h" + +void make_amp(MODEL *model, float f0, float cdB, float mdBHz) +{ + int i; + float mdBrad = mdBHz*FS/TWO_PI; + + model->Wo = f0*TWO_PI/FS; + model->L = PI/model->Wo; + for(i=0; i<=model->L; i++) + model->A[i] = pow(10.0,(cdB + (float)i*model->Wo*mdBrad)/20.0); + model->voiced = 1; +} + +void write_amp(char file[], MODEL *model) +{ + FILE *f; + int i; + + f = fopen(file,"wt"); + for(i=1; i<=model->L; i++) + fprintf(f, "%f\t%f\n", model->Wo*i, model->A[i]); + fclose(f); +} + +char *get_next_float(char *s, float *num) +{ + char *p = s; + char tmp[MAX_STR]; + + while(*p && !isspace(*p)) + p++; + memcpy(tmp, s, p-s); + tmp[p-s] = 0; + *num = atof(tmp); + + return p+1; +} + +char *get_next_int(char *s, int *num) +{ + char *p = s; + char tmp[MAX_STR]; + + while(*p && !isspace(*p)) + p++; + memcpy(tmp, s, p-s); + tmp[p-s] = 0; + *num = atoi(tmp); + + return p+1; +} + +void load_amp(MODEL *model, char file[], int frame) +{ + FILE *f; + int i; + char s[1024]; + char *ps; + + f = fopen(file,"rt"); + + for(i=0; i<frame; i++) + fgets(s, 1023, f); + + ps = s; + ps = get_next_float(ps, &model->Wo); + ps = get_next_int(ps, &model->L); + for(i=1; i<=model->L; i++) + ps = get_next_float(ps, &model->A[i]); + + fclose(f); +} + +int main() { + MODEL prev, next, interp; + + //make_amp(&prev, 50.0, 60.0, 6E-3); + //make_amp(&next, 50.0, 40.0, 6E-3); + load_amp(&prev, "../src/hts1a_model.txt", 32); + load_amp(&next, "../src/hts1a_model.txt", 34); + + interp.voiced = 1; + interpolate(&interp, &prev, &next); + + write_amp("tinterp_prev.txt", &prev); + write_amp("tinterp_interp.txt", &interp); + write_amp("tinterp_next.txt", &next); + + return 0; +} diff --git a/libs/libcodec2/unittest/tnlp.c b/libs/libcodec2/unittest/tnlp.c new file mode 100644 index 0000000000..4abf69c4ef --- /dev/null +++ b/libs/libcodec2/unittest/tnlp.c @@ -0,0 +1,148 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: tnlp.c + AUTHOR......: David Rowe + DATE CREATED: 23/3/93 + + Test program for non linear pitch estimation functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define N 80 /* frame size */ +#define M 320 /* pitch analysis window size */ +#define PITCH_MIN 20 +#define PITCH_MAX 160 +#define TNLP + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include "defines.h" +#include "dump.h" +#include "sine.h" +#include "nlp.h" + +int frames; + +/*---------------------------------------------------------------------------*\ + + switch_present() + + Searches the command line arguments for a "switch". If the switch is + found, returns the command line argument where it ws found, else returns + NULL. + +\*---------------------------------------------------------------------------*/ + +int switch_present(sw,argc,argv) + char sw[]; /* switch in string form */ + int argc; /* number of command line arguments */ + char *argv[]; /* array of command line arguments in string form */ +{ + int i; /* loop variable */ + + for(i=1; i<argc; i++) + if (!strcmp(sw,argv[i])) + return(i); + + return 0; +} + +/*---------------------------------------------------------------------------*\ + + MAIN + +\*---------------------------------------------------------------------------*/ + +int main(argc,argv) +int argc; +char *argv[]; +{ + FILE *fin,*fout; + short buf[N]; + float Sn[M]; /* float input speech samples */ + COMP Sw[FFT_ENC]; /* DFT of Sn[] */ + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + float pitch; + int i; + int dump; + float prev_Wo; + void *nlp_states; + + if (argc < 3) { + printf("\nusage: tnlp InputRawSpeechFile OutputPitchTextFile " + "[--dump DumpFile]\n"); + exit(0); + } + + /* Input file */ + + if ((fin = fopen(argv[1],"rb")) == NULL) { + printf("Error opening input speech file: %s\n",argv[1]); + exit(1); + } + + /* Output file */ + + if ((fout = fopen(argv[2],"wt")) == NULL) { + printf("Error opening output text file: %s\n",argv[2]); + exit(1); + } + + dump = switch_present("--dump",argc,argv); + if (dump) + dump_on(argv[dump+1]); + + nlp_states = nlp_create(); + make_analysis_window(w,W); + + frames = 0; + prev_Wo = 0; + while(fread(buf,sizeof(short),N,fin)) { + printf("%d\n", frames++); + + /* Update input speech buffers */ + + for(i=0; i<M-N; i++) + Sn[i] = Sn[i+N]; + for(i=0; i<N; i++) + Sn[i+M-N] = buf[i]; + dft_speech(Sw, Sn, w); + dump_Sn(Sn); dump_Sw(Sw); + + nlp(nlp_states,Sn,N,M,PITCH_MIN,PITCH_MAX,&pitch,Sw,&prev_Wo); + prev_Wo = TWO_PI/pitch; + + fprintf(fout,"%f\n",pitch); + } + + fclose(fin); + fclose(fout); + if (dump) dump_off(); + nlp_destroy(nlp_states); + + return 0; +} + + diff --git a/libs/libcodec2/unittest/tquant.c b/libs/libcodec2/unittest/tquant.c new file mode 100644 index 0000000000..1ff7564145 --- /dev/null +++ b/libs/libcodec2/unittest/tquant.c @@ -0,0 +1,215 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: tquant.c + AUTHOR......: David Rowe + DATE CREATED: 22/8/10 + + Generates quantisation curves for plotting on Octave. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include "defines.h" +#include "dump.h" +#include "quantise.h" + +int test_Wo_quant(); +int test_lsp_quant(); +int test_lsp(int lsp_number, int levels, float max_error_hz); +int test_energy_quant(int levels, float max_error_dB); + +int main() { + quantise_init(); + test_Wo_quant(); + test_lsp_quant(); + test_energy_quant(E_LEVELS, 0.5*(E_MAX_DB - E_MIN_DB)/E_LEVELS); + + return 0; +} + +int test_lsp_quant() { + test_lsp( 1, 16, 12.5); + test_lsp( 2, 16, 12.5); + test_lsp( 3, 16, 25); + test_lsp( 4, 16, 50); + test_lsp( 5, 16, 50); + test_lsp( 6, 16, 50); + test_lsp( 7, 16, 50); + test_lsp( 8, 8, 50); + test_lsp( 9, 8, 50); + test_lsp(10, 4, 100); + + return 0; +} + +int test_energy_quant(int levels, float max_error_dB) { + FILE *fe; + float e,e_dec, error, low_e, high_e; + int index, index_in, index_out, i; + + /* check 1:1 match between input and output levels */ + + for(i=0; i<levels; i++) { + index_in = i; + e = decode_energy(index_in); + index_out = encode_energy(e); + if (index_in != index_out) { + printf("edB: %f index_in: %d index_out: %d\n", + 10.0*log10(e), index_in, index_out); + exit(0); + } + } + + /* check error over range of quantiser */ + + low_e = decode_energy(0); + high_e = decode_energy(levels-1); + fe = fopen("energy_err.txt", "wt"); + + for(e=low_e; e<high_e; e +=(high_e-low_e)/1000.0) { + index = encode_energy(e); + e_dec = decode_energy(index); + error = 10.0*log10(e) - 10.0*log10(e_dec); + fprintf(fe, "%f\n", error); + if (fabs(error) > max_error_dB) { + printf("error: %f %f\n", error, max_error_dB); + exit(0); + } + } + + fclose(fe); + return 0; +} + +int test_lsp(int lsp_number, int levels, float max_error_hz) { + float lsp[LPC_ORD]; + int indexes_in[LPC_ORD]; + int indexes_out[LPC_ORD]; + int indexes[LPC_ORD]; + int i; + float lowf, highf, f, error; + char s[MAX_STR]; + FILE *flsp; + float max_error_rads; + + lsp_number--; + max_error_rads = max_error_hz*TWO_PI/FS; + + for(i=0; i<LPC_ORD; i++) + indexes_in[i] = 0; + + for(i=0; i<levels; i++) { + indexes_in[lsp_number] = i; + decode_lsps(lsp, indexes_in, LPC_ORD); + encode_lsps(indexes_out, lsp,LPC_ORD); + if (indexes_in[lsp_number] != indexes_out[lsp_number]) { + printf("freq: %f index_in: %d index_out: %d\n", + lsp[lsp_number]+1, indexes_in[lsp_number], + indexes_out[lsp_number]); + exit(0); + } + } + + for(i=0; i<LPC_ORD; i++) + indexes[i] = 0; + indexes[lsp_number] = 0; + decode_lsps(lsp, indexes, LPC_ORD); + lowf = lsp[lsp_number]; + indexes[lsp_number] = levels - 1; + decode_lsps(lsp, indexes, LPC_ORD); + highf = lsp[lsp_number]; + sprintf(s,"lsp%d_err.txt", lsp_number+1); + flsp = fopen(s, "wt"); + + for(f=lowf; f<highf; f +=(highf-lowf)/1000.0) { + lsp[lsp_number] = f; + encode_lsps(indexes, lsp, LPC_ORD); + decode_lsps(lsp, indexes, LPC_ORD); + error = f - lsp[lsp_number]; + fprintf(flsp, "%f\n", error); + if (fabs(error) > max_error_rads) { + printf("%d error: %f %f\n", lsp_number+1, error, max_error_rads); + exit(0); + } + } + + fclose(flsp); + + printf("OK\n"); + + return 0; +} + +int test_Wo_quant() { + int c; + FILE *f; + float Wo,Wo_dec, error, step_size; + int index, index_in, index_out; + + /* output Wo quant curve for plotting */ + + f = fopen("quant_pitch.txt","wt"); + + for(Wo=0.9*(TWO_PI/P_MAX); Wo<=1.1*(TWO_PI/P_MIN); Wo += 0.001) { + index = encode_Wo(Wo); + fprintf(f, "%f %d\n", Wo, index); + } + + fclose(f); + + /* check for all Wo codes we get 1:1 match between encoder + and decoder Wo levels */ + + for(c=0; c<WO_LEVELS; c++) { + index_in = c; + Wo = decode_Wo(index_in); + index_out = encode_Wo(Wo); + if (index_in != index_out) + printf(" Wo %f index_in %d index_out %d\n", Wo, + index_in, index_out); + } + + /* measure quantisation error stats and compare to expected. Also + plot histogram of error file to check. */ + + f = fopen("quant_pitch_err.txt","wt"); + step_size = ((TWO_PI/P_MIN) - (TWO_PI/P_MAX))/WO_LEVELS; + + for(Wo=TWO_PI/P_MAX; Wo<0.99*TWO_PI/P_MIN; Wo += 0.0001) { + index = encode_Wo(Wo); + Wo_dec = decode_Wo(index); + error = Wo - Wo_dec; + if (fabs(error) > (step_size/2.0)) { + printf("error: %f step_size/2: %f\n", error, step_size/2.0); + exit(0); + } + fprintf(f,"%f\n",error); + } + printf("OK\n"); + + fclose(f); + return 0; +} diff --git a/libs/libcodec2/unittest/vqtrain.c b/libs/libcodec2/unittest/vqtrain.c new file mode 100644 index 0000000000..b46d4fcf30 --- /dev/null +++ b/libs/libcodec2/unittest/vqtrain.c @@ -0,0 +1,297 @@ +/*--------------------------------------------------------------------------*\ + + FILE........: VQTRAIN.C + AUTHOR......: David Rowe + DATE CREATED: 23/2/95 + + This program trains vector quantisers using K dimensional Lloyd-Max + method. + +\*--------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/*-----------------------------------------------------------------------*\ + + INCLUDES + +\*-----------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <ctype.h> + +/*-----------------------------------------------------------------------*\ + + DEFINES + +\*-----------------------------------------------------------------------*/ + +#define DELTAQ 0.01 /* quiting distortion */ +#define MAX_STR 80 /* maximum string length */ + +/*-----------------------------------------------------------------------*\ + + FUNCTION PROTOTYPES + +\*-----------------------------------------------------------------------*/ + +void zero(float v[], int k); +void acc(float v1[], float v2[], int k); +void norm(float v[], int k, long n); +long quantise(float cb[], float vec[], int k, int m, float *se); + +/*-----------------------------------------------------------------------*\ + + MAIN + +\*-----------------------------------------------------------------------*/ + +int main(int argc, char *argv[]) { + long k,m; /* dimension and codebook size */ + float *vec; /* current vector */ + float *cb; /* vector codebook */ + float *cent; /* centroids for each codebook entry */ + long *n; /* number of vectors in this interval */ + long J; /* number of vectors in training set */ + long i,j; + long ind; /* index of current vector */ + float se; /* squared error for this iteration */ + float Dn,Dn_1; /* current and previous iterations distortion */ + float delta; /* improvement in distortion */ + FILE *ftrain; /* file containing training set */ + FILE *fvq; /* file containing vector quantiser */ + + /* Interpret command line arguments */ + + if (argc != 5) { + printf("usage: vqtrain TrainFile K M VQFile\n"); + exit(0); + } + + /* Open training file */ + + ftrain = fopen(argv[1],"rb"); + if (ftrain == NULL) { + printf("Error opening training database file: %s\n",argv[1]); + exit(1); + } + + /* determine k and m, and allocate arrays */ + + k = atol(argv[2]); + m = atol(argv[3]); + printf("dimension K=%ld number of entries M=%ld\n", k,m); + vec = (float*)malloc(sizeof(float)*k); + cb = (float*)malloc(sizeof(float)*k*m); + cent = (float*)malloc(sizeof(float)*k*m); + n = (long*)malloc(sizeof(long)*m); + if (cb == NULL || cb == NULL || cent == NULL || vec == NULL) { + printf("Error in malloc.\n"); + exit(1); + } + + /* determine size of training set */ + + J = 0; + while(fread(vec, sizeof(float), k, ftrain) == k) + J++; + printf("J=%ld entries in training set\n", J); + + /* set up initial codebook state from samples of training set */ + + rewind(ftrain); + fread(cb, sizeof(float), k*m, ftrain); + + /* main loop */ + + Dn = 1E32; + j = 1; + do { + Dn_1 = Dn; + + /* zero centroids */ + + for(i=0; i<m; i++) { + zero(¢[i*k], k); + n[i] = 0; + } + + /* quantise training set */ + + se = 0.0; + rewind(ftrain); + for(i=0; i<J; i++) { + fread(vec, sizeof(float), k, ftrain); + ind = quantise(cb, vec, k, m, &se); + n[ind]++; + acc(¢[ind*k], vec, k); + } + Dn = se/J; + delta = (Dn_1-Dn)/Dn; + + printf("\r Iteration %ld, Dn = %f, Delta = %e\n", j, Dn, delta); + j++; + + /* determine new codebook from centriods */ + + if (delta > DELTAQ) + for(i=0; i<m; i++) { + if (n[i] != 0) { + norm(¢[i*k], k, n[i]); + memcpy(&cb[i*k], ¢[i*k], k*sizeof(float)); + } + } + + } while (delta > DELTAQ); + + /* save codebook to disk */ + + fvq = fopen(argv[4],"wt"); + if (fvq == NULL) { + printf("Error opening VQ file: %s\n",argv[4]); + exit(1); + } + + for(j=0; j<m; j++) { + for(i=0; i<k; i++) + fprintf(fvq,"%f ",cb[j*k+i]); + fprintf(fvq,"\n"); + } + fclose(fvq); + + return 0; +} + +/*-----------------------------------------------------------------------*\ + + FUNCTIONS + +\*-----------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: zero() + + AUTHOR......: David Rowe + DATE CREATED: 23/2/95 + + Zeros a vector of length k. + +\*---------------------------------------------------------------------------*/ + +void zero(float v[], int k) +/* float v[]; ptr to start of vector */ +/* int k; lngth of vector */ +{ + int i; + + for(i=0; i<k; i++) + v[i] = 0.0; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: acc() + + AUTHOR......: David Rowe + DATE CREATED: 23/2/95 + + Adds k dimensional vectors v1 to v2 and stores the result back in v1. + +\*---------------------------------------------------------------------------*/ + +void acc(float v1[], float v2[], int k) +/* float v1[]; ptr to start of vector to accumulate */ +/* float v2[]; ptr to start of vector to add */ +/* int k; dimension of vectors */ +{ + int i; + + for(i=0; i<k; i++) + v1[i] += v2[i]; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: norm() + + AUTHOR......: David Rowe + DATE CREATED: 23/2/95 + + Divides each element in k dimensional vector v by n. + +\*---------------------------------------------------------------------------*/ + +void norm(float v[], int k, long n) +/* float v[]; ptr to start of vector */ +/* int k; dimension of vectors */ +/* int n; normalising factor */ +{ + int i; + + for(i=0; i<k; i++) + v[i] /= n; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: quantise() + + AUTHOR......: David Rowe + DATE CREATED: 23/2/95 + + Quantises vec by choosing the nearest vector in codebook cb, and + returns the vector index. The squared error of the quantised vector + is added to se. + +\*---------------------------------------------------------------------------*/ + +long quantise(float cb[], float vec[], int k, int m, float *se) +/* float cb[][K]; current VQ codebook */ +/* float vec[]; vector to quantise */ +/* int k; dimension of vectors */ +/* int m; size of codebook */ +/* float *se; accumulated squared error */ +{ + float e; /* current error */ + long besti; /* best index so far */ + float beste; /* best error so far */ + long j; + int i; + + besti = 0; + beste = 1E32; + for(j=0; j<m; j++) { + e = 0.0; + for(i=0; i<k; i++) + e += pow(cb[j*k+i]-vec[i],2.0); + if (e < beste) { + beste = e; + besti = j; + } + } + + *se += beste; + + return(besti); +} + diff --git a/libs/libcodec2/wav/f2400.wav b/libs/libcodec2/wav/f2400.wav new file mode 100644 index 0000000000..35c41d9eac Binary files /dev/null and b/libs/libcodec2/wav/f2400.wav differ diff --git a/libs/libcodec2/wav/forig.wav b/libs/libcodec2/wav/forig.wav new file mode 100644 index 0000000000..81f3f9fc81 Binary files /dev/null and b/libs/libcodec2/wav/forig.wav differ diff --git a/libs/libcodec2/wav/forig_speex_8k.wav b/libs/libcodec2/wav/forig_speex_8k.wav new file mode 100644 index 0000000000..ac816f9c94 Binary files /dev/null and b/libs/libcodec2/wav/forig_speex_8k.wav differ diff --git a/libs/libcodec2/wav/hts1a.wav b/libs/libcodec2/wav/hts1a.wav new file mode 100644 index 0000000000..f605089144 Binary files /dev/null and b/libs/libcodec2/wav/hts1a.wav differ diff --git a/libs/libcodec2/wav/hts1a_c2_v0.1.wav b/libs/libcodec2/wav/hts1a_c2_v0.1.wav new file mode 100644 index 0000000000..f41c70cb90 Binary files /dev/null and b/libs/libcodec2/wav/hts1a_c2_v0.1.wav differ diff --git a/libs/libcodec2/wav/hts1a_g729a.wav b/libs/libcodec2/wav/hts1a_g729a.wav new file mode 100644 index 0000000000..f475775bbd Binary files /dev/null and b/libs/libcodec2/wav/hts1a_g729a.wav differ diff --git a/libs/libcodec2/wav/hts1a_speex_8k.wav b/libs/libcodec2/wav/hts1a_speex_8k.wav new file mode 100644 index 0000000000..c192ee0234 Binary files /dev/null and b/libs/libcodec2/wav/hts1a_speex_8k.wav differ diff --git a/libs/libcodec2/wav/hts2a.wav b/libs/libcodec2/wav/hts2a.wav new file mode 100644 index 0000000000..644b536828 Binary files /dev/null and b/libs/libcodec2/wav/hts2a.wav differ diff --git a/libs/libcodec2/wav/hts2a_c2_v0.1.wav b/libs/libcodec2/wav/hts2a_c2_v0.1.wav new file mode 100644 index 0000000000..7f0e0f1e29 Binary files /dev/null and b/libs/libcodec2/wav/hts2a_c2_v0.1.wav differ diff --git a/libs/libcodec2/wav/hts2a_g729a.wav b/libs/libcodec2/wav/hts2a_g729a.wav new file mode 100644 index 0000000000..7709a1cd5d Binary files /dev/null and b/libs/libcodec2/wav/hts2a_g729a.wav differ diff --git a/libs/libcodec2/wav/hts2a_speex_8k.wav b/libs/libcodec2/wav/hts2a_speex_8k.wav new file mode 100644 index 0000000000..98293b602c Binary files /dev/null and b/libs/libcodec2/wav/hts2a_speex_8k.wav differ diff --git a/libs/libcodec2/wav/m2400.wav b/libs/libcodec2/wav/m2400.wav new file mode 100644 index 0000000000..a1fe1a5f27 Binary files /dev/null and b/libs/libcodec2/wav/m2400.wav differ diff --git a/libs/libcodec2/wav/mmt1.wav b/libs/libcodec2/wav/mmt1.wav new file mode 100644 index 0000000000..b0526cbdda Binary files /dev/null and b/libs/libcodec2/wav/mmt1.wav differ diff --git a/libs/libcodec2/wav/mmt1_speex_8k.wav b/libs/libcodec2/wav/mmt1_speex_8k.wav new file mode 100644 index 0000000000..f0191a2630 Binary files /dev/null and b/libs/libcodec2/wav/mmt1_speex_8k.wav differ diff --git a/libs/libcodec2/wav/morig.wav b/libs/libcodec2/wav/morig.wav new file mode 100644 index 0000000000..eaf52d18f0 Binary files /dev/null and b/libs/libcodec2/wav/morig.wav differ diff --git a/libs/libcodec2/wav/morig_speex_8k.wav b/libs/libcodec2/wav/morig_speex_8k.wav new file mode 100644 index 0000000000..d62d19b225 Binary files /dev/null and b/libs/libcodec2/wav/morig_speex_8k.wav differ diff --git a/libs/libteletone/src/libteletone_generate.c b/libs/libteletone/src/libteletone_generate.c index 911e3c2797..3977ca521d 100644 --- a/libs/libteletone/src/libteletone_generate.c +++ b/libs/libteletone/src/libteletone_generate.c @@ -302,7 +302,7 @@ TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone ts->samples * 2); } } - return ts->samples; + return ts->samples / ts->channels; } /* don't ask */ @@ -413,6 +413,9 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm *e++ = '\0'; } do { + if (!p) { + break; + } if ((next = strchr(p, ',')) != 0) { *next++ = '\0'; } diff --git a/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c b/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c index 0eaf955196..ca42c2c578 100644 --- a/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c +++ b/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c @@ -977,7 +977,7 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) */ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) { - uint32_t i, event_id = 0; + uint32_t i, event_id = ZAP_OOB_INVALID; zt_event_t zt_event_id = 0; for(i = 1; i <= span->chan_count; i++) { @@ -1025,6 +1025,8 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) event_id = ZAP_OOB_OFFHOOK; } else if (span->channels[i]->type == ZAP_CHAN_TYPE_FXO) { event_id = ZAP_OOB_RING_START; + } else { + event_id = ZAP_OOB_NOOP; } } break; diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c index 7d37a493c4..283a9fe332 100644 --- a/libs/openzap/src/zap_io.c +++ b/libs/openzap/src/zap_io.c @@ -1017,6 +1017,7 @@ OZ_DECLARE(zap_status_t) zap_channel_set_state(zap_channel_t *zchan, zap_channel case ZAP_CHANNEL_STATE_RING: case ZAP_CHANNEL_STATE_PROGRESS_MEDIA: case ZAP_CHANNEL_STATE_PROGRESS: + case ZAP_CHANNEL_STATE_IDLE: case ZAP_CHANNEL_STATE_GET_CALLERID: case ZAP_CHANNEL_STATE_GENRING: ok = 1; diff --git a/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h b/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h index d5bb617914..bd42743c9f 100644 --- a/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h +++ b/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h @@ -58,7 +58,11 @@ SOFIA_BEGIN_DECLS #define HTTP_DEFAULT_SERV "80" /** HTTP protocol identifier */ +#ifndef _MSC_VER #define HTTP_PROTOCOL_TAG ((void *)0x48545450) /* 'HTTP' */ +#else +#define HTTP_PROTOCOL_TAG ((void *)(UINT_PTR)0x48545450) /* 'HTTP' */ +#endif /** HTTP parser flags */ enum { diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c index 2be30b04b9..061cd5ef2a 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c +++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c @@ -50,7 +50,11 @@ #include <sofia-sip/su_tagarg.h> #include "sofia-sip/msg_tag_class.h" +#ifndef _MSC_VER #define NONE ((void*)-1) +#else +#define NONE ((void*)(INT_PTR)-1) +#endif int msghdrtag_snprintf(tagi_t const *t, char b[], size_t size) { diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h index 91fd72316b..c633aa3632 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h +++ b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h @@ -299,7 +299,12 @@ enum { (h)) /** No header. */ + +#ifndef _MSC_VER #define MSG_HEADER_NONE ((msg_header_t *)-1) +#else +#define MSG_HEADER_NONE ((msg_header_t *)(INT_PTR)-1) +#endif SOFIA_END_DECLS diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h index 4a9f234dec..033c551fdb 100644 --- a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h +++ b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h @@ -235,7 +235,11 @@ msg_content_length_t *msg_content_length_create(su_home_t *home, uint32_t n); SOFIAPUBVAR char const msg_mime_version_1_0[]; /** MIME multipart parser table identifier. @HIDE */ +#ifndef _MSC_VER #define MSG_MULTIPART_PROTOCOL_TAG ((void *)0x4d494d45) /* 'MIME' */ +#else +#define MSG_MULTIPART_PROTOCOL_TAG ((void *)(UINT_PTR)0x4d494d45) /* 'MIME' */ +#endif SOFIA_END_DECLS diff --git a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c index 4287ae4359..a6c7d49ac6 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c +++ b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c @@ -41,7 +41,11 @@ #include "nea_debug.h" +#ifndef _MSC_VER #define NONE ((void *)- 1) +#else +#define NONE ((void *)(INT_PTR)- 1) +#endif #define SU_ROOT_MAGIC_T struct nea_server_s #define SU_MSG_ARG_T tagi_t diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c index 656aecc195..40ee1f8f85 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c +++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c @@ -104,8 +104,11 @@ char const nta_version[] = PACKAGE_VERSION; static char const __func__[] = "nta"; #endif +#ifndef _MSC_VER #define NONE ((void *)-1) - +#else +#define NONE ((void *)(INT_PTR)-1) +#endif /* ------------------------------------------------------------------------- */ /** Resolving order */ diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c index bf35263d92..b96b1f31c0 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c @@ -53,7 +53,12 @@ #include <sofia-sip/su_debug.h> #ifndef NONE + +#ifndef _MSC_VER #define NONE ((void *)-1) +#else +#define NONE ((void *)(INT_PTR)-1) +#endif #endif /* ======================================================================== */ diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h index 318ccdd61d..97c88582a3 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h @@ -83,7 +83,11 @@ typedef struct nua_ee_data { nua_event_data_t ee_data[1]; } nua_ee_data_t; +#ifndef _MSC_VER #define NONE ((void *)-1) +#else +#define NONE ((void *)(INT_PTR)-1) +#endif typedef struct register_usage nua_registration_t; diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h b/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h index 1a235ca4c8..37ae836598 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h +++ b/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h @@ -81,10 +81,18 @@ typedef enum { #define SIP_METHOD_PUBLISH sip_method_publish, "PUBLISH" /** Magic pointer value - never valid for SIP headers. @HI */ +#ifndef _MSC_VER #define SIP_NONE ((void const *)-1L) +#else +#define SIP_NONE ((void const *)(INT_PTR)-1L) +#endif /** SIP protocol identifier @HIDE */ +#ifndef _MSC_VER #define SIP_PROTOCOL_TAG ((void *)0x53495020) /* 'SIP'20 */ +#else +#define SIP_PROTOCOL_TAG ((void *)(UINT_PTR)0x53495020) /* 'SIP'20 */ +#endif enum { /** Default port for SIP as integer */ diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa.c index de79e0f3a5..7f272a8e6f 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa.c @@ -56,7 +56,11 @@ #include <sofia-sip/su_string.h> #include <sofia-sip/su_errno.h> +#ifndef _MSC_VER #define NONE ((void *)-1) +#else +#define NONE ((void *)(INT_PTR)-1) +#endif #define XXX assert(!"implemented") typedef unsigned longlong ull; diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c index f94f9b2962..f104274ef4 100644 --- a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c +++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c @@ -396,7 +396,11 @@ sdp_rtpmap_t *soa_sdp_media_matching_rtpmap(sdp_rtpmap_t const *from, return NULL; } +#ifndef _MSC_VER #define SDP_MEDIA_NONE ((sdp_media_t *)-1) +#else +#define SDP_MEDIA_NONE ((sdp_media_t *)(INT_PTR)-1) +#endif /** Find first matching media in table @a mm. * diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c index f660b2ce22..e494571f54 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c +++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c @@ -125,7 +125,7 @@ su_inline ssize_t sres_recvfrom(sres_socket_t s, void *buffer, size_t length, int flags, struct sockaddr *from, socklen_t *fromlen) { - int retval, ilen; + int retval, ilen = 0; if (fromlen) ilen = *fromlen; diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su.c b/libs/sofia-sip/libsofia-sip-ua/su/su.c index 250b5d62d1..8067fdec60 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su.c @@ -434,7 +434,7 @@ ssize_t su_recv(su_socket_t s, void *buffer, size_t length, int flags) ssize_t su_recvfrom(su_socket_t s, void *buffer, size_t length, int flags, su_sockaddr_t *from, socklen_t *fromlen) { - int retval, ilen; + int retval, ilen = 0; if (fromlen) ilen = *fromlen; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h b/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h index b56dd2d9bc..683b79a360 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h @@ -79,7 +79,11 @@ #endif #ifndef NONE +#ifndef _MSC_VER #define NONE ((void *)-1) +#else +#define NONE ((void *)(INT_PTR)-1) +#endif #endif SOFIA_BEGIN_DECLS diff --git a/libs/spandsp/src/spandsp/private/t30.h b/libs/spandsp/src/spandsp/private/t30.h index e56753e07d..b8a2e8be1c 100644 --- a/libs/spandsp/src/spandsp/private/t30.h +++ b/libs/spandsp/src/spandsp/private/t30.h @@ -60,10 +60,8 @@ struct t30_state_s int supported_t30_features; /*! \brief TRUE is ECM mode handling is enabled. */ int ecm_allowed; -#if 0 /*! \brief TRUE if we are capable of retransmitting pages */ int retransmit_capable; -#endif /*! \brief The received DCS, formatted as an ASCII string, for inclusion in the TIFF file. */ @@ -71,12 +69,12 @@ struct t30_state_s /*! \brief The text which will be used in FAX page header. No text results in no header line. */ char header_info[T30_MAX_PAGE_HEADER_INFO + 1]; -#if 0 /*! \brief TRUE for FAX page headers to overlay (i.e. replace) the beginning of the page image. FALSE for FAX page headers to add to the overall length of the page. */ int header_overlays_image; -#endif + /*! \brief TRUE if remote T.30 procedural interrupts are allowed. */ + int remote_interrupts_allowed; /*! \brief The information fields received. */ t30_exchanged_info_t rx_info; @@ -207,13 +205,6 @@ struct t30_state_s /*! \brief This is only used in full duplex (e.g. ISDN) modes. */ int timer_t8; - /* These fields are guessed based on compiler error forensics, I added them to fix the build -anthm */ - int remote_interrupts_allowed; - int rtp_events; - int rtn_events; - int retransmit_capable; - /* end guessed fields */ - /*! \brief TRUE once the far end FAX entity has been detected. */ int far_end_detected; @@ -283,12 +274,10 @@ struct t30_state_s /*! \brief The current completion status. */ int current_status; -#if 0 /*! \brief The number of RTP events */ int rtp_events; /*! \brief The number of RTN events */ int rtn_events; -#endif /*! \brief the FCF2 field of the last PPS message we received. */ uint8_t last_pps_fcf2; diff --git a/libs/spandsp/src/spandsp/t30.h b/libs/spandsp/src/spandsp/t30.h index 9df7321abd..a2fff2d28c 100644 --- a/libs/spandsp/src/spandsp/t30.h +++ b/libs/spandsp/src/spandsp/t30.h @@ -682,6 +682,10 @@ SPAN_DECLARE(void) t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t); \param state TRUE to enable interrupt request, else FALSE. */ SPAN_DECLARE(void) t30_local_interrupt_request(t30_state_t *s, int state); +/*! Allow remote interrupts of FAX exchange. + \brief Allow remote interrupts of FAX exchange. + \param s The T.30 context. + \param state TRUE to allow interruptd, else FALSE. */ SPAN_DECLARE(void) t30_remote_interrupts_allowed(t30_state_t *s, int state); #if defined(__cplusplus) diff --git a/libs/win32/openssl/libeay32.2010.vcxproj b/libs/win32/openssl/libeay32.2010.vcxproj index 1157e5ca87..4d0d9a44ee 100644 --- a/libs/win32/openssl/libeay32.2010.vcxproj +++ b/libs/win32/openssl/libeay32.2010.vcxproj @@ -74,6 +74,10 @@ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(PlatformName)\libeay32\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(PlatformName)\libeay32\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\libeay32\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\libeay32\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PreBuildEvent> diff --git a/libs/win32/openssl/ssleay32.2010.vcxproj b/libs/win32/openssl/ssleay32.2010.vcxproj index 8d6c22df18..1a444bb41f 100644 --- a/libs/win32/openssl/ssleay32.2010.vcxproj +++ b/libs/win32/openssl/ssleay32.2010.vcxproj @@ -73,6 +73,10 @@ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(PlatformName)\ssleay32\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(PlatformName)\ssleay32\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\ssleay32\$(Configuration)\</IntDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\ssleay32\$(Configuration)\</IntDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PreBuildEvent> diff --git a/scripts/perl/blacklist.pl b/scripts/perl/blacklist.pl new file mode 100755 index 0000000000..f434669f36 --- /dev/null +++ b/scripts/perl/blacklist.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl +# +# Add this to acl.conf.xml +# +# <X-PRE-PROCESS cmd="exec" data="$${base_dir}/bin/blacklist.pl"/> +# + +use Data::Dumper; +use LWP::Simple; + +# http://www.infiltrated.net/voipabuse/addresses.txt +# http://www.infiltrated.net/voipabuse/netblocks.txt + + +my @addresses = split(/\n/, get("http://www.infiltrated.net/voipabuse/addresses.txt")); +my @netblocks = split(/\n/, get("http://www.infiltrated.net/voipabuse/netblocks.txt")); + +print "<list name=\"voip-abuse-addresses\" default=\"deny\">\n"; +foreach $addr (@addresses) { + print " <node type=\"allow\" cidr=\"$addr/32\"/>\n"; +} +print "</list>\n"; + + +print "<list name=\"voip-abuse-netblocks\" default=\"deny\">\n"; +foreach $netb (@netblocks) { + print " <node type=\"allow\" cidr=\"$netb\"/>\n"; +} +print "</list>\n"; diff --git a/scripts/perl/honeypot.pl b/scripts/perl/honeypot.pl new file mode 100755 index 0000000000..ef52142cb1 --- /dev/null +++ b/scripts/perl/honeypot.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +# +# Add this to conf/dialplan/public but only if you wish to setup a honeypot. +# +# <X-PRE-PROCESS cmd="exec" data="$${base_dir}/bin/honeypot.pl"/> +# + +use Data::Dumper; +use LWP::Simple; + +# http://www.infiltrated.net/voipabuse/numberscalled.txt + +my @numberscalled = split(/\n/, get("http://www.infiltrated.net/voipabuse/numberscalled.txt")); + +foreach $number (@numberscalled) { + my ($num,$ts) = split(/\t/, $number); + + print "<extension name=\"$num\">\n"; + print " <condition field=\"destination_number\" expression=\"^$num\$\">\n"; + print " <action application=\"answer\"/>\n"; + print " <action application=\"sleep\" data=\"30000\"/>\n"; + print " </condition>\n"; + print "</extension>\n"; +} + + diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 50dde95dc7..e77d5f74ef 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -233,6 +233,8 @@ struct switch_runtime { switch_profile_timer_t *profile_timer; double profile_time; double min_idle_time; + int sql_buffer_len; + int max_sql_buffer_len; }; extern struct switch_runtime runtime; diff --git a/src/include/switch.h b/src/include/switch.h index 7143c61d91..81684c59b0 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -91,7 +91,10 @@ #include <Ws2tcpip.h> #pragma warning(pop) #else +/* work around for warnings in vs 2010 */ +#pragma warning (disable:6386) #include <Ws2tcpip.h> +#pragma warning (default:6386) #endif #else #include <strings.h> diff --git a/src/include/switch_config.h b/src/include/switch_config.h index 2281a9bbc1..4115564f56 100644 --- a/src/include/switch_config.h +++ b/src/include/switch_config.h @@ -38,7 +38,7 @@ /** * @defgroup config Config File Parser * @ingroup core1 - * This module implements a basic interface and file format parser it may be depricated in favor of database entries + * This module implements a basic interface and file format parser it may be deprecated in favor of database entries * or expanded to tie to external handlers in the future as necessary. * <pre> * diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 7275f26319..8b08db7d9d 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1339,12 +1339,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_destroy(switch_timer_t *timer) \param pool the memory pool to use \return SWITCH_STATUS_SUCCESS if the handle is allocated */ -SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, +#define switch_core_codec_init(_codec, _codec_name, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool) \ + switch_core_codec_init_with_bitrate(_codec, _codec_name, _fmtp, _rate, _ms, _channels, 0, _flags, _codec_settings, _pool) +SWITCH_DECLARE(switch_status_t) switch_core_codec_init_with_bitrate(switch_codec_t *codec, const char *codec_name, const char *fmtp, uint32_t rate, int ms, int channels, + uint32_t bitrate, uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool); SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, switch_memory_pool_t *pool); diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index ed14f108c7..0ede8e638f 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -292,7 +292,8 @@ SWITCH_DECLARE(void) consoleCleanLog(char *msg); SWITCH_DECLARE(int) transfer(char *extension, char *dialplan = NULL, char *context = NULL); - SWITCH_DECLARE(char *) read(int min_digits, int max_digits, const char *prompt_audio_file, int timeout, const char *valid_terminators); + SWITCH_DECLARE(char *) read(int min_digits, int max_digits, + const char *prompt_audio_file, int timeout, const char *valid_terminators, int digit_timeout = 0); /** \brief Play a file into channel and collect dtmfs * @@ -306,7 +307,7 @@ SWITCH_DECLARE(void) consoleCleanLog(char *msg); int max_digits, int max_tries, int timeout, char *terminators, char *audio_files, char *bad_input_audio_files, - char *digits_regex, const char *var_name = NULL); + char *digits_regex, const char *var_name = NULL, int digit_timeout = 0); /** \brief Play a file that resides on disk into the channel * diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 40ba1dc16f..4c562a51d7 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -369,7 +369,8 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t const char *audio_file, const char *bad_input_audio_file, const char *var_name, char *digit_buffer, uint32_t digit_buffer_length, - const char *digits_regex); + const char *digits_regex, + uint32_t digit_timeout); SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session_t *session, switch_speech_handle_t *sh, @@ -804,7 +805,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, uint32_t max_digits, const char *prompt_audio_file, const char *var_name, - char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators); + char *digit_buffer, + switch_size_t digit_buffer_length, + uint32_t timeout, + const char *valid_terminators, + uint32_t digit_timeout); + SWITCH_DECLARE(switch_status_t) switch_ivr_block_dtmf_session(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_ivr_unblock_dtmf_session(switch_core_session_t *session); diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index 68719062b7..37c752bd3e 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -92,7 +92,7 @@ SWITCH_BEGIN_EXTERN_C \brief Initilize the module backend and load all the modules \return SWITCH_STATUS_SUCCESS when complete */ -SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(void); +SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autoload); /*! \brief Shutdown the module backend and call the shutdown routine in all loaded modules diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 078b83d2fd..a6013a9386 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -570,42 +570,23 @@ struct switch_directory_handle { void *private_info; }; - /* nobody has more setting than speex so we will let them set the standard */ /*! \brief Various codec settings (currently only relevant to speex) */ struct switch_codec_settings { - /*! desired quality */ - int quality; - /*! desired complexity */ - int complexity; - /*! desired enhancement */ - int enhancement; - /*! desired vad level */ - int vad; - /*! desired vbr level */ - int vbr; - /*! desired vbr quality */ - float vbr_quality; - /*! desired abr level */ - int abr; - /*! desired dtx setting */ - int dtx; - /*! desired preprocessor settings */ - int preproc; - /*! preprocessor vad settings */ - int pp_vad; - /*! preprocessor gain control settings */ - int pp_agc; - /*! preprocessor gain level */ - float pp_agc_level; - /*! preprocessor denoise level */ - int pp_denoise; - /*! preprocessor dereverb settings */ - int pp_dereverb; - /*! preprocessor dereverb decay level */ - float pp_dereverb_decay; - /*! preprocessor dereverb level */ - float pp_dereverb_level; + int unused; +}; + +/*! an abstract handle of a fmtp parsed by codec */ +struct switch_codec_fmtp { + /*! actual samples transferred per second for those who are not moron g722 RFC writers */ + uint32_t actual_samples_per_second; + /*! bits transferred per second */ + int bits_per_second; + /*! number of microseconds of media in one packet (ptime * 1000) */ + int microseconds_per_packet; + /*! private data for the codec module to store handle specific info */ + void *private_info; + }; /*! an abstract handle to a codec module */ @@ -618,8 +599,6 @@ struct switch_codec { char *fmtp_in; /*! fmtp line for local sdp */ char *fmtp_out; - /*! codec settings for this handle */ - switch_codec_settings_t codec_settings; /*! flags to modify behaviour */ uint32_t flags; /*! the handle's memory pool */ @@ -678,6 +657,8 @@ struct switch_codec_interface { const char *interface_name; /*! a list of codec implementations related to the codec */ switch_codec_implementation_t *implementations; + /*! function to decode a codec fmtp parameters */ + switch_core_codec_fmtp_parse_func_t parse_fmtp; uint32_t codec_id; switch_thread_rwlock_t *rwlock; int refs; diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 7e6028a68b..7269a2b8d9 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -449,6 +449,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_ SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs); SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session); /*! \} diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 5a88cd5751..57c5661c7c 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -255,7 +255,8 @@ typedef enum { SCF_USE_CLOCK_RT = (1 << 10), SCF_VERBOSE_EVENTS = (1 << 11), SCF_USE_WIN32_MONOTONIC = (1 << 12), - SCF_AUTO_SCHEMAS = (1 << 13) + SCF_AUTO_SCHEMAS = (1 << 13), + SCF_MINIMAL = (1 << 14) } switch_core_flag_enum_t; typedef uint32_t switch_core_flag_t; @@ -479,9 +480,16 @@ typedef struct { switch_size_t flush_packet_count; } switch_rtp_numbers_t; + +typedef struct { + uint32_t packet_count; + uint32_t octet_count; +} switch_rtcp_numbers_t; + typedef struct { switch_rtp_numbers_t inbound; switch_rtp_numbers_t outbound; + switch_rtcp_numbers_t rtcp; } switch_rtp_stats_t; typedef enum { @@ -762,9 +770,9 @@ typedef struct { const char *T38FaxUdpEC; const char *T38VendorInfo; const char *remote_ip; - uint32_t remote_port; + uint16_t remote_port; const char *local_ip; - uint32_t local_port; + uint16_t local_port; } switch_t38_options_t; /*! @@ -1580,6 +1588,7 @@ typedef struct switch_core_thread_session switch_core_thread_session_t; typedef struct switch_codec_implementation switch_codec_implementation_t; typedef struct switch_buffer switch_buffer_t; typedef struct switch_codec_settings switch_codec_settings_t; +typedef struct switch_codec_fmtp switch_codec_fmtp_t; typedef struct switch_odbc_handle switch_odbc_handle_t; typedef struct switch_io_routines switch_io_routines_t; @@ -1638,6 +1647,7 @@ typedef switch_status_t (*switch_core_codec_decode_func_t) (switch_codec_t *code void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag); typedef switch_status_t (*switch_core_codec_init_func_t) (switch_codec_t *, switch_codec_flag_t, const switch_codec_settings_t *codec_settings); +typedef switch_status_t (*switch_core_codec_fmtp_parse_func_t) (const char *fmtp, switch_codec_fmtp_t *codec_fmtp); typedef switch_status_t (*switch_core_codec_destroy_func_t) (switch_codec_t *); diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index f24cee5e9f..e5d70c43cc 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -139,6 +139,9 @@ static inline char *switch_strchr_strict(const char *in, char find, const char * #define switch_is_valid_rate(_tmp) (_tmp == 8000 || _tmp == 12000 || _tmp == 16000 || _tmp == 24000 || _tmp == 32000 || _tmp == 11025 || _tmp == 22050 || _tmp == 44100 || _tmp == 48000) +#ifdef _MSC_VER +#pragma warning(disable:6011) +#endif static inline int switch_string_has_escaped_data(const char *in) { const char *i = strchr(in, '\\'); @@ -153,6 +156,9 @@ static inline int switch_string_has_escaped_data(const char *in) return 0; } +#ifdef _MSC_VER +#pragma warning(default:6011) +#endif SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen); SWITCH_DECLARE(switch_size_t) switch_b64_decode(char *in, char *out, switch_size_t olen); @@ -171,6 +177,23 @@ static inline switch_bool_t switch_is_digit_string(const char *s) return SWITCH_TRUE; } + +static inline uint32_t switch_known_bitrate(switch_payload_t payload) +{ + switch(payload) { + case 0: /* PCMU */ return 64000; + case 3: /* GSM */ return 13200; + case 4: /* G723 */ return 6300; + case 7: /* LPC */ return 2400; + case 8: /* PCMA */ return 64000; + case 9: /* G722 */ return 64000; + case 18: /* G729 */ return 8000; + default: break; + } + + return 0; +} + SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_size_t len); @@ -353,7 +376,16 @@ switch_mutex_unlock(obj->flag_mutex); #define switch_set_string(_dst, _src) switch_copy_string(_dst, _src, sizeof(_dst)) - static inline char *switch_sanitize_number(char *number) +static inline uint32_t switch_default_ptime(const char *name, uint32_t number) +{ + if (!strcasecmp(name, "G723")) { + return 30; + } + + return 20; +} + +static inline char *switch_sanitize_number(char *number) { char *p = number, *q; char warp[] = "/:"; @@ -455,6 +487,9 @@ static inline char *switch_safe_strdup(const char *it) } +#ifdef _MSC_VER +#pragma warning(disable:6011) +#endif static inline char *switch_lc_strdup(const char *it) { char *dup; @@ -487,6 +522,9 @@ static inline char *switch_uc_strdup(const char *it) return NULL; } +#ifdef _MSC_VER +#pragma warning(default:6011) +#endif /*! @@ -680,7 +718,15 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_netwo SWITCH_DECLARE(int) switch_inet_pton(int af, const char *src, void *dst); +SWITCH_DECLARE(const char *) switch_dow_int2str(int val); +SWITCH_DECLARE(int) switch_dow_str2int(const char *exp); +SWITCH_DECLARE(int) switch_dow_cmp(const char *exp, int val); SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val); +SWITCH_DECLARE(int) switch_tod_cmp(const char *exp, int val); + +SWITCH_DECLARE(int) switch_fulldate_cmp(const char *exp, switch_time_t *ts); +SWITCH_DECLARE(void) switch_split_date(const char *exp, int *year, int *month, int *day); +SWITCH_DECLARE(void) switch_split_time(const char *exp, int *hour, int *min, int *sec); /*! \brief Split a user@domain string as user and domain diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h index 220e65df02..9b0fbb44f3 100644 --- a/src/include/switch_xml.h +++ b/src/include/switch_xml.h @@ -331,6 +331,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_open_root(_In_ uint8_t reload, _Out_ con ///\return SWITCH_STATUS_SUCCESS if successful SWITCH_DECLARE(switch_status_t) switch_xml_init(_In_ switch_memory_pool_t *pool, _Out_ const char **err); +SWITCH_DECLARE(switch_status_t) switch_xml_reload(const char **err); SWITCH_DECLARE(switch_status_t) switch_xml_destroy(void); diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index e08757ba38..b58e647e3b 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1259,7 +1259,7 @@ static switch_status_t load_config(void) if (!strcasecmp(var, "debug")) { globals.debug = atoi(val); } else if (!strcasecmp(var, "odbc-dsn")) { - globals.odbc_dsn = strdup(switch_xml_attr(param, "odbc-dsn")); + globals.odbc_dsn = strdup(val); if (!zstr(globals.odbc_dsn)) { if ((globals.odbc_user = strchr(globals.odbc_dsn, ':'))) { @@ -1498,7 +1498,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa /* Update Agents Items */ /* Do not remove uuid of the agent if we are a standby agent */ - sql = switch_mprintf("UPDATE agents SET %q last_bridge_end = %ld, talk_time = talk_time + (%ld-last_bridge_start) WHERE name = '%q' AND system = '%q';" + sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %ld, talk_time = talk_time + (%ld-last_bridge_start) WHERE name = '%q' AND system = '%q';" , (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), (long) switch_epoch_time_now(NULL), (long) switch_epoch_time_now(NULL), h->agent_name, h->agent_system); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); @@ -2675,9 +2675,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load) { switch_application_interface_t *app_interface; switch_api_interface_t *api_interface; - - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); + switch_status_t status; memset(&globals, 0, sizeof(globals)); globals.pool = pool; @@ -2685,11 +2683,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load) switch_core_hash_init(&globals.queue_hash, globals.pool); switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); + if ((status = load_config()) != SWITCH_STATUS_SUCCESS) { + return status; + } + switch_mutex_lock(globals.mutex); globals.running = 1; switch_mutex_unlock(globals.mutex); - load_config(); + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); if (!AGENT_DISPATCH_THREAD_STARTED) { cc_agent_dispatch_thread_start(); diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index e1eb2a6b6a..1fb1c95c47 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -135,7 +135,7 @@ SWITCH_STANDARD_API(nat_map_function) switch_bool_t sticky = SWITCH_FALSE; if (!cmd) { - goto error; + goto usage; } if (!switch_nat_is_initialized()) { @@ -147,9 +147,8 @@ SWITCH_STANDARD_API(nat_map_function) switch_assert(mydata); argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if (argc < 1) { - goto error; + goto usage; } if (argv[0] && switch_stristr("status", argv[0])) { tmp = switch_nat_status(); @@ -197,6 +196,10 @@ SWITCH_STANDARD_API(nat_map_function) error: stream->write_function(stream, "false"); + goto ok; + + usage: + stream->write_function(stream, "USAGE: nat_map [status|reinit|republish] | [add|del] <port> [tcp|udp] [sticky]"); ok: @@ -605,11 +608,12 @@ SWITCH_STANDARD_API(in_group_function) SWITCH_STANDARD_API(user_data_function) { - switch_xml_t x_domain, xml = NULL, x_user = NULL, x_param, x_params; + switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params; int argc; char *mydata = NULL, *argv[3], *key = NULL, *type = NULL, *user, *domain; char delim = ' '; const char *container = "params", *elem = "param"; + const char *result = NULL; switch_event_t *params = NULL; if (zstr(cmd) || !(mydata = strdup(cmd))) { @@ -637,10 +641,10 @@ SWITCH_STANDARD_API(user_data_function) switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "type", type); - if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL, params) == SWITCH_STATUS_SUCCESS) { + if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, params) == SWITCH_STATUS_SUCCESS) { if (!strcmp(type, "attr")) { const char *attr = switch_xml_attr_soft(x_user, key); - stream->write_function(stream, "%s", attr); + result = attr; goto end; } @@ -649,33 +653,45 @@ SWITCH_STANDARD_API(user_data_function) elem = "variable"; } - if ((x_params = switch_xml_child(x_user, container))) { - for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) { - const char *var = switch_xml_attr(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - - if (var && val && !strcasecmp(var, key)) { - stream->write_function(stream, "%s", val); - goto end; - } - - } - } - if ((x_params = switch_xml_child(x_domain, container))) { for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) { const char *var = switch_xml_attr(x_param, "name"); const char *val = switch_xml_attr(x_param, "value"); if (var && val && !strcasecmp(var, key)) { - stream->write_function(stream, "%s", val); - goto end; + result = val; + } + + } + } + + if (x_group && (x_params = switch_xml_child(x_group, container))) { + for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) { + const char *var = switch_xml_attr(x_param, "name"); + const char *val = switch_xml_attr(x_param, "value"); + + if (var && val && !strcasecmp(var, key)) { + result = val; + } + } + } + + if ((x_params = switch_xml_child(x_user, container))) { + for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) { + const char *var = switch_xml_attr(x_param, "name"); + const char *val = switch_xml_attr(x_param, "value"); + + if (var && val && !strcasecmp(var, key)) { + result = val; } } } } end: + if (result) { + stream->write_function(stream, "%s", result); + } switch_xml_free(xml); switch_safe_free(mydata); switch_event_destroy(¶ms); @@ -1049,7 +1065,7 @@ SWITCH_STANDARD_API(url_encode_function) int len = 0; if (!zstr(cmd)) { - len = (strlen(cmd) * 3) + 1; + len = (int)(strlen(cmd) * 3) + 1; switch_zmalloc(data, len); switch_url_encode(cmd, data, len); reply = data; @@ -1166,17 +1182,18 @@ SWITCH_STANDARD_API(xml_locate_function) SWITCH_STANDARD_API(reload_acl_function) { const char *err; - switch_xml_t xml_root; - if (cmd && !strcmp(cmd, "reloadxml")) { - if ((xml_root = switch_xml_open_root(1, &err))) { - switch_xml_free(xml_root); - } + if (cmd && !strcasecmp(cmd, "reloadxml")) { + stream->write_function(stream, "This option is deprecated, we now always reloadxml.\n"); + } + + if (switch_xml_reload(&err) == SWITCH_STATUS_SUCCESS) { + switch_load_network_lists(SWITCH_TRUE); + stream->write_function(stream, "+OK acl reloaded\n"); + } else { + stream->write_function(stream, "-Error [%s]\n", err); } - switch_load_network_lists(SWITCH_TRUE); - - stream->write_function(stream, "+OK acl reloaded\n"); return SWITCH_STATUS_SUCCESS; } @@ -1374,7 +1391,7 @@ SWITCH_STANDARD_API(cond_function) argc = switch_separate_string(mydata, ':', argv, (sizeof(argv) / sizeof(argv[0]))); - if (argc != 3) { + if (! (argc >= 2 && argc <= 3)) { goto error; } @@ -1451,7 +1468,12 @@ SWITCH_STANDARD_API(cond_function) } switch_safe_free(s_a); switch_safe_free(s_b); - stream->write_function(stream, "%s", is_true ? argv[1] : argv[2]); + + if ((argc == 2 && !is_true)) { + stream->write_function(stream, ""); + } else { + stream->write_function(stream, "%s", is_true ? argv[1] : argv[2]); + } goto ok; } @@ -1720,6 +1742,10 @@ SWITCH_STANDARD_API(load_function) return SWITCH_STATUS_SUCCESS; } + if (switch_xml_reload(&err) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Reloading XML\n"); + } + if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) cmd, SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "+OK\n"); } else { @@ -1814,6 +1840,10 @@ SWITCH_STANDARD_API(reload_function) stream->write_function(stream, "-ERR unloading module [%s]\n", err); } + if (switch_xml_reload(&err) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Reloading XML\n"); + } + if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) cmd, SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "+OK module loaded\n"); } else { @@ -1825,13 +1855,9 @@ SWITCH_STANDARD_API(reload_function) SWITCH_STANDARD_API(reload_xml_function) { - const char *err; - switch_xml_t xml_root; - - if ((xml_root = switch_xml_open_root(1, &err))) { - switch_xml_free(xml_root); - } + const char *err = ""; + switch_xml_reload(&err); stream->write_function(stream, "+OK [%s]\n", err); return SWITCH_STATUS_SUCCESS; @@ -3022,7 +3048,7 @@ SWITCH_STANDARD_API(xml_wrap_api_function) if (mystream.data) { if (encoded) { - elen = (int) strlen(mystream.data) * 3; + elen = (int) strlen(mystream.data) * 3 + 1; edata = malloc(elen); switch_assert(edata != NULL); memset(edata, 0, elen); @@ -4040,7 +4066,7 @@ SWITCH_STANDARD_API(uuid_dump_function) return SWITCH_STATUS_SUCCESS; } -#define GLOBAL_SETVAR_SYNTAX "<var> <value> [<value2>]" +#define GLOBAL_SETVAR_SYNTAX "<var>=<value> [=<value2>]" SWITCH_STANDARD_API(global_setvar_function) { char *mycmd = NULL, *argv[3] = { 0 }; @@ -4192,7 +4218,7 @@ SWITCH_STANDARD_API(escape_function) return SWITCH_STATUS_SUCCESS; } - len = strlen(cmd) * 2; + len = (int)strlen(cmd) * 2; mycmd = malloc(len); stream->write_function(stream, "%s", switch_escape_string(cmd, mycmd, len)); @@ -4551,7 +4577,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "originate", "Originate a Call", originate_function, ORIGINATE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "pause", "Pause", pause_function, PAUSE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "regex", "Eval a regex", regex_function, "<data>|<pattern>[|<subst string>]"); - SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload ACL", reload_acl_function, "[reloadxml]"); + SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload ACL", reload_acl_function, ""); SWITCH_ADD_API(commands_api_interface, "reload", "Reload Module", reload_function, UNLOAD_SYNTAX); SWITCH_ADD_API(commands_api_interface, "reloadxml", "Reload XML", reload_xml_function, ""); SWITCH_ADD_API(commands_api_interface, "replace", "replace a string", replace_function, "<data>|<string1>|<string2>"); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 5128e3baed..7018294546 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -99,7 +99,7 @@ typedef enum { CALLER_CONTROL_DEAF_MUTE, CALLER_CONTROL_ENERGY_UP, CALLER_CONTROL_ENERGY_EQU_CONF, - CALLER_CONTROL_ENERGEY_DN, + CALLER_CONTROL_ENERGY_DN, CALLER_CONTROL_VOL_TALK_UP, CALLER_CONTROL_VOL_TALK_ZERO, CALLER_CONTROL_VOL_TALK_DN, @@ -121,7 +121,7 @@ typedef struct conference_member conference_member_t; struct call_list { char *string; - int itteration; + int iteration; struct call_list *next; }; typedef struct call_list call_list_t; @@ -717,7 +717,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe if (call_list) { char saymsg[1024]; - switch_snprintf(saymsg, sizeof(saymsg), "Auto Calling %d parties", call_list->itteration); + switch_snprintf(saymsg, sizeof(saymsg), "Auto Calling %d parties", call_list->iteration); conference_member_say(member, saymsg, 0); } else { if (zstr(conference->special_announce)) { @@ -1012,7 +1012,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v uint8_t *file_frame; uint8_t *async_file_frame; int16_t *bptr; - int x = 0; + uint32_t x = 0; int32_t z = 0; int member_score_sum = 0; int divisor = 0; @@ -2298,7 +2298,7 @@ static caller_control_fn_table_t ccfntbl[] = { {"deaf mute", "*", CALLER_CONTROL_DEAF_MUTE, conference_loop_fn_deafmute_toggle}, {"energy up", "9", CALLER_CONTROL_ENERGY_UP, conference_loop_fn_energy_up}, {"energy equ", "8", CALLER_CONTROL_ENERGY_EQU_CONF, conference_loop_fn_energy_equ_conf}, - {"energy dn", "7", CALLER_CONTROL_ENERGEY_DN, conference_loop_fn_energy_dn}, + {"energy dn", "7", CALLER_CONTROL_ENERGY_DN, conference_loop_fn_energy_dn}, {"vol talk up", "3", CALLER_CONTROL_VOL_TALK_UP, conference_loop_fn_volume_talk_up}, {"vol talk zero", "2", CALLER_CONTROL_VOL_TALK_ZERO, conference_loop_fn_volume_talk_zero}, {"vol talk dn", "1", CALLER_CONTROL_VOL_TALK_DN, conference_loop_fn_volume_talk_dn}, @@ -3733,7 +3733,7 @@ static switch_status_t conf_api_sub_list(conference_obj_t *conference, switch_st static switch_xml_t add_x_tag(switch_xml_t x_member, const char *name, const char *value, int off) { - switch_size_t dlen = strlen(value) * 3; + switch_size_t dlen = strlen(value) * 3 + 1; char *data; switch_xml_t x_tag; @@ -5199,9 +5199,9 @@ SWITCH_STANDARD_APP(conference_auto_function) np->string = switch_core_session_strdup(session, data); if (call_list) { np->next = call_list; - np->itteration = call_list->itteration + 1; + np->iteration = call_list->iteration + 1; } else { - np->itteration = 1; + np->iteration = 1; } call_list = np; } diff --git a/src/mod/applications/mod_directory/mod_directory.c b/src/mod/applications/mod_directory/mod_directory.c index d3389ab3b1..d92974766d 100644 --- a/src/mod/applications/mod_directory/mod_directory.c +++ b/src/mod/applications/mod_directory/mod_directory.c @@ -393,7 +393,7 @@ static dir_profile_t *load_profile(const char *profile_name) profile_set_config(profile); /* Add the params to the event structure */ - count = switch_event_import_xml(switch_xml_child(x_profile, "param"), "name", "value", &event); + count = (int)switch_event_import_xml(switch_xml_child(x_profile, "param"), "name", "value", &event); if (switch_xml_config_parse_event(event, count, SWITCH_FALSE, profile->config) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to process configuration\n"); @@ -611,7 +611,7 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit } if (strlen(cbr->digits) < sizeof(cbr->digits) - 2) { - int at = strlen(cbr->digits); + int at = (int)strlen(cbr->digits); cbr->digits[at++] = dtmf->digit; cbr->digits[at] = '\0'; } else { @@ -649,25 +649,25 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_ if (zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%d", DIR_RESULT_ITEM, cbt->want + 1); - switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key); + switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (!zstr_buf(recorded_name) && zstr_buf(buf)) { - switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key); + switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (zstr_buf(recorded_name) && zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_SAY_NAME, cbt->fullname); - switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key); + switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (cbt->exten_visible && zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_AT, cbt->extension); - switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key); + switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0); } if (zstr_buf(buf)) { switch_snprintf(macro, sizeof(macro), "phrase:%s:%c,%c,%c,%c", DIR_RESULT_MENU, *profile->select_name_key, *profile->next_key, *profile->prev_key, *profile->new_search_key); - switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key); + switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key, 0); } if (!zstr_buf(buf)) { @@ -884,6 +884,18 @@ SWITCH_STANDARD_APP(directory_function) if (strcasecmp(profile->search_order, "last_name")) { s_param.search_by_last_name = 0; } + + { + const char *var_search_order = switch_channel_get_variable(channel, "directory_search_order"); + if (var_search_order) { + if (!strcasecmp(var_search_order, "first_name")) { + s_param.search_by_last_name = 0; + } else { + s_param.search_by_last_name = 1; + } + } + } + attempts = profile->max_menu_attempt; s_param.try_again = 1; while (switch_channel_ready(channel) && (s_param.try_again && attempts-- > 0)) { diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 55429275dd..dd63f8aae9 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1712,10 +1712,11 @@ SWITCH_STANDARD_APP(att_xfer_function) SWITCH_STANDARD_APP(read_function) { char *mydata; - char *argv[6] = { 0 }; + char *argv[7] = { 0 }; int argc; int32_t min_digits = 0; int32_t max_digits = 0; + uint32_t digit_timeout = 0; int timeout = 1000; char digit_buffer[128] = ""; const char *prompt_audio_file = NULL; @@ -1751,6 +1752,13 @@ SWITCH_STANDARD_APP(read_function) valid_terminators = argv[5]; } + if (argc > 6) { + digit_timeout = atoi(argv[6]); + if (digit_timeout < 0) { + digit_timeout = 0; + } + } + if (min_digits <= 1) { min_digits = 1; } @@ -1767,17 +1775,19 @@ SWITCH_STANDARD_APP(read_function) valid_terminators = "#"; } - switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, sizeof(digit_buffer), timeout, valid_terminators); + switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, sizeof(digit_buffer), timeout, valid_terminators, + digit_timeout); } SWITCH_STANDARD_APP(play_and_get_digits_function) { char *mydata; - char *argv[9] = { 0 }; + char *argv[10] = { 0 }; int argc; int32_t min_digits = 0; int32_t max_digits = 0; int32_t max_tries = 0; + uint32_t digit_timeout = 0; int timeout = 1000; char digit_buffer[128] = ""; const char *prompt_audio_file = NULL; @@ -1827,6 +1837,14 @@ SWITCH_STANDARD_APP(play_and_get_digits_function) digits_regex = argv[8]; } + if (argc > 9) { + digit_timeout = atoi(argv[9]); + if (digit_timeout < 0) { + digit_timeout = 0; + } + } + + if (min_digits <= 1) { min_digits = 1; } @@ -1844,7 +1862,7 @@ SWITCH_STANDARD_APP(play_and_get_digits_function) } switch_play_and_get_digits(session, min_digits, max_digits, max_tries, timeout, valid_terminators, - prompt_audio_file, bad_input_audio_file, var_name, digit_buffer, sizeof(digit_buffer), digits_regex); + prompt_audio_file, bad_input_audio_file, var_name, digit_buffer, sizeof(digit_buffer), digits_regex, digit_timeout); } #define SAY_SYNTAX "<module_name> <say_type> <say_method> [<say_gender>] <text>" @@ -3367,9 +3385,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "endless_playback", "Playback File Endlessly", "Endlessly Playback a file to the channel", endless_playback_function, "<path>", SAF_NONE); SWITCH_ADD_APP(app_interface, "att_xfer", "Attended Transfer", "Attended Transfer", att_xfer_function, "<channel_url>", SAF_NONE); - SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function, "<min> <max> <file> <var_name> <timeout> <terminators>", SAF_NONE); + SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function, + "<min> <max> <file> <var_name> <timeout> <terminators> <digit_timeout>", SAF_NONE); SWITCH_ADD_APP(app_interface, "play_and_get_digits", "Play and get Digits", "Play and get Digits", - play_and_get_digits_function, "<min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp>", SAF_NONE); + play_and_get_digits_function, + "<min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp> [<digit_timeout>]", SAF_NONE); SWITCH_ADD_APP(app_interface, "stop_record_session", "Stop Record Session", STOP_SESS_REC_DESC, stop_record_session_function, "<path>", SAF_NONE); SWITCH_ADD_APP(app_interface, "record_session", "Record Session", SESS_REC_DESC, record_session_function, "<path> [+<timeout>]", SAF_MEDIA_TAP); SWITCH_ADD_APP(app_interface, "record", "Record File", "Record a file from the channels input", record_function, diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index aa49689062..563706c9f2 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -439,7 +439,7 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, #define check_string(s) if (!zstr(s) && !strcasecmp(s, "undef")) { s = NULL; } -static int node_consumer_wait_count(fifo_node_t *node) +static int node_caller_count(fifo_node_t *node) { int i, len = 0; @@ -458,7 +458,7 @@ static void node_remove_uuid(fifo_node_t *node, const char *uuid) fifo_queue_popfly(node->fifo_list[i], uuid); } - if (!node_consumer_wait_count(node)) { + if (!node_caller_count(node)) { node->start_waiting = 0; } @@ -513,7 +513,6 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session if (match_key(caller_exit_key, *buf)) { cd->abort = 1; return SWITCH_STATUS_FALSE; - switch_channel_set_variable(channel, "fifo_caller_exit_key", (char *)buf); } cd->next = switch_epoch_time_now(NULL) + cd->freq; cd->index++; @@ -875,7 +874,7 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses char *sql; switch_event_t *event; - switch_channel_clear_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG); + switch_channel_clear_app_flag_key(__FILE__, consumer_channel, FIFO_APP_BRIDGE_TAG); switch_channel_set_variable(consumer_channel, "fifo_bridged", NULL); ts = switch_micro_time_now(); @@ -989,7 +988,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ goto end; } - switch_channel_set_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG); + switch_channel_set_app_flag_key(__FILE__, consumer_channel, FIFO_APP_BRIDGE_TAG); switch_channel_set_variable(consumer_channel, "fifo_bridged", "true"); switch_channel_set_variable(consumer_channel, "fifo_manual_bridge", "true"); @@ -1683,7 +1682,7 @@ static void find_consumers(fifo_node_t *node) switch(node->outbound_strategy) { case NODE_STRATEGY_ENTERPRISE: { - int need = node_consumer_wait_count(node); + int need = node_caller_count(node); if (node->outbound_per_cycle && node->outbound_per_cycle < need) { need = node->outbound_per_cycle; @@ -1753,7 +1752,7 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o if ((node = (fifo_node_t *) val)) { if (node->outbound_priority == 0) node->outbound_priority = 5; if (node->has_outbound && node->ready && !node->busy && node->outbound_priority == cur_priority) { - ppl_waiting = node_consumer_wait_count(node); + ppl_waiting = node_caller_count(node); consumer_total = node->consumer_count; idle_consumers = node_idle_consumers(node); @@ -1831,7 +1830,7 @@ static void check_cancel(fifo_node_t *node) return; } - ppl_waiting = node_consumer_wait_count(node); + ppl_waiting = node_caller_count(node); if (node->ring_consumer_count > 0 && ppl_waiting < 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound call count (%d) exceeds required value for queue %s (%d), " @@ -1855,7 +1854,7 @@ static void send_presence(fifo_node_t *node) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "park"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", node->name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", node->name); - if ((wait_count = node_consumer_wait_count(node)) > 0) { + if ((wait_count = node_caller_count(node)) > 0) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d waiting)", wait_count); } else { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "Idle"); @@ -1990,6 +1989,11 @@ static void dec_use_count(switch_core_session_t *session, switch_bool_t send_eve if ((outbound_id = switch_channel_get_variable(channel, "fifo_outbound_uuid"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s untracking call on uuid %s!\n", switch_channel_get_name(channel), outbound_id); + + sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(session)); + fifo_execute_sql(sql, globals.sql_mutex); + switch_safe_free(sql); + del_bridge_call(outbound_id); sql = switch_mprintf("update fifo_outbound set use_count=use_count-1, stop_time=%ld, next_avail=%ld + lag + 1 where use_count > 0 and uuid='%q'", now, now, outbound_id); @@ -2043,7 +2047,7 @@ SWITCH_STANDARD_APP(fifo_track_call_function) add_bridge_call(data); - switch_channel_set_app_flag(channel, FIFO_APP_TRACKING); + switch_channel_set_app_flag_key(__FILE__, channel, FIFO_APP_TRACKING); switch_channel_set_variable(channel, "fifo_outbound_uuid", data); switch_channel_set_variable(channel, "fifo_track_call", "true"); @@ -2296,7 +2300,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_answer(channel); switch_thread_rwlock_wrlock(node->rwlock); - node->caller_count++; if ((pri = switch_channel_get_variable(channel, "fifo_priority"))) { p = atoi(pri); @@ -2306,7 +2309,7 @@ SWITCH_STANDARD_APP(fifo_function) p = MAX_PRI - 1; } - if (!node_consumer_wait_count(node)) { + if (!node_caller_count(node)) { node->start_waiting = switch_micro_time_now(); } @@ -2343,7 +2346,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(channel, "fifo_timestamp", date); switch_channel_set_variable(channel, "fifo_serviced_uuid", NULL); - switch_channel_set_app_flag(channel, FIFO_APP_BRIDGE_TAG); + switch_channel_set_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG); if (chime_list) { char *list_dup = switch_core_session_strdup(session, chime_list); @@ -2416,10 +2419,10 @@ SWITCH_STANDARD_APP(fifo_function) } } - switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG); + abort: + + switch_channel_clear_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG); - abort: - fifo_caller_del(switch_core_session_get_uuid(session)); if (!aborted && switch_channel_ready(channel)) { @@ -2442,7 +2445,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_mutex_lock(globals.mutex); switch_thread_rwlock_wrlock(node->rwlock); node_remove_uuid(node, uuid); - node->caller_count--; switch_thread_rwlock_unlock(node->rwlock); send_presence(node); check_cancel(node); @@ -2583,7 +2585,7 @@ SWITCH_STANDARD_APP(fifo_function) continue; } - if ((waiting = node_consumer_wait_count(node))) { + if ((waiting = node_caller_count(node))) { if (!importance || node->importance > importance) { if (strat == STRAT_WAITING_LONGER) { @@ -2671,7 +2673,7 @@ SWITCH_STANDARD_APP(fifo_function) } } - if (pop && !node_consumer_wait_count(node)) { + if (pop && !node_caller_count(node)) { switch_thread_rwlock_wrlock(node->rwlock); node->start_waiting = 0; switch_thread_rwlock_unlock(node->rwlock); @@ -2775,7 +2777,8 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_flag(other_channel, CF_BREAK); - while (switch_channel_ready(channel) && switch_channel_ready(other_channel) && switch_channel_test_app_flag(other_channel, FIFO_APP_BRIDGE_TAG)) { + while (switch_channel_ready(channel) && switch_channel_ready(other_channel) && + switch_channel_test_app_flag(other_channel, FIFO_APP_BRIDGE_TAG)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { break; @@ -2787,9 +2790,6 @@ SWITCH_STANDARD_APP(fifo_function) const char *arg = switch_channel_get_variable(other_channel, "current_application_data"); switch_caller_extension_t *extension = NULL; - switch_thread_rwlock_wrlock(node->rwlock); - node->caller_count--; - switch_thread_rwlock_unlock(node->rwlock); send_presence(node); check_cancel(node); @@ -2955,9 +2955,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(other_channel, "fifo_status", "DONE"); switch_channel_set_variable(other_channel, "fifo_timestamp", date); - switch_thread_rwlock_wrlock(node->rwlock); - node->caller_count--; - switch_thread_rwlock_unlock(node->rwlock); send_presence(node); check_cancel(node); switch_core_session_rwunlock(other_session); @@ -3070,7 +3067,7 @@ SWITCH_STANDARD_APP(fifo_function) done: switch_mutex_lock(globals.mutex); - if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node->caller_count == 0) { + if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node_caller_count(node) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name); switch_core_hash_delete(globals.fifo_hash, node->name); switch_thread_rwlock_wrlock(node->rwlock); @@ -3085,7 +3082,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_mutex_unlock(globals.mutex); - switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG); + switch_channel_clear_app_flag_key(__FILE__, channel, FIFO_APP_BRIDGE_TAG); switch_core_media_bug_resume(session); @@ -3505,9 +3502,9 @@ static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int ve switch_xml_set_attr_d(x_fifo, "name", node->name); switch_snprintf(tmp, sizeof(buffer), "%d", node->consumer_count); switch_xml_set_attr_d(x_fifo, "consumer_count", tmp); - switch_snprintf(tmp, sizeof(buffer), "%d", node->caller_count); + switch_snprintf(tmp, sizeof(buffer), "%d", node_caller_count(node)); switch_xml_set_attr_d(x_fifo, "caller_count", tmp); - switch_snprintf(tmp, sizeof(buffer), "%d", node_consumer_wait_count(node)); + switch_snprintf(tmp, sizeof(buffer), "%d", node_caller_count(node)); switch_xml_set_attr_d(x_fifo, "waiting_count", tmp); switch_snprintf(tmp, sizeof(buffer), "%u", node->importance); switch_xml_set_attr_d(x_fifo, "importance", tmp); @@ -3569,7 +3566,7 @@ void node_dump(switch_stream_handle_t *stream) node->outbound_priority, node->busy, node->ready, - node_consumer_wait_count(node) + node_caller_count(node) ); } @@ -3687,9 +3684,9 @@ SWITCH_STANDARD_API(fifo_api_function) for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); - stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node->caller_count, len); + stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node_caller_count(node), len); switch_thread_rwlock_unlock(node->rwlock); x++; } @@ -3698,9 +3695,9 @@ SWITCH_STANDARD_API(fifo_api_function) stream->write_function(stream, "none\n"); } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); - stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node->caller_count, len); + stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node_caller_count(node), len); switch_thread_rwlock_unlock(node->rwlock); } else { stream->write_function(stream, "none\n"); @@ -3710,7 +3707,7 @@ SWITCH_STANDARD_API(fifo_api_function) for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); stream->write_function(stream, "%s:%d\n", (char *) var, node->has_outbound); switch_thread_rwlock_unlock(node->rwlock); @@ -3721,7 +3718,7 @@ SWITCH_STANDARD_API(fifo_api_function) stream->write_function(stream, "none\n"); } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { - len = node_consumer_wait_count(node); + len = node_caller_count(node); switch_thread_rwlock_wrlock(node->rwlock); stream->write_function(stream, "%s:%d\n", argv[1], node->has_outbound); switch_thread_rwlock_unlock(node->rwlock); @@ -4072,7 +4069,7 @@ static switch_status_t load_config(int reload, int del_all) continue; } - if (node_consumer_wait_count(node) || node->consumer_count || node_idle_consumers(node)) { + if (node_caller_count(node) || node->consumer_count || node_idle_consumers(node)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s removal delayed, still in use.\n", node->name); node->ready = FIFO_DELAY_DESTROY; } else { diff --git a/src/mod/applications/mod_hash/mod_hash.c b/src/mod/applications/mod_hash/mod_hash.c index 3a65528ea3..29a056104f 100644 --- a/src/mod/applications/mod_hash/mod_hash.c +++ b/src/mod/applications/mod_hash/mod_hash.c @@ -852,7 +852,8 @@ static void do_config(switch_bool_t reload) const char *username = switch_xml_attr(x_list, "username"); const char *password = switch_xml_attr(x_list, "password"); const char *szinterval = switch_xml_attr(x_list, "interval"); - int port = 0, interval = 0; + uint16_t port = 0; + int interval = 0; limit_remote_t *remote; switch_threadattr_t *thd_attr = NULL; @@ -866,7 +867,7 @@ static void do_config(switch_bool_t reload) } if (!zstr(szport)) { - port = atoi(szport); + port = (uint16_t)atoi(szport); } if (!zstr(szinterval)) { @@ -949,7 +950,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_hash_shutdown) /* Kill remote connections, destroy needs a wrlock so we unlock after finding a pointer */ while(remote_clean) { void *val; - const void *key; + const void *key = NULL; switch_ssize_t keylen; limit_remote_t *item = NULL; diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index bbf7bb568d..cc93707367 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -167,7 +167,7 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha switch_channel_t *channel = NULL; if (!zstr(cid)) { - len = strlen(cid); + len = (uint32_t)strlen(cid); } else { goto done; } @@ -506,7 +506,7 @@ static char *expand_digits(switch_memory_pool_t *pool, char *digits, switch_bool int digit_len; SWITCH_STANDARD_STREAM(dig_stream); - digit_len = strlen(digits); + digit_len = (int)strlen(digits); digits_copy = switch_core_strdup(pool, digits); for (n = digit_len; n > 0; n--) { @@ -1571,7 +1571,6 @@ SWITCH_STANDARD_APP(lcr_app_function) switch_channel_set_variable(channel, vbuf, cur_route->carrier_name); switch_snprintf(vbuf, sizeof(vbuf), "lcr_codec_%d", cnt); switch_channel_set_variable(channel, vbuf, cur_route->codec); - cnt++; if (cur_route->next) { if (routes.profile->enable_sip_redir) { dig_stream.write_function(&dig_stream, "%s,", cur_route->dialstring); diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index 06bc7d0abd..42369f5d0b 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -419,10 +419,10 @@ static switch_status_t do_billing(switch_core_session_t *session) billaccount = switch_channel_get_variable(channel, "nibble_account"); if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) { - nobal_amt = atof(switch_channel_get_variable(channel, "nobal_amt")); + nobal_amt = (float)atof(switch_channel_get_variable(channel, "nobal_amt")); } if (!zstr(switch_channel_get_variable(channel, "lowbal_amt"))) { - lowbal_amt = atof(switch_channel_get_variable(channel, "lowbal_amt")); + lowbal_amt = (float)atof(switch_channel_get_variable(channel, "lowbal_amt")); } /* Return if there's no billing information on this session */ diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c index 096d967ff0..aa7d05cf9e 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c @@ -549,8 +549,8 @@ static switch_status_t do_config(void) if (id == -1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to add tone_descriptor: %s, tone: %s. (too many tones)\n", name, tone_name); return SWITCH_STATUS_FALSE; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding tone_descriptor: %s, tone: %s(%d)\n", name, tone_name, id);} + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding tone_descriptor: %s, tone: %s(%d)\n", name, tone_name, id); /* add elements to tone */ for (element = switch_xml_child(tone, "element"); element; element = switch_xml_next(element)) { const char *freq1_attr = switch_xml_attr(element, "freq1"); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 7ff106aceb..27878246f0 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -74,6 +74,8 @@ static struct { char header[50]; char *prepend_string; char *spool; + switch_thread_cond_t *cond; + switch_mutex_t *cond_mutex; } globals; struct pvt_s { @@ -118,27 +120,34 @@ static struct { int thread_running; } t38_state_list; + + +static void wake_thread(int force) +{ + if (force) { + switch_thread_cond_signal(globals.cond); + return; + } + + if (switch_mutex_trylock(globals.cond_mutex) == SWITCH_STATUS_SUCCESS) { + switch_thread_cond_signal(globals.cond); + switch_mutex_unlock(globals.cond_mutex); + } +} + static int add_pvt(pvt_t *pvt) { int r = 0; - uint32_t sanity = 50; - - switch_mutex_lock(t38_state_list.mutex); - if (!t38_state_list.thread_running) { - - launch_timer_thread(); - - while(--sanity && !t38_state_list.thread_running) { - switch_yield(10000); - } - } - switch_mutex_unlock(t38_state_list.mutex); if (t38_state_list.thread_running) { switch_mutex_lock(t38_state_list.mutex); pvt->next = t38_state_list.head; t38_state_list.head = pvt; switch_mutex_unlock(t38_state_list.mutex); + r = 1; + wake_thread(0); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error launching thread\n"); } return r; @@ -151,9 +160,9 @@ static int del_pvt(pvt_t *del_pvt) pvt_t *p, *l = NULL; int r = 0; - if (!t38_state_list.thread_running) goto end; - + switch_mutex_lock(t38_state_list.mutex); + for (p = t38_state_list.head; p; p = p->next) { if (p == del_pvt) { if (l) { @@ -163,34 +172,38 @@ static int del_pvt(pvt_t *del_pvt) } p->next = NULL; r = 1; - goto end; + break; } l = p; } - end: - switch_mutex_unlock(t38_state_list.mutex); - return r; + wake_thread(0); + return r; } static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void *obj) { switch_timer_t timer = { 0 }; pvt_t *pvt; - int samples = 240; - int ms = 30; + int samples = 160; + int ms = 20; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "timer thread started.\n"); + switch_mutex_lock(t38_state_list.mutex); + t38_state_list.thread_running = 1; + switch_mutex_unlock(t38_state_list.mutex); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FAX timer thread started.\n"); if (switch_core_timer_init(&timer, "soft", ms, samples, NULL) != SWITCH_STATUS_SUCCESS) { - return NULL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "timer init failed.\n"); + goto end; } - t38_state_list.thread_running = 1; + switch_mutex_lock(globals.cond_mutex); while(t38_state_list.thread_running) { @@ -198,7 +211,9 @@ static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void * if (!t38_state_list.head) { switch_mutex_unlock(t38_state_list.mutex); - goto end; + switch_thread_cond_wait(globals.cond, globals.cond_mutex); + switch_core_timer_sync(&timer); + continue; } for (pvt = t38_state_list.head; pvt; pvt = pvt->next) { @@ -211,13 +226,20 @@ static void *SWITCH_THREAD_FUNC timer_thread_run(switch_thread_t *thread, void * switch_core_timer_next(&timer); } + + switch_mutex_unlock(globals.cond_mutex); end: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "timer thread ended.\n"); - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FAX timer thread ended.\n"); + + switch_mutex_lock(t38_state_list.mutex); t38_state_list.thread_running = 0; - switch_core_timer_destroy(&timer); + switch_mutex_unlock(t38_state_list.mutex); + + if (timer.timer_interface) { + switch_core_timer_destroy(&timer); + } return NULL; } @@ -468,49 +490,61 @@ static switch_status_t spanfax_init(pvt_t *pvt, transport_mode_t trans_mode) } break; case T38_MODE: - if (pvt->t38_state == NULL) { - pvt->t38_state = (t38_terminal_state_t *) switch_core_session_alloc(pvt->session, sizeof(t38_terminal_state_t)); - } - if (pvt->t38_state == NULL) { - return SWITCH_STATUS_FALSE; - } - if (pvt->udptl_state == NULL) { - pvt->udptl_state = (udptl_state_t *) switch_core_session_alloc(pvt->session, sizeof(udptl_state_t)); - } - if (pvt->udptl_state == NULL) { - t38_terminal_free(pvt->t38_state); - pvt->t38_state = NULL; - return SWITCH_STATUS_FALSE; - } + { + switch_core_session_message_t msg = { 0 }; - /* add to timer thread processing */ - add_pvt(pvt); + if (pvt->t38_state == NULL) { + pvt->t38_state = (t38_terminal_state_t *) switch_core_session_alloc(pvt->session, sizeof(t38_terminal_state_t)); + } + if (pvt->t38_state == NULL) { + return SWITCH_STATUS_FALSE; + } + if (pvt->udptl_state == NULL) { + pvt->udptl_state = (udptl_state_t *) switch_core_session_alloc(pvt->session, sizeof(udptl_state_t)); + } + if (pvt->udptl_state == NULL) { + t38_terminal_free(pvt->t38_state); + pvt->t38_state = NULL; + return SWITCH_STATUS_FALSE; + } + + t38 = pvt->t38_state; + t30 = t38_terminal_get_t30_state(t38); + + memset(t38, 0, sizeof(t38_terminal_state_t)); + + if (t38_terminal_init(t38, pvt->caller, t38_tx_packet_handler, pvt) == NULL) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my T.38 structs\n"); + return SWITCH_STATUS_FALSE; + } + + pvt->t38_core = t38_terminal_get_t38_core_state(pvt->t38_state); + + if (udptl_init(pvt->udptl_state, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, + (udptl_rx_packet_handler_t *) t38_core_rx_ifp_packet, (void *) pvt->t38_core) == NULL) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my UDPTL structs\n"); + return SWITCH_STATUS_FALSE; + } + + msg.from = __FILE__; + msg.message_id = SWITCH_MESSAGE_INDICATE_UDPTL_MODE; + switch_core_session_receive_message(pvt->session, &msg); - t38 = pvt->t38_state; - t30 = t38_terminal_get_t30_state(t38); + /* add to timer thread processing */ + if (!add_pvt(pvt)) { + if (channel) { + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + } + } + + span_log_set_message_handler(&t38->logging, spanfax_log_message); + span_log_set_message_handler(&t30->logging, spanfax_log_message); - memset(t38, 0, sizeof(t38_terminal_state_t)); - - if (t38_terminal_init(t38, pvt->caller, t38_tx_packet_handler, pvt) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my T.38 structs\n"); - return SWITCH_STATUS_FALSE; - } - - pvt->t38_core = t38_terminal_get_t38_core_state(pvt->t38_state); - - if (udptl_init(pvt->udptl_state, UDPTL_ERROR_CORRECTION_REDUNDANCY, 3, 3, - (udptl_rx_packet_handler_t *) t38_core_rx_ifp_packet, (void *) pvt->t38_core) == NULL) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot initialize my UDPTL structs\n"); - return SWITCH_STATUS_FALSE; - } - - span_log_set_message_handler(&t38->logging, spanfax_log_message); - span_log_set_message_handler(&t30->logging, spanfax_log_message); - - if (pvt->verbose) { - span_log_set_level(&t38->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); - span_log_set_level(&t30->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); - } + if (pvt->verbose) { + span_log_set_level(&t38->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_level(&t30->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + } + } break; case T38_GATEWAY_MODE: if (pvt->t38_gateway_state == NULL) { @@ -757,9 +791,9 @@ static t38_mode_t negotiate_t38(pvt_t *pvt) t38_options->T38FaxRateManagement = "transferredTCF"; t38_options->T38FaxMaxBuffer = 2000; t38_options->T38FaxMaxDatagram = LOCAL_FAX_MAX_DATAGRAM; - if (strcasecmp(t38_options->T38FaxUdpEC, "t38UDPRedundancy") == 0 - || - strcasecmp(t38_options->T38FaxUdpEC, "t38UDPFEC") == 0) { + if (!zstr(t38_options->T38FaxUdpEC) && + (strcasecmp(t38_options->T38FaxUdpEC, "t38UDPRedundancy") == 0 || + strcasecmp(t38_options->T38FaxUdpEC, "t38UDPFEC") == 0)) { t38_options->T38FaxUdpEC = "t38UDPRedundancy"; } else { t38_options->T38FaxUdpEC = NULL; @@ -818,6 +852,12 @@ static t38_mode_t request_t38(pvt_t *pvt) insist = globals.enable_t38_insist; } + if ((t38_options = switch_channel_get_private(channel, "t38_options"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "%s already has T.38 data\n", switch_channel_get_name(channel)); + enabled = 0; + } + if (enabled) { t38_options = switch_core_session_alloc(session, sizeof(*t38_options)); @@ -960,6 +1000,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat switch_frame_t write_frame = { 0 }; switch_codec_implementation_t read_impl = { 0 }; int16_t *buf = NULL; + uint32_t req_counter = 0; switch_core_session_get_read_impl(session, &read_impl); @@ -1075,10 +1116,11 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat switch_ivr_sleep(session, 250, SWITCH_TRUE, NULL); - - /* If you have the means, I highly recommend picking one up. ...*/ - request_t38(pvt); - + if (pvt->app_mode == FUNCTION_TX) { + req_counter = 100; + } else { + req_counter = 50; + } while (switch_channel_ready(channel)) { int tx = 0; @@ -1122,6 +1164,13 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat break; case T38_MODE_UNKNOWN: { + if (req_counter) { + if (!--req_counter) { + /* If you have the means, I highly recommend picking one up. ...*/ + request_t38(pvt); + } + } + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { if (negotiate_t38(pvt) == T38_MODE_NEGOTIATED) { /* is is safe to call this again, it was already called above in AUDIO_MODE */ @@ -1145,8 +1194,6 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "READ %d udptl bytes\n", read_frame->packetlen); udptl_rx_packet(pvt->udptl_state, read_frame->packet, read_frame->packetlen); - - } } continue; @@ -1282,6 +1329,8 @@ void mod_spandsp_fax_event_handler(switch_event_t *event) void mod_spandsp_fax_load(switch_memory_pool_t *pool) { + uint32_t sanity = 200; + memset(&globals, 0, sizeof(globals)); memset(&t38_state_list, 0, sizeof(t38_state_list)); @@ -1289,6 +1338,9 @@ void mod_spandsp_fax_load(switch_memory_pool_t *pool) switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); switch_mutex_init(&t38_state_list.mutex, SWITCH_MUTEX_NESTED, globals.pool); + + switch_mutex_init(&globals.cond_mutex, SWITCH_MUTEX_NESTED, globals.pool); + switch_thread_cond_create(&globals.cond, globals.pool); globals.enable_t38 = 1; globals.total_sessions = 0; @@ -1301,10 +1353,22 @@ void mod_spandsp_fax_load(switch_memory_pool_t *pool) strncpy(globals.header, "SpanDSP Fax Header", sizeof(globals.header) - 1); load_configuration(0); + + + launch_timer_thread(); + + while(--sanity && !t38_state_list.thread_running) { + switch_yield(20000); + } } void mod_spandsp_fax_shutdown(void) { + switch_status_t tstatus = SWITCH_STATUS_SUCCESS; + + t38_state_list.thread_running = 0; + wake_thread(1); + switch_thread_join(&tstatus, t38_state_list.thread); memset(&globals, 0, sizeof(globals)); } @@ -1659,8 +1723,8 @@ static switch_status_t t38_gateway_on_reset(switch_core_session_t *session) switch_channel_clear_flag(channel, CF_REDIRECT); - if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)) { - switch_channel_clear_app_flag(channel, CF_APP_TAGGED); + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_TAGGED)) { + switch_channel_clear_app_flag_key("T38", channel, CF_APP_TAGGED); switch_channel_set_state(channel, CS_CONSUME_MEDIA); } else { switch_channel_set_state(channel, CS_SOFT_EXECUTE); @@ -1697,6 +1761,9 @@ 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_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s starting gateway mode to %s\n", switch_channel_get_name(peer ? channel : other_channel), @@ -1709,8 +1776,8 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, switch_channel_add_state_handler(channel, &t38_gateway_state_handlers); switch_channel_add_state_handler(other_channel, &t38_gateway_state_handlers); - switch_channel_set_app_flag(peer ? channel : other_channel, CF_APP_TAGGED); - switch_channel_clear_app_flag(peer ? other_channel : channel, CF_APP_TAGGED); + switch_channel_set_app_flag_key("T38", peer ? channel : other_channel, CF_APP_TAGGED); + switch_channel_clear_app_flag_key("T38", peer ? other_channel : channel, CF_APP_TAGGED); switch_channel_set_flag(channel, CF_REDIRECT); switch_channel_set_state(channel, CS_RESET); diff --git a/src/mod/applications/mod_spandsp/udptl.c b/src/mod/applications/mod_spandsp/udptl.c index a2651513f0..f5b3be2445 100644 --- a/src/mod/applications/mod_spandsp/udptl.c +++ b/src/mod/applications/mod_spandsp/udptl.c @@ -93,7 +93,7 @@ static int encode_length(uint8_t *buf, int *len, int value) if (value < 0x80) { /* 1 octet */ - buf[(*len)++] = value; + buf[(*len)++] = (uint8_t)value; return value; } if (value < 0x4000) { @@ -106,7 +106,7 @@ static int encode_length(uint8_t *buf, int *len, int value) /* Fragmentation */ multiplier = (value < 0x10000) ? (value >> 14) : 4; /* Set the first 2 bits of the octet */ - buf[(*len)++] = 0xC0 | multiplier; + buf[(*len)++] = (uint8_t) (0xC0 | multiplier); return multiplier << 14; } @@ -419,10 +419,10 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int /* Span is defined as an inconstrained integer, which it dumb. It will only ever be a small value. Treat it as such. */ buf[len++] = 1; - buf[len++] = span; + buf[len++] = (uint8_t)span; /* The number of entries is defined as a length, but will only ever be a small value. Treat it as such. */ - buf[len++] = entries; + buf[len++] = (uint8_t)entries; for (m = 0; m < entries; m++) { /* Make an XOR'ed entry the maximum length */ limit = (entry + m) & UDPTL_BUF_MASK; diff --git a/src/mod/applications/mod_valet_parking/mod_valet_parking.c b/src/mod/applications/mod_valet_parking/mod_valet_parking.c index aee49c76e9..b75202189c 100644 --- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c +++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c @@ -203,7 +203,7 @@ SWITCH_STANDARD_APP(valet_parking_function) } do { - status = switch_ivr_read(session, min, max, prompt, NULL, dtmf_buf, sizeof(dtmf_buf), to, "#"); + status = switch_ivr_read(session, min, max, prompt, NULL, dtmf_buf, sizeof(dtmf_buf), to, "#", 0); } while (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_FALSE); if (status == SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index c683712922..860f89788b 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -824,7 +824,8 @@ static switch_status_t control_playback(switch_core_session_t *session, void *in if (!cc->noexit && (dtmf->digit == *cc->profile->delete_file_key || dtmf->digit == *cc->profile->save_file_key || dtmf->digit == *cc->profile->prev_msg_key || dtmf->digit == *cc->profile->next_msg_key - || dtmf->digit == *cc->profile->terminator_key || dtmf->digit == *cc->profile->skip_info_key)) { + || dtmf->digit == *cc->profile->terminator_key || dtmf->digit == *cc->profile->skip_info_key + || dtmf->digit == *cc->profile->email_key || dtmf->digit == *cc->profile->forward_key)) { *cc->buf = dtmf->digit; return SWITCH_STATUS_BREAK; } @@ -1421,6 +1422,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t char cid_buf[1024] = ""; if (switch_channel_ready(channel)) { + const char *vm_announce_cid = NULL; switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", cbt->cid_number, cbt->cid_name); @@ -1428,7 +1430,13 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t msg.string_arg = cid_buf; msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY; switch_core_session_receive_message(session, &msg); - + + if (!zstr(cbt->cid_number) && (vm_announce_cid = switch_channel_get_variable(channel, "vm_announce_cid"))) { + switch_ivr_play_file(session, NULL, vm_announce_cid, NULL); + switch_ivr_sleep(session, 500, SWITCH_TRUE, NULL); + switch_ivr_say(session, cbt->cid_number, NULL, "name_spelled", "pronounced", NULL, NULL); + } + args.input_callback = cancel_on_dtmf; switch_snprintf(key_buf, sizeof(key_buf), "%s:%s:%s:%s:%s:%s%s%s", profile->listen_file_key, profile->save_file_key, @@ -1523,7 +1531,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t vm_cc[0] = '\0'; TRY_CODE(switch_ivr_read - (session, 0, sizeof(vm_cc), macro_buf, NULL, vm_cc, sizeof(vm_cc), profile->digit_timeout, profile->terminator_key)); + (session, 0, sizeof(vm_cc), macro_buf, NULL, vm_cc, sizeof(vm_cc), profile->digit_timeout, profile->terminator_key, 0)); cmd = switch_core_session_sprintf(session, "%s@%s %s %s '%s'", vm_cc, cbt->domain, new_file_path, cbt->cid_number, cbt->cid_name); @@ -1987,7 +1995,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p switch_xml_t xx_user, xx_domain, xx_domain_root; switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", VM_ENTER_PASS_MACRO, profile->terminator_key); - TRY_CODE(switch_ivr_read(session, 0, 255, macro, NULL, buf, sizeof(buf), 10000, profile->terminator_key)); + TRY_CODE(switch_ivr_read(session, 0, 255, macro, NULL, buf, sizeof(buf), 10000, profile->terminator_key, 0)); sql = switch_mprintf("update voicemail_prefs set password='%s' where username='%s' and domain='%s'", buf, myid, domain_name); vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(file_path); @@ -2686,23 +2694,29 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t if ((domain = strchr(user, '@'))) { *domain++ = '\0'; - } else { - domain = user; - } - if ((profile_name = strchr(domain, '@'))) { - *profile_name++ = '\0'; - } else { - profile_name = domain; + if ((profile_name = strchr(domain, '@'))) { + *profile_name++ = '\0'; + } else { + profile_name = domain; + } } if (switch_stristr("group=", user)) { user += 6; isgroup++; - } else if (user == domain) { + } else if (switch_stristr("domain=", user)) { + user += 7; + domain = user; + profile_name = domain; isall++; } + if (zstr(domain)) { + domain = switch_core_get_variable("domain"); + profile_name = domain; + } + if (!(user && domain)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid syntax [%s][%s]\n", switch_str_nil(user), switch_str_nil(domain)); status = SWITCH_STATUS_FALSE; @@ -2746,6 +2760,7 @@ static switch_status_t voicemail_inject(const char *data, switch_core_session_t switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain); status = SWITCH_STATUS_FALSE; switch_event_destroy(&my_params); + profile_rwunlock(profile); goto end; } @@ -3164,7 +3179,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p switch_event_destroy(&vars); if (status == SWITCH_STATUS_SUCCESS) { if ((vm_cc = switch_channel_get_variable(channel, "vm_cc"))) { - char *cmd = switch_core_session_sprintf(session, "%s %s %s %s %s@%s %s", + char *cmd = switch_core_session_sprintf(session, "%s %s %s '%s' %s@%s %s", vm_cc, file_path, caller_id_number, caller_id_name, id, domain_name, read_flags); if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) { @@ -3670,7 +3685,7 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames) const char *fmt = "%a, %e %b %Y %T %z"; char heard[80]; char title_b4[128] = ""; - char title_aft[128 * 3] = ""; + char title_aft[128 * 3 + 1] = ""; if (argc > 0) { l_created = switch_time_make(atol(argv[0]), 0); @@ -3961,7 +3976,7 @@ static void do_web(vm_profile_t *profile, const char *user_in, const char *domai } } -#define VM_INJECT_USAGE "[group=]<box> <sound_file> [<cid_num>] [<cid_name>]" +#define VM_INJECT_USAGE "[group=<group>[@domain]|domain=<domain>|<box>[@<domain>]] <sound_file> [<cid_num>] [<cid_name>]" SWITCH_STANDARD_API(voicemail_inject_api_function) { if (voicemail_inject(cmd, session) == SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index 139fe217a3..4b36e1435e 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -2724,7 +2724,7 @@ static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec name++; name = switch_core_sprintf(ah->memory_pool, "%s ASR-%d", name, speech_channel_number); } else { - name = switch_core_sprintf(ah->memory_pool, "ASR-%d", name, speech_channel_number); + name = switch_core_sprintf(ah->memory_pool, "ASR-%d", speech_channel_number); } /* Allocate the channel */ diff --git a/src/mod/codecs/mod_amr/mod_amr.c b/src/mod/codecs/mod_amr/mod_amr.c index a864254e28..e8925c4581 100644 --- a/src/mod/codecs/mod_amr/mod_amr.c +++ b/src/mod/codecs/mod_amr/mod_amr.c @@ -98,11 +98,8 @@ typedef enum { AMR_DTX_ENABLED } amr_dtx_t; -struct amr_context { - void *encoder_state; - void *decoder_state; - switch_byte_t enc_modes; - switch_byte_t enc_mode; +/*! \brief Various codec settings */ +struct amr_codec_settings { int dtx_mode; uint32_t change_period; switch_byte_t max_ptime; @@ -110,6 +107,24 @@ struct amr_context { switch_byte_t channels; switch_byte_t flags; }; +typedef struct amr_codec_settings amr_codec_settings_t; + +static amr_codec_settings_t default_codec_settings = { + /*.dtx_mode */ AMR_DTX_ENABLED, + /*.change_period */ 0, + /*.max_ptime */ 0, + /*.ptime */ 0, + /*.channels */ 0, + /*.flags */ 0, +}; + + +struct amr_context { + void *encoder_state; + void *decoder_state; + switch_byte_t enc_modes; + switch_byte_t enc_mode; +}; #define AMR_DEFAULT_BITRATE AMR_BITRATE_1220 @@ -117,6 +132,88 @@ static struct { switch_byte_t default_bitrate; } globals; +static switch_status_t switch_amr_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + amr_codec_settings_t *codec_settings = NULL; + if (codec_fmtp->private_info) { + codec_settings = codec_fmtp->private_info; + memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); + } + + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + + argc = switch_separate_string((char *) fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + /* + if (!strcasecmp(data, "bitrate")) { + bit_rate = atoi(arg); + } + */ + if (codec_settings) { + if (!strcasecmp(data, "octet-align")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_OCTET_ALIGN); + } + } else if (!strcasecmp(data, "mode-change-neighbor")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_MODE_CHANGE_NEIGHBOR); + } + } else if (!strcasecmp(data, "crc")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_CRC); + } + } else if (!strcasecmp(data, "robust-sorting")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_ROBUST_SORTING); + } + } else if (!strcasecmp(data, "interveaving")) { + if (atoi(arg)) { + switch_set_flag(codec_settings, AMR_OPT_INTERLEAVING); + } + } else if (!strcasecmp(data, "mode-change-period")) { + codec_settings->change_period = atoi(arg); + } else if (!strcasecmp(data, "ptime")) { + codec_settings->ptime = (switch_byte_t) atoi(arg); + } else if (!strcasecmp(data, "channels")) { + codec_settings->channels = (switch_byte_t) atoi(arg); + } else if (!strcasecmp(data, "maxptime")) { + codec_settings->max_ptime = (switch_byte_t) atoi(arg); + } else if (!strcasecmp(data, "mode-set")) { + int y, m_argc; + char *m_argv[7]; + m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); + for (y = 0; y < m_argc; y++) { + codec_settings->enc_modes |= (1 << atoi(m_argv[y])); + } + } else if (!strcasecmp(data, "dtx")) { + codec_settings->dtx_mode = (atoi(arg)) ? AMR_DTX_ENABLED : AMR_DTX_DISABLED; + } + } + + } + } + free(fmtp_dup); + } + //codec_fmtp->bits_per_second = bit_rate; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + #endif static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) @@ -128,7 +225,10 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ } return SWITCH_STATUS_SUCCESS; #else + struct amr_context *context = NULL; + switch_codec_fmtp_t codec_fmtp; + amr_codec_settings_t amr_codec_settings; int encoding, decoding; int x, i, argc; char *argv[10]; @@ -141,58 +241,9 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_ return SWITCH_STATUS_FALSE; } else { - context->dtx_mode = AMR_DTX_ENABLED; - if (codec->fmtp_in) { - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - while (*data && *data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "octet-align")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_OCTET_ALIGN); - } - } else if (!strcasecmp(data, "mode-change-neighbor")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_MODE_CHANGE_NEIGHBOR); - } - } else if (!strcasecmp(data, "crc")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_CRC); - } - } else if (!strcasecmp(data, "robust-sorting")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_ROBUST_SORTING); - } - } else if (!strcasecmp(data, "interveaving")) { - if (atoi(arg)) { - switch_set_flag(context, AMR_OPT_INTERLEAVING); - } - } else if (!strcasecmp(data, "mode-change-period")) { - context->change_period = atoi(arg); - } else if (!strcasecmp(data, "ptime")) { - context->ptime = (switch_byte_t) atoi(arg); - } else if (!strcasecmp(data, "channels")) { - context->channels = (switch_byte_t) atoi(arg); - } else if (!strcasecmp(data, "maxptime")) { - context->max_ptime = (switch_byte_t) atoi(arg); - } else if (!strcasecmp(data, "mode-set")) { - int y, m_argc; - char *m_argv[7]; - m_argc = switch_separate_string(arg, ',', m_argv, (sizeof(m_argv) / sizeof(m_argv[0]))); - for (y = 0; y < m_argc; y++) { - context->enc_modes |= (1 << atoi(m_argv[y])); - } - } else if (!strcasecmp(data, "dtx")) { - context->dtx_mode = (atoi(arg)) ? AMR_DTX_ENABLED : AMR_DTX_DISABLED; - } - } - } - } + memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + codec_fmtp.private_info = &amr_codec_settings; + switch_amr_fmtp_parse(codec->fmtp_in, &codec_fmtp); if (context->enc_modes) { for (i = 7; i > -1; i++) { @@ -321,6 +372,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amr_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "AMR"); +#ifndef AMR_PASSTHROUGH + codec_interface->parse_fmtp = switch_amr_fmtp_parse; +#endif switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 96, /* the IANA code number */ "AMR", /* the IANA code name */ diff --git a/src/mod/codecs/mod_codec2/Makefile b/src/mod/codecs/mod_codec2/Makefile new file mode 100644 index 0000000000..568df9c64d --- /dev/null +++ b/src/mod/codecs/mod_codec2/Makefile @@ -0,0 +1,14 @@ +BASE=../../../.. + +CODEC2_DIR=$(switch_srcdir)/libs/libcodec2 +CODEC2_BUILDDIR=$(switch_builddir)/libs/libcodec2 +CODEC2LA=$(CODEC2_BUILDDIR)/src/libcodec2.la + +LOCAL_CFLAGS=-I$(CODEC2_DIR)/include -I$(CODEC2_BUILDDIR)/src +LOCAL_LIBADD=$(CODEC2LA) +include $(BASE)/build/modmake.rules + +$(CODEC2LA): $(CODEC2_DIR) $(CODEC2_DIR)/.update + cd $(CODEC2_BUILDDIR) && $(MAKE) + $(TOUCH_TARGET) + diff --git a/src/mod/codecs/mod_codec2/mod_codec2.c b/src/mod/codecs/mod_codec2/mod_codec2.c new file mode 100644 index 0000000000..e7aa645090 --- /dev/null +++ b/src/mod/codecs/mod_codec2/mod_codec2.c @@ -0,0 +1,264 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org> + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library + * + * The Initial Developer of the Original Code is + * Brian West <brian@freeswitch.org> + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mathieu Rene <mrene@avgs.ca> + * + * mod_codec2 -- FreeSWITCH CODEC2 Module + * + */ + +#include <switch.h> +#include <codec2.h> + +/* Uncomment to log input/output data for debugging +#define LOG_DATA +#define CODEC2_DEBUG +*/ + +#ifdef CODEC2_DEBUG +#define codec2_assert(_x) switch_assert(_x) +#else +#define codec2_assert(_x) +#endif + +SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load); + +SWITCH_MODULE_DEFINITION(mod_codec2, mod_codec2_load, NULL, NULL); + +struct codec2_context { + void *encoder; + void *decoder; +#ifdef LOG_DATA + FILE *encoder_in; + FILE *encoder_out; + FILE *encoder_out_unpacked; + FILE *decoder_in; + FILE *decoder_in_unpacked; + FILE *decoder_out; +#endif +}; + +#ifdef LOG_DATA +static int c2_count = 0; +#endif + +static switch_status_t switch_codec2_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) +{ + uint32_t encoding, decoding; + struct codec2_context *context = NULL; + + encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); + decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + + if (!(encoding || decoding)) { + return SWITCH_STATUS_FALSE; + } + + if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) { + return SWITCH_STATUS_FALSE; + } + + if (encoding) { + context->encoder = codec2_create(); + } + + if (decoding) { + context->decoder = codec2_create(); + } + + codec->private_info = context; + +#ifdef LOG_DATA + { + + int c = c2_count++; + char buf[1024]; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Logging as /tmp/c2-%d-*\n", c); + + if (encoding) { + snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-in", c); + context->encoder_in = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-out", c); + context->encoder_out = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-enc-out-unpacked", c); + context->encoder_out_unpacked = fopen(buf, "w"); + } + if (decoding) { + snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-in", c); + context->decoder_in = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-out", c); + context->decoder_out = fopen(buf, "w"); + + snprintf(buf, sizeof(buf), "/tmp/c2-%d-dec-out-unpacked", c); + context->decoder_in_unpacked = fopen(buf, "w"); + } + } +#endif + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_codec2_encode(switch_codec_t *codec, switch_codec_t *other_codec, + void *decoded_data, + uint32_t decoded_data_len, + uint32_t decoded_rate, + void *encoded_data, + uint32_t *encoded_data_len, + uint32_t *encoded_rate, + unsigned int *flag) +{ + struct codec2_context *context = codec->private_info; + + codec2_assert(decoded_data_len == CODEC2_SAMPLES_PER_FRAME * 2); + +#ifdef LOG_DATA + fwrite(decoded_data, decoded_data_len, 1, context->encoder_in); + fflush(context->encoder_in); +#endif + + codec2_encode(context->encoder, encoded_data, decoded_data); + +#ifdef LOG_DATA + fwrite(encode_buf, sizeof(encode_buf), 1, context->encoder_out_unpacked); + fflush(context->encoder_out_unpacked); + fwrite(encoded_data, 8, 1, context->encoder_out); + fflush(context->encoder_out); +#endif + + *encoded_data_len = 8; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_codec2_decode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *encoded_data, + uint32_t encoded_data_len, + uint32_t encoded_rate, + void *decoded_data, + uint32_t *decoded_data_len, + uint32_t *decoded_rate, + unsigned int *flag) +{ + struct codec2_context *context = codec->private_info; + + codec2_assert(encoded_data_len == 8 /* aligned to 8 */); + +#ifdef LOG_DATA + fwrite(encoded_data, encoded_data_len, 1, context->decoder_in); + fflush(context->decoder_in); + fwrite(bits, sizeof(bits), 1, context->decoder_in_unpacked); + fflush(context->decoder_in_unpacked); +#endif + + codec2_decode(context->decoder, decoded_data, encoded_data); + +#ifdef LOG_DATA + fwrite(decoded_data, CODEC2_SAMPLES_PER_FRAME, 2, context->decoder_out); + fflush(context->decoder_out); +#endif + + *decoded_data_len = CODEC2_SAMPLES_PER_FRAME * 2; /* 160 samples */ + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_codec2_destroy(switch_codec_t *codec) +{ + struct codec2_context *context = codec->private_info; + + codec2_destroy(context->encoder); + codec2_destroy(context->decoder); + + context->encoder = NULL; + context->decoder = NULL; + +#ifdef LOG_DATA + if (context->encoder_in) { + fclose(context->encoder_in); + } + if (context->encoder_out) { + fclose(context->encoder_out); + } + if (context->encoder_out_unpacked) { + fclose(context->encoder_out_unpacked); + } + if (context->decoder_in) { + fclose(context->decoder_in); + } + if (context->decoder_in_unpacked) { + fclose(context->decoder_in_unpacked); + } + if (context->decoder_out) { + fclose(context->decoder_out); + } +#endif + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load) +{ + switch_codec_interface_t *codec_interface; + + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_CODEC(codec_interface, "CODEC2 2550bps"); + + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, + 111, + "CODEC2", + NULL, + 8000, /* samples/sec */ + 8000, /* samples/sec */ + 2550, /* bps */ + 20000, /* ptime */ + CODEC2_SAMPLES_PER_FRAME, /* samples decoded */ + CODEC2_SAMPLES_PER_FRAME*2, /* bytes decoded */ + 0, /* bytes encoded */ + 1, /* channels */ + 1, /* frames/packet */ + switch_codec2_init, + switch_codec2_encode, + switch_codec2_decode, + switch_codec2_destroy); + + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/codecs/mod_ilbc/mod_ilbc.c b/src/mod/codecs/mod_ilbc/mod_ilbc.c index b37056c393..85298375db 100644 --- a/src/mod/codecs/mod_ilbc/mod_ilbc.c +++ b/src/mod/codecs/mod_ilbc/mod_ilbc.c @@ -40,6 +40,27 @@ struct ilbc_context { ilbc_decode_state_t decoder_object; }; +static switch_status_t switch_ilbc_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + char *mode = NULL; + int codec_ms = 0; + + memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + + if (fmtp && (mode = strstr(fmtp, "mode=")) && (mode + 5)) { + codec_ms = atoi(mode + 5); + } + if (!codec_ms) { + /* default to 30 when no mode is defined for ilbc ONLY */ + codec_ms = 30; + } + codec_fmtp->microseconds_per_packet = (codec_ms * 1000); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct ilbc_context *context; @@ -51,26 +72,6 @@ static switch_status_t switch_ilbc_init(switch_codec_t *codec, switch_codec_flag return SWITCH_STATUS_FALSE; } - if (codec->fmtp_in) { - int x, argc; - char *argv[10]; - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - switch_assert(data); - while (*data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "mode")) { - mode = atoi(arg); - } - } - } - } - codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "mode=%d", mode); if (encoding) { @@ -136,6 +137,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_ilbc_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "iLBC"); + codec_interface->parse_fmtp = switch_ilbc_fmtp_parse; switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 98, /* the IANA code number */ diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index 9d0abcdf8b..934c9ebe32 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -41,6 +41,22 @@ SWITCH_MODULE_DEFINITION(mod_silk, mod_silk_load, NULL, NULL); #define MAX_LBRR_DELAY 2 #define MAX_FRAME_LENGTH 480 +/*! \brief Various codec settings */ +struct silk_codec_settings { + SKP_int useinbandfec; + SKP_int usedtx; + SKP_int maxaveragebitrate; + SKP_int plpct; +}; +typedef struct silk_codec_settings silk_codec_settings_t; + +static silk_codec_settings_t default_codec_settings = { + /*.useinbandfec */ 0, + /*.usedtx */ 0, + /*.maxaveragebitrate */ 0, + /*.plpct */ 10, // 10% for now +}; + struct silk_context { SKP_SILK_SDK_EncControlStruct encoder_object; SKP_SILK_SDK_DecControlStruct decoder_object; @@ -48,12 +64,105 @@ struct silk_context { void *dec_state; }; +static switch_status_t switch_silk_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + silk_codec_settings_t *codec_settings = NULL; + + if (codec_fmtp->private_info) { + codec_settings = codec_fmtp->private_info; + memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); + } + + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + if (codec_settings) { + if (!strcasecmp(data, "useinbandfec")) { + if (switch_true(arg)) { + codec_settings->useinbandfec = 1; + } + } + if (!strcasecmp(data, "usedtx")) { + if (switch_true(arg)) { + codec_settings->usedtx = 1; + } + } + if (!strcasecmp(data, "maxaveragebitrate")) { + codec_settings->maxaveragebitrate = atoi(arg); + switch(codec_fmtp->actual_samples_per_second) { + case 8000: + { + if(codec_settings->maxaveragebitrate < 6000 || codec_settings->maxaveragebitrate > 20000) { + codec_settings->maxaveragebitrate = 20000; + } + break; + } + case 12000: + { + if(codec_settings->maxaveragebitrate < 7000 || codec_settings->maxaveragebitrate > 25000) { + codec_settings->maxaveragebitrate = 25000; + } + break; + } + case 16000: + { + if(codec_settings->maxaveragebitrate < 8000 || codec_settings->maxaveragebitrate > 30000) { + codec_settings->maxaveragebitrate = 30000; + } + break; + } + case 24000: + { + if(codec_settings->maxaveragebitrate < 12000 || codec_settings->maxaveragebitrate > 40000) { + codec_settings->maxaveragebitrate = 40000; + } + break; + } + + default: + /* this should never happen but 20000 is common among all rates */ + codec_settings->maxaveragebitrate = 20000; + break; + } + + } + + } + } + } + free(fmtp_dup); + } + //codec_fmtp->bits_per_second = bit_rate; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + + + + static switch_status_t switch_silk_init(switch_codec_t *codec, switch_codec_flag_t freeswitch_flags, const switch_codec_settings_t *codec_settings) { struct silk_context *context = NULL; - SKP_int useinbandfec = 0, usedtx = 0, maxaveragebitrate = 0, plpct =0; + switch_codec_fmtp_t codec_fmtp; + silk_codec_settings_t silk_codec_settings; SKP_int32 encSizeBytes; SKP_int32 decSizeBytes; int encoding = (freeswitch_flags & SWITCH_CODEC_FLAG_ENCODE); @@ -62,78 +171,15 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } - - if (codec->fmtp_in) { - int x, argc; - char *argv[10]; - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - switch_assert(data); - while (*data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "useinbandfec")) { - if (switch_true(arg)) { - useinbandfec = 1; - plpct = 10;// 10% for now - } - } - if (!strcasecmp(data, "usedtx")) { - if (switch_true(arg)) { - usedtx = 1; - } - } - if (!strcasecmp(data, "maxaveragebitrate")) { - maxaveragebitrate = atoi(arg); - switch(codec->implementation->actual_samples_per_second) { - case 8000: - { - if(maxaveragebitrate < 6000 || maxaveragebitrate > 20000) { - maxaveragebitrate = 20000; - } - break; - } - case 12000: - { - if(maxaveragebitrate < 7000 || maxaveragebitrate > 25000) { - maxaveragebitrate = 25000; - } - break; - } - case 16000: - { - if(maxaveragebitrate < 8000 || maxaveragebitrate > 30000) { - maxaveragebitrate = 30000; - } - break; - } - case 24000: - { - if(maxaveragebitrate < 12000 || maxaveragebitrate > 40000) { - maxaveragebitrate = 40000; - } - break; - } - - default: - /* this should never happen but 20000 is common among all rates */ - maxaveragebitrate = 20000; - break; - } - - } - } - } - } + + memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + codec_fmtp.private_info = &silk_codec_settings; + switch_silk_fmtp_parse(codec->fmtp_in, &codec_fmtp); codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "useinbandfec=%s; usedtx=%s; maxaveragebitrate=%d", - useinbandfec ? "1" : "0", - usedtx ? "1" : "0", - maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second); + silk_codec_settings.useinbandfec ? "1" : "0", + silk_codec_settings.usedtx ? "1" : "0", + silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second); if (encoding) { if (SKP_Silk_SDK_Get_Encoder_Size(&encSizeBytes)) { @@ -148,11 +194,11 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, context->encoder_object.sampleRate = codec->implementation->actual_samples_per_second; context->encoder_object.packetSize = codec->implementation->samples_per_packet; - context->encoder_object.useInBandFEC = useinbandfec; + context->encoder_object.useInBandFEC = silk_codec_settings.useinbandfec; context->encoder_object.complexity = 0; - context->encoder_object.bitRate = maxaveragebitrate ? maxaveragebitrate : codec->implementation->bits_per_second; - context->encoder_object.useDTX = usedtx; - context->encoder_object.packetLossPercentage = plpct;; + context->encoder_object.bitRate = silk_codec_settings.maxaveragebitrate ? silk_codec_settings.maxaveragebitrate : codec->implementation->bits_per_second; + context->encoder_object.useDTX = silk_codec_settings.usedtx; + context->encoder_object.packetLossPercentage = silk_codec_settings.plpct; } if (decoding) { @@ -174,7 +220,7 @@ static switch_status_t switch_silk_init(switch_codec_t *codec, static switch_status_t switch_silk_destroy(switch_codec_t *codec) { - codec->private_info = NULL; + codec->private_info = NULL; return SWITCH_STATUS_SUCCESS; } @@ -299,6 +345,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_silk_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "SILK"); + codec_interface->parse_fmtp = switch_silk_fmtp_parse; switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 117, /* the IANA code number */ diff --git a/src/mod/codecs/mod_siren/mod_siren.c b/src/mod/codecs/mod_siren/mod_siren.c index 1ccd36eafb..4646ffc5ae 100644 --- a/src/mod/codecs/mod_siren/mod_siren.c +++ b/src/mod/codecs/mod_siren/mod_siren.c @@ -47,6 +47,40 @@ struct siren_context { g722_1_encode_state_t encoder_object; }; +static switch_status_t switch_siren_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + int bit_rate = 0; + memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + if (!strcasecmp(data, "bitrate")) { + bit_rate = atoi(arg); + } + } + } + free(fmtp_dup); + } + codec_fmtp->bits_per_second = bit_rate; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct siren_context *context = NULL; @@ -58,26 +92,6 @@ static switch_status_t switch_siren_init(switch_codec_t *codec, switch_codec_fla return SWITCH_STATUS_FALSE; } - if (codec->fmtp_in) { - int x, argc; - char *argv[10]; - argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); - for (x = 0; x < argc; x++) { - char *data = argv[x]; - char *arg; - switch_assert(data); - while (*data == ' ') { - data++; - } - if ((arg = strchr(data, '='))) { - *arg++ = '\0'; - if (!strcasecmp(data, "bitrate")) { - bit_rate = atoi(arg); - } - } - } - } - codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate); if (encoding) { @@ -145,6 +159,28 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_siren_load) *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "Polycom(R) G722.1/G722.1C"); + codec_interface->parse_fmtp = switch_siren_fmtp_parse; + + spf = 320, bpf = 640; + for (count = 3; count > 0; count--) { + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 107, /* the IANA code number */ + "G7221", /* the IANA code name */ + "bitrate=24000", /* default fmtp to send (can be overridden by the init function) */ + 16000, /* samples transferred per second */ + 16000, /* actual samples transferred per second */ + 24000, /* bits transferred per second */ + mpf * count, /* number of microseconds per frame */ + spf * count, /* number of samples per frame */ + bpf * count, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_siren_init, /* function to initialize a codec handle using this implementation */ + switch_siren_encode, /* function to encode raw data into encoded data */ + switch_siren_decode, /* function to decode encoded data into raw data */ + switch_siren_destroy); /* deinitalize a codec handle using this implementation */ + } spf = 320, bpf = 640; for (count = 3; count > 0; count--) { diff --git a/src/mod/codecs/mod_speex/mod_speex.c b/src/mod/codecs/mod_speex/mod_speex.c index 1d4a0409b8..a951b12d84 100644 --- a/src/mod/codecs/mod_speex/mod_speex.c +++ b/src/mod/codecs/mod_speex/mod_speex.c @@ -37,7 +37,46 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load); SWITCH_MODULE_DEFINITION(mod_speex, mod_speex_load, NULL, NULL); -static switch_codec_settings_t default_codec_settings = { +/* nobody has more setting than speex so we will let them set the standard */ +/*! \brief Various codec settings (currently only relevant to speex) */ +struct speex_codec_settings { + /*! desired quality */ + int quality; + /*! desired complexity */ + int complexity; + /*! desired enhancement */ + int enhancement; + /*! desired vad level */ + int vad; + /*! desired vbr level */ + int vbr; + /*! desired vbr quality */ + float vbr_quality; + /*! desired abr level */ + int abr; + /*! desired dtx setting */ + int dtx; + /*! desired preprocessor settings */ + int preproc; + /*! preprocessor vad settings */ + int pp_vad; + /*! preprocessor gain control settings */ + int pp_agc; + /*! preprocessor gain level */ + float pp_agc_level; + /*! preprocessor denoise level */ + int pp_denoise; + /*! preprocessor dereverb settings */ + int pp_dereverb; + /*! preprocessor dereverb decay level */ + float pp_dereverb_decay; + /*! preprocessor dereverb level */ + float pp_dereverb_level; +}; + +typedef struct speex_codec_settings speex_codec_settings_t; + +static speex_codec_settings_t default_codec_settings = { /*.quality */ 5, /*.complexity */ 5, /*.enhancement */ 1, @@ -58,6 +97,7 @@ static switch_codec_settings_t default_codec_settings = { struct speex_context { switch_codec_t *codec; + speex_codec_settings_t codec_settings; unsigned int flags; /* Encoder */ @@ -74,6 +114,56 @@ struct speex_context { int decoder_mode; }; +static switch_status_t switch_speex_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + speex_codec_settings_t *codec_settings = NULL; + if (codec_fmtp->private_info) { + codec_settings = codec_fmtp->private_info; + memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); + } + + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + /* + if (!strcasecmp(data, "bitrate")) { + bit_rate = atoi(arg); + } + */ + /* + if (codec_settings) { + if (!strcasecmp(data, "vad")) { + bit_rate = atoi(arg); + } + } + */ + } + } + free(fmtp_dup); + } + /*codec_fmtp->bits_per_second = bit_rate;*/ + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + + static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct speex_context *context = NULL; @@ -82,16 +172,18 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); decoding = (flags & SWITCH_CODEC_FLAG_DECODE); - if (!codec_settings) { - codec_settings = &default_codec_settings; - } - - memcpy(&codec->codec_settings, codec_settings, sizeof(codec->codec_settings)); - if (!(encoding || decoding) || ((context = switch_core_alloc(codec->memory_pool, sizeof(*context))) == 0)) { return SWITCH_STATUS_FALSE; } else { const SpeexMode *mode = NULL; + switch_codec_fmtp_t codec_fmtp; + speex_codec_settings_t codec_settings; + + memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + codec_fmtp.private_info = &codec_settings; + switch_speex_fmtp_parse(codec->fmtp_in, &codec_fmtp); + + memcpy(&context->codec_settings, &codec_settings, sizeof(context->codec_settings)); context->codec = codec; if (codec->implementation->actual_samples_per_second == 8000) { @@ -110,41 +202,41 @@ static switch_status_t switch_speex_init(switch_codec_t *codec, switch_codec_fla speex_bits_init(&context->encoder_bits); context->encoder_state = speex_encoder_init(mode); speex_encoder_ctl(context->encoder_state, SPEEX_GET_FRAME_SIZE, &context->encoder_frame_size); - speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &codec->codec_settings.complexity); - if (codec->codec_settings.preproc) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_COMPLEXITY, &context->codec_settings.complexity); + if (context->codec_settings.preproc) { context->pp = speex_preprocess_state_init(context->encoder_frame_size, codec->implementation->actual_samples_per_second); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &codec->codec_settings.pp_vad); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &codec->codec_settings.pp_agc); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &codec->codec_settings.pp_agc_level); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &codec->codec_settings.pp_denoise); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &codec->codec_settings.pp_dereverb); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &codec->codec_settings.pp_dereverb_decay); - speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &codec->codec_settings.pp_dereverb_level); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_VAD, &context->codec_settings.pp_vad); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC, &context->codec_settings.pp_agc); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &context->codec_settings.pp_agc_level); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DENOISE, &context->codec_settings.pp_denoise); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB, &context->codec_settings.pp_dereverb); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &context->codec_settings.pp_dereverb_decay); + speex_preprocess_ctl(context->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &context->codec_settings.pp_dereverb_level); } - if (!codec->codec_settings.abr && !codec->codec_settings.vbr) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &codec->codec_settings.quality); - if (codec->codec_settings.vad) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &codec->codec_settings.vad); + if (!context->codec_settings.abr && !context->codec_settings.vbr) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_QUALITY, &context->codec_settings.quality); + if (context->codec_settings.vad) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_VAD, &context->codec_settings.vad); } } - if (codec->codec_settings.vbr) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &codec->codec_settings.vbr); - speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &codec->codec_settings.vbr_quality); + if (context->codec_settings.vbr) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR, &context->codec_settings.vbr); + speex_encoder_ctl(context->encoder_state, SPEEX_SET_VBR_QUALITY, &context->codec_settings.vbr_quality); } - if (codec->codec_settings.abr) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &codec->codec_settings.abr); + if (context->codec_settings.abr) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_ABR, &context->codec_settings.abr); } - if (codec->codec_settings.dtx) { - speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &codec->codec_settings.dtx); + if (context->codec_settings.dtx) { + speex_encoder_ctl(context->encoder_state, SPEEX_SET_DTX, &context->codec_settings.dtx); } } if (decoding) { speex_bits_init(&context->decoder_bits); context->decoder_state = speex_decoder_init(mode); - if (codec->codec_settings.enhancement) { - speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &codec->codec_settings.enhancement); + if (context->codec_settings.enhancement) { + speex_decoder_ctl(context->decoder_state, SPEEX_SET_ENH, &context->codec_settings.enhancement); } } @@ -178,7 +270,7 @@ static switch_status_t switch_speex_encode(switch_codec_t *codec, if (is_speech) { is_speech = speex_encode_int(context->encoder_state, buf, &context->encoder_bits) - || !context->codec->codec_settings.dtx; + || !context->codec_settings.dtx; } else { speex_bits_pack(&context->encoder_bits, 0, 5); } @@ -270,6 +362,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_speex_load) /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "Speex"); + codec_interface->parse_fmtp = switch_speex_fmtp_parse; for (counta = 1; counta <= 3; counta++) { for (countb = 1; countb > 0; countb--) { switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ diff --git a/src/mod/endpoints/mod_h323/changes.txt b/src/mod/endpoints/mod_h323/changes.txt index ff47780118..19aca46dc8 100644 --- a/src/mod/endpoints/mod_h323/changes.txt +++ b/src/mod/endpoints/mod_h323/changes.txt @@ -1,3 +1,4 @@ +fix crashes on FSH323Connection calls in on_hangup routine in different threads. move PTrace level set to FSH323EndPoint::Initialise partially apply patch from from Peter Olsson, Remove UnLock() when TryLock() failed and DEBUG_RTP_PACKETS directive. apply changes from mod_h323-patch.diff by Peter Olsson. diff --git a/src/mod/endpoints/mod_h323/mod_h323.cpp b/src/mod/endpoints/mod_h323/mod_h323.cpp index aeee422ca5..142506dd92 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.cpp +++ b/src/mod/endpoints/mod_h323/mod_h323.cpp @@ -24,7 +24,7 @@ * * mod_h323.cpp -- H323 endpoint * - * Version 0.0.55 + * Version 0.0.56 */ //#define DEBUG_RTP_PACKETS @@ -747,6 +747,17 @@ FSH323Connection::~FSH323Connection() // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_unlock\n"); } +void FSH323Connection::AttachSignalChannel(const PString & token, + H323Transport * channel, + PBoolean answeringCall) +{ + h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(m_fsSession); + tech_pvt->token = strdup((const char *)token); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"---------->token = %s [%p]\n",(const char *)token,this); + H323Connection::AttachSignalChannel(token,channel,answeringCall); +} + + void FSH323Connection::OnSetLocalCapabilities() { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"======>FSH323Connection::OnSetLocalCapabilities() [%p]\n",this); @@ -2321,8 +2332,9 @@ static switch_status_t on_hangup(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); h323_private_t *tech_pvt = (h323_private_t *) switch_core_session_get_private(session); FSH323Connection *me = tech_pvt->me; + FSH323EndPoint & ep = h323_process->GetH323EndPoint(); tech_pvt->me = NULL; - + if (me) { if (me->m_rtp_resetting == 1) { switch_core_session_unlock_codec_read(session); @@ -2340,12 +2352,12 @@ static switch_status_t on_hangup(switch_core_session_t *session) me->CloseAllLogicalChannels(false); me->Unlock(); } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"----->%s\n",(const char *)(me->GetCallToken())); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"----->%s\n",(const char *)(tech_pvt->token)); Q931::CauseValues cause = (Q931::CauseValues)switch_channel_get_cause_q850(channel); int trylock = me->TryLock(); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"-----> () = %d\n",trylock); if (trylock == 1) { - const PString currentToken(me->GetCallToken()); + const PString currentToken(tech_pvt->token); FSH323Connection *connection = (FSH323Connection *)me->GetEndPoint()->FindConnectionWithLock(currentToken); if (connection) { connection->Unlock(); @@ -2356,8 +2368,10 @@ static switch_status_t on_hangup(switch_core_session_t *session) } else if (trylock == -1) { /* Failed to lock - just go on */ } + const PString currentToken(tech_pvt->token); me->SetQ931Cause(cause); - me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX)); +// me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX)); + ep.ClearCall(currentToken, H323TranslateToCallEndReason(cause, UINT_MAX)); // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"------------->h323_mutex_lock\n"); // switch_mutex_lock(tech_pvt->h323_mutex); } diff --git a/src/mod/endpoints/mod_h323/mod_h323.h b/src/mod/endpoints/mod_h323/mod_h323.h index 087540c509..8127206126 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.h +++ b/src/mod/endpoints/mod_h323/mod_h323.h @@ -184,6 +184,7 @@ typedef struct { switch_mutex_t *h323_io_mutex; FSH323Connection *me; + char *token; } h323_private_t; #define DECLARE_CALLBACK0(name) \ @@ -306,7 +307,11 @@ class FSH323Connection:public H323Connection { unsigned callReference, switch_caller_profile_t *outbound_profile, switch_core_session_t *fsSession, switch_channel_t *fsChannel); ~FSH323Connection(); - + virtual void AttachSignalChannel( + const PString & token, + H323Transport * channel, + PBoolean answeringCall + ); virtual H323Channel *CreateRealTimeLogicalChannel(const H323Capability & capability, H323Channel::Directions dir, unsigned sessionID, const H245_H2250LogicalChannelParameters * param, RTP_QOS * rtpqos = NULL); diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 8275893be8..ab4db6a1b0 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -52,7 +52,8 @@ typedef enum { TFLAG_BRIDGE = (1 << 4), TFLAG_BOWOUT = (1 << 5), TFLAG_BLEG = (1 << 6), - TFLAG_APP = (1 << 7) + TFLAG_APP = (1 << 7), + TFLAG_BOWOUT_USED = (1 << 8) } TFLAGS; struct private_object { @@ -635,7 +636,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); - if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || switch_test_flag(tech_pvt, TFLAG_BOWOUT)) { + if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { return SWITCH_STATUS_SUCCESS; } @@ -662,6 +663,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc switch_clear_flag_locked(tech_pvt, TFLAG_WRITE); switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_WRITE); + switch_set_flag_locked(tech_pvt, TFLAG_BOWOUT_USED); + switch_set_flag_locked(tech_pvt->other_tech_pvt, TFLAG_BOWOUT_USED); + if (a_uuid && b_uuid) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s detected bridge on both ends, attempting direct connection.\n", switch_channel_get_name(channel)); diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 165815078b..2df8937647 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -1343,19 +1343,6 @@ static switch_status_t kill_listener(listener_t *listener, void *pvt) return SWITCH_STATUS_SUCCESS; } -static switch_status_t kill_expired_listener(listener_t *listener, void *pvt) -{ - switch_event_t *event = NULL; - - if(listener->expire_time < switch_epoch_time_now(NULL)) { - /* skinny::expire event */ - skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE); - switch_event_fire(&event); - return kill_listener(listener, pvt); - } - return SWITCH_STATUS_SUCCESS; -} - switch_status_t keepalive_listener(listener_t *listener, void *pvt) { skinny_profile_t *profile; @@ -1414,6 +1401,13 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) case SWITCH_STATUS_TIMEOUT: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Communication Time Out with %s:%d.\n", listener->remote_ip, listener->remote_port); + + if(listener->expire_time < switch_epoch_time_now(NULL)) { + switch_event_t *event = NULL; + /* skinny::expire event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_EXPIRE); + switch_event_fire(&event); + } break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Communication Error with %s:%d.\n", @@ -1917,9 +1911,57 @@ static switch_status_t load_skinny_config(void) return SWITCH_STATUS_SUCCESS; } -static void skinny_heartbeat_event_handler(switch_event_t *event) +static void skinny_user_to_device_event_handler(switch_event_t *event) { - walk_listeners(kill_expired_listener, NULL); + char *profile_name = switch_event_get_header_nil(event, "Skinny-Profile-Name"); + skinny_profile_t *profile; + + if ((profile = skinny_find_profile(profile_name))) { + char *device_name = switch_event_get_header_nil(event, "Skinny-Device-Name"); + uint32_t device_instance = atoi(switch_event_get_header_nil(event, "Skinny-Station-Instance")); + listener_t *listener = NULL; + skinny_profile_find_listener_by_device_name_and_instance(profile, device_name, device_instance, &listener); + if(listener) { + uint32_t message_type = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id")); + uint32_t application_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Application-Id")); + uint32_t line_instance = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Line-Instance")); + uint32_t call_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Call-Id")); + uint32_t transaction_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Transaction-Id")); + uint32_t data_length = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Data-Length")); + uint32_t sequence_flag = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Sequence-Flag")); + uint32_t display_priority = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Display-Priority")); + uint32_t conference_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Conference-Id")); + uint32_t app_instance_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-App-Instance-Id")); + uint32_t routing_id = atoi(switch_event_get_header_nil(event, "Skinny-UserToDevice-Routing-Id")); + char *data = switch_event_get_body(event); + if (message_type == 0) { + message_type = skinny_str2message_type(switch_event_get_header_nil(event, "Skinny-UserToDevice-Message-Id-String")); + } + switch(message_type) { + case USER_TO_DEVICE_DATA_MESSAGE: + data_length = strlen(data); /* we ignore data_length sent */ + send_data(listener, message_type, + application_id, line_instance, call_id, transaction_id, data_length, + data); + case USER_TO_DEVICE_DATA_VERSION1_MESSAGE: + data_length = strlen(data); /* we ignore data_length sent */ + send_extended_data(listener, message_type, + application_id, line_instance, call_id, transaction_id, data_length, + sequence_flag, display_priority, conference_id, app_instance_id, routing_id, + data); + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Incorrect message type %s (%d).\n", skinny_message_type2str(message_type), message_type); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Device %s:%d in profile '%s' not found.\n", device_name, device_instance, profile_name); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Profile '%s' not found.\n", profile_name); + } } static void skinny_call_state_event_handler(switch_event_t *event) @@ -2129,10 +2171,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) return SWITCH_STATUS_TERM; } /* bind to events */ - if ((switch_event_bind_removable(modname, SWITCH_EVENT_HEARTBEAT, NULL, skinny_heartbeat_event_handler, NULL, &globals.heartbeat_node) != SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our heartbeat handler!\n"); - /* Not such severe to prevent loading */ - } if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_CALL_STATE, skinny_call_state_event_handler, NULL, &globals.call_state_node) != SWITCH_STATUS_SUCCESS)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our call_state handler!\n"); return SWITCH_STATUS_TERM; @@ -2145,6 +2183,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Couldn't bind our trap handler!\n"); /* Not such severe to prevent loading */ } + if ((switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE, skinny_user_to_device_event_handler, NULL, &globals.user_to_device_node) != SWITCH_STATUS_SUCCESS)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our user_to_device handler!\n"); + /* Not such severe to prevent loading */ + } /* reserve events */ if (switch_event_reserve_subclass(SKINNY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) { @@ -2167,6 +2209,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_CALL_STATE); return SWITCH_STATUS_TERM; } + if (switch_event_reserve_subclass(SKINNY_EVENT_USER_TO_DEVICE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_USER_TO_DEVICE); + return SWITCH_STATUS_TERM; + } + if (switch_event_reserve_subclass(SKINNY_EVENT_DEVICE_TO_USER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SKINNY_EVENT_DEVICE_TO_USER); + return SWITCH_STATUS_TERM; + } /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(globals.pool, modname); @@ -2205,7 +2255,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown) skinny_api_unregister(); /* release events */ - switch_event_unbind(&globals.heartbeat_node); + switch_event_unbind(&globals.user_to_device_node); switch_event_unbind(&globals.call_state_node); switch_event_unbind(&globals.message_waiting_node); switch_event_unbind(&globals.trap_node); @@ -2214,6 +2264,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skinny_shutdown) switch_event_free_subclass(SKINNY_EVENT_EXPIRE); switch_event_free_subclass(SKINNY_EVENT_ALARM); switch_event_free_subclass(SKINNY_EVENT_CALL_STATE); + switch_event_free_subclass(SKINNY_EVENT_USER_TO_DEVICE); + switch_event_free_subclass(SKINNY_EVENT_DEVICE_TO_USER); switch_mutex_lock(mutex); diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index bbd318b746..b5cc96b7ae 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -43,13 +43,15 @@ #define SKINNY_EVENT_EXPIRE "skinny::expire" #define SKINNY_EVENT_ALARM "skinny::alarm" #define SKINNY_EVENT_CALL_STATE "skinny::call_state" +#define SKINNY_EVENT_USER_TO_DEVICE "skinny::user_to_device" +#define SKINNY_EVENT_DEVICE_TO_USER "skinny::device_to_user" struct skinny_globals { int running; switch_memory_pool_t *pool; switch_mutex_t *mutex; switch_hash_t *profile_hash; - switch_event_node_t *heartbeat_node; + switch_event_node_t *user_to_device_node; switch_event_node_t *call_state_node; switch_event_node_t *message_waiting_node; switch_event_node_t *trap_node; diff --git a/src/mod/endpoints/mod_skinny/skinny_api.c b/src/mod/endpoints/mod_skinny/skinny_api.c index 90699d1ad2..7bbb27afd3 100644 --- a/src/mod/endpoints/mod_skinny/skinny_api.c +++ b/src/mod/endpoints/mod_skinny/skinny_api.c @@ -366,6 +366,62 @@ static switch_status_t skinny_api_cmd_profile_device_send_reset_message(const ch return SWITCH_STATUS_SUCCESS; } +static switch_status_t skinny_api_cmd_profile_device_send_data(const char *profile_name, const char *device_name, const char *message_type, char *params, const char *body, switch_stream_handle_t *stream) +{ + skinny_profile_t *profile; + + if ((profile = skinny_find_profile(profile_name))) { + listener_t *listener = NULL; + skinny_profile_find_listener_by_device_name(profile, device_name, &listener); + if(listener) { + switch_event_t *event = NULL; + char *argv[64] = { 0 }; + int argc = 0; + int x = 0; + /* skinny::user_to_device event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_USER_TO_DEVICE); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Message-Id-String", "%s", message_type); + argc = switch_separate_string(params, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *var_name, *var_value = NULL; + var_name = argv[x]; + if (var_name && (var_value = strchr(var_name, '='))) { + *var_value++ = '\0'; + } + if (zstr(var_name)) { + stream->write_function(stream, "-ERR No variable specified\n"); + } else { + char *tmp = switch_mprintf("Skinny-UserToDevice-%s", var_name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, tmp, "%s", var_value); + switch_safe_free(tmp); + /* + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Application-Id", "%d", request->data.extended_data.application_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Line-Instance", "%d", request->data.extended_data.line_instance); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Call-Id", "%d", request->data.extended_data.call_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Transaction-Id", "%d", request->data.extended_data.transaction_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Data-Length", "%d", request->data.extended_data.data_length); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Sequence-Flag", "%d", request->data.extended_data.sequence_flag); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Display-Priority", "%d", request->data.extended_data.display_priority); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Conference-Id", "%d", request->data.extended_data.conference_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-App-Instance-Id", "%d", request->data.extended_data.app_instance_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-UserToDevice-Routing-Id", "%d", request->data.extended_data.routing_id); + */ + } + } + switch_event_add_body(event, "%s", body); + switch_event_fire(&event); + stream->write_function(stream, "+OK\n"); + } else { + stream->write_function(stream, "Listener not found!\n"); + } + } else { + stream->write_function(stream, "Profile not found!\n"); + } + + return SWITCH_STATUS_SUCCESS; +} + + static switch_status_t skinny_api_cmd_profile_set(const char *profile_name, const char *name, const char *value, switch_stream_handle_t *stream) { skinny_profile_t *profile; @@ -403,6 +459,7 @@ SWITCH_STANDARD_API(skinny_function) "skinny profile <profile_name> device <device_name> send SetLampMessage <stimulus> <instance> <lamp_mode>\n" "skinny profile <profile_name> device <device_name> send SetSpeakerModeMessage <speaker_mode>\n" "skinny profile <profile_name> device <device_name> send CallStateMessage <call_state> <line_instance> <call_id>\n" + "skinny profile <profile_name> device <device_name> send <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data>\n" "skinny profile <profile_name> set <name> <value>\n" "--------------------------------------------------------------------------------\n"; if (session) { @@ -465,6 +522,16 @@ SWITCH_STANDARD_API(skinny_function) status = skinny_api_cmd_profile_device_send_reset_message(argv[1], argv[3], argv[6], stream); } break; + case USER_TO_DEVICE_DATA_MESSAGE: + case USER_TO_DEVICE_DATA_VERSION1_MESSAGE: + if(argc == 8) { + /* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> [ <param>=<value>;... ] <data> */ + status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], argv[6], argv[7], stream); + } else if(argc == 7) { + /* <UserToDeviceDataMessage|UserToDeviceDataVersion1Message> <data> */ + status = skinny_api_cmd_profile_device_send_data(argv[1], argv[3], argv[5], "", argv[6], stream); + } + break; default: stream->write_function(stream, "Unhandled message %s\n", argv[5]); } @@ -495,6 +562,8 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_ switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetLampMessage ::skinny::list_stimuli ::skinny::list_stimulus_instances ::skinny::list_stimulus_modes"); switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send SetSpeakerModeMessage ::skinny::list_speaker_modes"); switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send CallStateMessage ::skinny::list_call_states ::skinny::list_line_instances ::skinny::list_call_ids"); + switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataMessage"); + switch_console_set_complete("add skinny profile ::skinny::list_profiles device ::skinny::list_devices send UserToDeviceDataVersion1Message"); switch_console_set_complete("add skinny profile ::skinny::list_profiles set ::skinny::list_settings"); switch_console_add_complete_func("::skinny::list_profiles", skinny_api_list_profiles); diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 1aea812574..743514d98c 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -135,6 +135,10 @@ switch_status_t skinny_read_packet(listener_t *listener, skinny_message_t **req) status = switch_socket_recv(listener->sock, ptr, &mlen); + if (listener->expire_time && listener->expire_time < switch_epoch_time_now(NULL)) { + return SWITCH_STATUS_TIMEOUT; + } + if (!listener_is_ready(listener)) { break; } @@ -898,6 +902,68 @@ switch_status_t send_reset(listener_t *listener, uint32_t reset_type) return skinny_send_reply(listener, message); } +switch_status_t send_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + const char *data) +{ + skinny_message_t *message; + switch_assert(data_length == strlen(data)); + /* data_length should be a multiple of 4 */ + if ((data_length % 4) != 0) { + data_length = (data_length / 4 + 1) * 4; + } + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.data)+data_length-1); + message->type = message_type; + message->length = 4 + sizeof(message->data.data)+data_length-1; + message->data.data.application_id = application_id; + message->data.data.line_instance = line_instance; + message->data.data.call_id = call_id; + message->data.data.transaction_id = transaction_id; + message->data.data.data_length = data_length; + strncpy(message->data.data.data, data, data_length); + return skinny_send_reply(listener, message); +} + +switch_status_t send_extended_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + uint32_t sequence_flag, + uint32_t display_priority, + uint32_t conference_id, + uint32_t app_instance_id, + uint32_t routing_id, + const char *data) +{ + skinny_message_t *message; + switch_assert(data_length == strlen(data)); + /* data_length should be a multiple of 4 */ + if ((data_length % 4) != 0) { + data_length = (data_length / 4 + 1) * 4; + } + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.extended_data)+data_length-1); + message->type = message_type; + message->length = 4 + sizeof(message->data.extended_data)+data_length-1; + message->data.extended_data.application_id = application_id; + message->data.extended_data.line_instance = line_instance; + message->data.extended_data.call_id = call_id; + message->data.extended_data.transaction_id = transaction_id; + message->data.extended_data.data_length = data_length; + message->data.extended_data.sequence_flag = sequence_flag; + message->data.extended_data.display_priority = display_priority; + message->data.extended_data.conference_id = conference_id; + message->data.extended_data.app_instance_id = app_instance_id; + message->data.extended_data.routing_id = routing_id; + strncpy(message->data.extended_data.data, data, data_length); + return skinny_send_reply(listener, message); +} + switch_status_t skinny_perform_send_reply(listener_t *listener, const char *file, const char *func, int line, skinny_message_t *reply) { char *ptr; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 236c667509..d85a190ba8 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -174,6 +174,21 @@ struct PACKED register_available_lines_message { uint32_t count; }; +/* DeviceToUserDataMessage */ +#define DEVICE_TO_USER_DATA_MESSAGE 0x002E +struct PACKED data_message { + uint32_t application_id; + uint32_t line_instance; + uint32_t call_id; + uint32_t transaction_id; + uint32_t data_length; + char data[1]; +}; + +/* DeviceToUserDataResponseMessage */ +#define DEVICE_TO_USER_DATA_RESPONSE_MESSAGE 0x002F +/* See struct PACKED data_message */ + /* ServiceUrlStatReqMessage */ #define SERVICE_URL_STAT_REQ_MESSAGE 0x0033 struct PACKED service_url_stat_req_message { @@ -186,6 +201,26 @@ struct PACKED feature_stat_req_message { uint32_t feature_index; }; +/* DeviceToUserDataVersion1Message */ +#define DEVICE_TO_USER_DATA_VERSION1_MESSAGE 0x0041 +struct PACKED extended_data_message { + uint32_t application_id; + uint32_t line_instance; + uint32_t call_id; + uint32_t transaction_id; + uint32_t data_length; + uint32_t sequence_flag; + uint32_t display_priority; + uint32_t conference_id; + uint32_t app_instance_id; + uint32_t routing_id; + char data[1]; +}; + +/* DeviceToUserDataResponseVersion1Message */ +#define DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE 0x0042 +/* See struct PACKED extended_data_message */ + /* RegisterAckMessage */ #define REGISTER_ACK_MESSAGE 0x0081 struct PACKED register_ack_message { @@ -479,6 +514,10 @@ struct PACKED dialed_number_message { uint32_t call_id; }; +/* UserToDeviceDataMessage */ +#define USER_TO_DEVICE_DATA_MESSAGE 0x011E +/* See struct PACKED data_message */ + /* FeatureStatMessage */ #define FEATURE_STAT_RES_MESSAGE 0x011F struct PACKED feature_stat_res_message { @@ -504,6 +543,10 @@ struct PACKED service_url_stat_res_message { char display_name[40]; }; +/* UserToDeviceDataVersion1Message */ +#define USER_TO_DEVICE_DATA_VERSION1_MESSAGE 0x013F +/* See struct PACKED extended_data_message */ + /*****************************************************************************/ /* SKINNY MESSAGE */ /*****************************************************************************/ @@ -512,6 +555,7 @@ struct PACKED service_url_stat_res_message { #define SKINNY_MESSAGE_MAXSIZE 1000 union skinny_data { + /* no data for KEEP_ALIVE_MESSAGE */ struct register_message reg; struct port_message port; struct keypad_button_message keypad_button; @@ -520,14 +564,25 @@ union skinny_data { struct on_hook_message on_hook; struct speed_dial_stat_req_message speed_dial_req; struct line_stat_req_message line_req; + /* no data for CONFIG_STAT_REQ_MESSAGE */ + /* no data for TIME_DATE_REQ_MESSAGE */ + /* no data for BUTTON_TEMPLATE_REQ_MESSAGE */ + /* no data for VERSION_REQ_MESSAGE */ struct capabilities_res_message cap_res; struct alarm_message alarm; struct open_receive_channel_ack_message open_receive_channel_ack; + /* no data for SOFT_KEY_SET_REQ_MESSAGE */ struct soft_key_event_message soft_key_event; - struct service_url_stat_req_message service_url_req; - struct feature_stat_req_message feature_req; + /* no data for UNREGISTER_MESSAGE */ + /* no data for SOFT_KEY_TEMPLATE_REQ_MESSAGE */ struct headset_status_message headset_status; struct register_available_lines_message reg_lines; + /* see field "data" for DEVICE_TO_USER_DATA_MESSAGE */ + /* see field "data" for DEVICE_TO_USER_DATA_RESPONSE_MESSAGE */ + struct service_url_stat_req_message service_url_req; + struct feature_stat_req_message feature_req; + /* see field "extended_data" for DEVICE_TO_USER_DATA_VERSION1_MESSAGE */ + /* see field "extended_data" for DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE */ struct register_ack_message reg_ack; struct start_tone_message start_tone; struct stop_tone_message stop_tone; @@ -543,8 +598,10 @@ union skinny_data { struct define_time_date_message define_time_date; struct button_template_message button_template; struct version_message version; + /* no data for CAPABILITIES_REQ_MESSAGE */ struct register_reject_message reg_rej; struct reset_message reset; + /* no data for KEEP_ALIVE_ACK_MESSAGE */ struct open_receive_channel_message open_receive_channel; struct close_receive_channel_message close_receive_channel; struct soft_key_template_res_message soft_key_template; @@ -557,9 +614,14 @@ union skinny_data { struct unregister_ack_message unregister_ack; struct back_space_req_message back_space_req; struct dialed_number_message dialed_number; + /* see field "data" for USER_TO_DEVICE_DATA_MESSAGE */ struct feature_stat_res_message feature_res; struct display_pri_notify_message display_pri_notify; struct service_url_stat_res_message service_url_res; + /* see field "extended_data" for USER_TO_DEVICE_DATA_VERSION1_MESSAGE */ + + struct data_message data; + struct extended_data_message extended_data; uint16_t as_uint16; char as_char; @@ -777,6 +839,27 @@ switch_status_t send_display_pri_notify(listener_t *listener, switch_status_t send_reset(listener_t *listener, uint32_t reset_type); +switch_status_t send_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + const char *data); + +switch_status_t send_extended_data(listener_t *listener, uint32_t message_type, + uint32_t application_id, + uint32_t line_instance, + uint32_t call_id, + uint32_t transaction_id, + uint32_t data_length, + uint32_t sequence_flag, + uint32_t display_priority, + uint32_t conference_id, + uint32_t app_instance_id, + uint32_t routing_id, + const char *data); + #endif /* _SKINNY_PROTOCOL_H */ /* For Emacs: diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 3fa4aab6c4..cfafea6f01 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1864,6 +1864,33 @@ switch_status_t skinny_handle_register_available_lines_message(listener_t *liste return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_data_message(listener_t *listener, skinny_message_t *request) +{ + switch_event_t *event = NULL; + char *tmp = NULL; + skinny_check_data_length(request, sizeof(request->data.data)); + skinny_check_data_length(request, sizeof(request->data.data) + request->data.data.data_length - 1); + + /* skinny::device_to_user event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.data.application_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.data.line_instance); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.data.call_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.data.transaction_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.data.data_length); + /* Ensure that the body is null-terminated */ + tmp = malloc(request->data.data.data_length + 1); + memcpy(tmp, request->data.data.data, request->data.data.data_length); + tmp[request->data.data.data_length] = '\0'; + switch_event_add_body(event, "%s", tmp); + switch_safe_free(tmp); + switch_event_fire(&event); + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request) { skinny_message_t *message; @@ -1904,6 +1931,38 @@ switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_ return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_extended_data_message(listener_t *listener, skinny_message_t *request) +{ + switch_event_t *event = NULL; + char *tmp = NULL; + skinny_check_data_length(request, sizeof(request->data.extended_data)); + skinny_check_data_length(request, sizeof(request->data.extended_data)+request->data.extended_data.data_length-1); + + /* skinny::device_to_user event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_DEVICE_TO_USER); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id", "%d", request->type); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Message-Id-String", "%s", skinny_message_type2str(request->type)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Application-Id", "%d", request->data.extended_data.application_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Line-Instance", "%d", request->data.extended_data.line_instance); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Call-Id", "%d", request->data.extended_data.call_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Transaction-Id", "%d", request->data.extended_data.transaction_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Data-Length", "%d", request->data.extended_data.data_length); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Sequence-Flag", "%d", request->data.extended_data.sequence_flag); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Display-Priority", "%d", request->data.extended_data.display_priority); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Conference-Id", "%d", request->data.extended_data.conference_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-App-Instance-Id", "%d", request->data.extended_data.app_instance_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-DeviceToUser-Routing-Id", "%d", request->data.extended_data.routing_id); + /* Ensure that the body is null-terminated */ + tmp = malloc(request->data.data.data_length + 1); + memcpy(tmp, request->data.data.data, request->data.data.data_length); + tmp[request->data.data.data_length] = '\0'; + switch_event_add_body(event, "%s", tmp); + switch_safe_free(tmp); + switch_event_fire(&event); + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request) { if (listener->profile->debug >= 10 || request->type != KEEP_ALIVE_MESSAGE) { @@ -1961,10 +2020,18 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_headset_status_message(listener, request); case REGISTER_AVAILABLE_LINES_MESSAGE: return skinny_handle_register_available_lines_message(listener, request); + case DEVICE_TO_USER_DATA_MESSAGE: + return skinny_handle_data_message(listener, request); + case DEVICE_TO_USER_DATA_RESPONSE_MESSAGE: + return skinny_handle_data_message(listener, request); case SERVICE_URL_STAT_REQ_MESSAGE: return skinny_handle_service_url_stat_request(listener, request); case FEATURE_STAT_REQ_MESSAGE: return skinny_handle_feature_stat_request(listener, request); + case DEVICE_TO_USER_DATA_VERSION1_MESSAGE: + return skinny_handle_extended_data_message(listener, request); + case DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE: + return skinny_handle_extended_data_message(listener, request); default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 43b2290560..0a27ad76c4 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -55,10 +55,14 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"SoftKeyEventMessage", SOFT_KEY_EVENT_MESSAGE}, {"UnregisterMessage", UNREGISTER_MESSAGE}, {"SoftKeyTemplateReqMessage", SOFT_KEY_TEMPLATE_REQ_MESSAGE}, - {"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE}, - {"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE}, {"HeadsetStatusMessage", HEADSET_STATUS_MESSAGE}, {"RegisterAvailableLinesMessage", REGISTER_AVAILABLE_LINES_MESSAGE}, + {"DeviceToUserDataMessage", DEVICE_TO_USER_DATA_MESSAGE}, + {"DeviceToUserDataResponseMessage", DEVICE_TO_USER_DATA_RESPONSE_MESSAGE}, + {"ServiceUrlStatReqMessage", SERVICE_URL_STAT_REQ_MESSAGE}, + {"FeatureStatReqMessage", FEATURE_STAT_REQ_MESSAGE}, + {"DeviceToUserDataVersion1Message", DEVICE_TO_USER_DATA_VERSION1_MESSAGE}, + {"DeviceToUserDataResponseVersion1Message", DEVICE_TO_USER_DATA_RESPONSE_VERSION1_MESSAGE}, {"RegisterAckMessage", REGISTER_ACK_MESSAGE}, {"StartToneMessage", START_TONE_MESSAGE}, {"StopToneMessage", STOP_TONE_MESSAGE}, @@ -90,9 +94,11 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"UnregisterAckMessage", UNREGISTER_ACK_MESSAGE}, {"BackSpaceReqMessage", BACK_SPACE_REQ_MESSAGE}, {"DialedNumberMessage", DIALED_NUMBER_MESSAGE}, + {"UserToDeviceDataMessage", USER_TO_DEVICE_DATA_MESSAGE}, {"FeatureResMessage", FEATURE_STAT_RES_MESSAGE}, {"DisplayPriNotifyMessage", DISPLAY_PRI_NOTIFY_MESSAGE}, {"ServiceUrlStatMessage", SERVICE_URL_STAT_RES_MESSAGE}, + {"UserToDeviceDataVersion1Message", USER_TO_DEVICE_DATA_VERSION1_MESSAGE}, {NULL, 0} }; SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage") diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 1747360264..14962b8b78 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -87,7 +87,7 @@ uint32_t func(const char *str)\ } -extern struct skinny_table SKINNY_MESSAGE_TYPES[59]; +extern struct skinny_table SKINNY_MESSAGE_TYPES[65]; const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 19a44f43e1..7e92decfb1 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -85,6 +85,10 @@ static switch_status_t sofia_on_init(switch_core_session_t *session) sofia_glue_tech_absorb_sdp(tech_pvt); } + if (sofia_test_flag(tech_pvt, TFLAG_RECOVERING) || sofia_test_flag(tech_pvt, TFLAG_RECOVERING_BRIDGE)) { + sofia_set_flag(tech_pvt, TFLAG_RECOVERED); + } + if (sofia_test_flag(tech_pvt, TFLAG_OUTBOUND) || sofia_test_flag(tech_pvt, TFLAG_RECOVERING)) { const char *var; @@ -717,6 +721,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)), TAG_IF(cid, SIPTAG_HEADER_STR(cid)), NUTAG_SESSION_TIMER(session_timeout), + TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), @@ -732,6 +737,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)), TAG_IF(cid, SIPTAG_HEADER_STR(cid)), NUTAG_SESSION_TIMER(session_timeout), + TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")), SIPTAG_CONTENT_TYPE_STR("application/sdp"), @@ -1232,7 +1238,12 @@ static void start_udptl(private_object_t *tech_pvt, switch_t38_options_t *t38_op switch_rtp_udptl_mode(tech_pvt->rtp_session); - if (remote_host && remote_port && !strcmp(remote_host, t38_options->remote_ip) && remote_port == t38_options->remote_port) { + if (!t38_options || !t38_options->remote_ip) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "No remote address\n"); + return; + } + + if (remote_host && remote_port && remote_port == t38_options->remote_port && !strcmp(remote_host, t38_options->remote_ip)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n", t38_options->remote_ip, t38_options->remote_port); return; @@ -1471,12 +1482,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: { - const char *pl = - "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" - " <media_control>\r\n" - " <vc_primitive>\r\n" - " <to_encoder>\r\n" - " <picture_fast_update>\r\n" " </picture_fast_update>\r\n" " </to_encoder>\r\n" " </vc_primitive>\r\n" " </media_control>\r\n"; + const char *pl = "<media_control><vc_primitive><to_encoder><picture_fast_update/></to_encoder></vc_primitive></media_control>"; + + if (!zstr(msg->string_arg)) { + pl = msg->string_arg; + } nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); @@ -1765,7 +1775,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi nua_update(tech_pvt->nh, TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); - } else if ((ua && (switch_stristr("cisco", ua)))) { + } else if (0 && (ua && (switch_stristr("cisco", ua)))) { snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <sip:%s@%s>", name, number, tech_pvt->profile->sipip); sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY); @@ -2005,6 +2015,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options"); if (t38_options) { sofia_glue_set_image_sdp(tech_pvt, t38_options, 0); + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_udptl_mode(tech_pvt->rtp_session); + } } } else { sofia_glue_tech_set_local_sdp(tech_pvt, sdp, SWITCH_TRUE); @@ -2090,6 +2103,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; case SWITCH_MESSAGE_INDICATE_ANSWER: status = sofia_answer_channel(session); + if (switch_channel_test_flag(tech_pvt->channel, CF_VIDEO)) { + sofia_glue_build_vid_refresh_message(session, NULL); + } break; case SWITCH_MESSAGE_INDICATE_PROGRESS: { @@ -2315,7 +2331,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam switch_time_t etime = atoi(argv[6]); switch_size_t retsize; - exp_secs = etime - now; + exp_secs = (int)(etime - now); switch_time_exp_lt(&tm, switch_time_from_sec(etime)); switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm); } @@ -2355,7 +2371,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum switch_time_t etime = atoi(argv[6]); switch_size_t retsize; - exp_secs = etime - now; + exp_secs = (int)(etime - now); switch_time_exp_lt(&tm, switch_time_from_sec(etime)); switch_strftime_nocheck(exp_buf, &retsize, sizeof(exp_buf), "%Y-%m-%d %T", &tm); } @@ -2422,7 +2438,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t ob_failed += gp->ob_failed_calls; ob += gp->ob_calls; - stream->write_function(stream, "%25s\t%32s\t%s\t%ld/%ld\t%ld/%ld", + stream->write_function(stream, "%25s\t%32s\t%s\t%u/%u\t%u/%u", pkey, gp->register_to, sofia_state_names[gp->state], gp->ib_failed_calls, gp->ib_calls, gp->ob_failed_calls, gp->ob_calls); @@ -2441,8 +2457,8 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t } switch_mutex_unlock(mod_sofia_globals.hash_mutex); stream->write_function(stream, "%s\n", line); - stream->write_function(stream, "%d gateway%s: Inound(Failed/Total): %ld/%ld," - "Outbound(Failed/Total):%ld/%ld\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob); + stream->write_function(stream, "%d gateway%s: Inbound(Failed/Total): %u/%u," + "Outbound(Failed/Total):%u/%u\n", c, c == 1 ? "" : "s", ib_failed, ib, ob_failed, ob); return SWITCH_STATUS_SUCCESS; } @@ -2471,10 +2487,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t stream->write_function(stream, "PingState\t%d/%d/%d\n", gp->ping_min, gp->ping_count, gp->ping_max); stream->write_function(stream, "State \t%s\n", sofia_state_names[gp->state]); stream->write_function(stream, "Status \t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); - stream->write_function(stream, "CallsIN \t%d\n", gp->ib_calls); - stream->write_function(stream, "CallsOUT\t%d\n", gp->ob_calls); - stream->write_function(stream, "FailedCallsIN\t%d\n", gp->ib_failed_calls); - stream->write_function(stream, "FailedCallsOUT\t%d\n", gp->ob_failed_calls); + stream->write_function(stream, "CallsIN \t%u\n", gp->ib_calls); + stream->write_function(stream, "CallsOUT\t%u\n", gp->ob_calls); + stream->write_function(stream, "FailedCallsIN\t%u\n", gp->ib_failed_calls); + stream->write_function(stream, "FailedCallsOUT\t%u\n", gp->ob_failed_calls); stream->write_function(stream, "%s\n", line); sofia_reg_release_gateway(gp); } else { @@ -2483,7 +2499,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t } else if (!strcasecmp(argv[0], "profile")) { struct cb_helper cb; char *sql = NULL; - int x = 0; + uint32_t x = 0; cb.row_process = 0; @@ -2548,10 +2564,10 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t if (profile->max_registrations_perext > 0) { stream->write_function(stream, "MAX-REG-PEREXT \t%d\n", profile->max_registrations_perext); } - stream->write_function(stream, "CALLS-IN \t%d\n", profile->ib_calls); - stream->write_function(stream, "FAILED-CALLS-IN \t%d\n", profile->ib_failed_calls); - stream->write_function(stream, "CALLS-OUT \t%d\n", profile->ob_calls); - stream->write_function(stream, "FAILED-CALLS-OUT \t%d\n", profile->ob_failed_calls); + stream->write_function(stream, "CALLS-IN \t%u\n", profile->ib_calls); + stream->write_function(stream, "FAILED-CALLS-IN \t%u\n", profile->ib_failed_calls); + stream->write_function(stream, "CALLS-OUT \t%u\n", profile->ob_calls); + stream->write_function(stream, "FAILED-CALLS-OUT \t%u\n", profile->ob_failed_calls); } stream->write_function(stream, "\nRegistrations:\n%s\n", line); @@ -2697,10 +2713,10 @@ static void xml_gateway_status(sofia_gateway_t *gp, switch_stream_handle_t *stre stream->write_function(stream, " <pingfreq>%d</pingfreq>\n", gp->ping_freq); stream->write_function(stream, " <state>%s</state>\n", sofia_state_names[gp->state]); stream->write_function(stream, " <status>%s%s</status>\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); - stream->write_function(stream, " <calls-in>%d</calls-in>\n", gp->ib_calls); - stream->write_function(stream, " <calls-out>%d</calls-out>\n", gp->ob_calls); - stream->write_function(stream, " <failed-calls-in>%d</failed-calls-in>\n", gp->ib_failed_calls); - stream->write_function(stream, " <failed-calls-out>%d</failed-calls-out>\n", gp->ob_failed_calls); + stream->write_function(stream, " <calls-in>%u</calls-in>\n", gp->ib_calls); + stream->write_function(stream, " <calls-out>%u</calls-out>\n", gp->ob_calls); + stream->write_function(stream, " <failed-calls-in>%u</failed-calls-in>\n", gp->ib_failed_calls); + stream->write_function(stream, " <failed-calls-out>%u</failed-calls-out>\n", gp->ob_failed_calls); if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) { time_t now = switch_epoch_time_now(NULL); @@ -2763,7 +2779,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl } else if (!strcasecmp(argv[0], "profile")) { struct cb_helper cb; char *sql = NULL; - int x = 0; + uint32_t x = 0; cb.row_process = 0; @@ -2819,10 +2835,10 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl stream->write_function(stream, " <user-agent-filter>%s</user-agent-filter>\n", switch_str_nil(profile->user_agent_filter)); stream->write_function(stream, " <max-registrations-per-extension>%d</max-registrations-per-extension>\n", profile->max_registrations_perext); - stream->write_function(stream, " <calls-in>%d</calls-in>\n", profile->ib_calls); - stream->write_function(stream, " <calls-out>%d</calls-out>\n", profile->ob_calls); - stream->write_function(stream, " <failed-calls-in>%d</failed-calls-in>\n", profile->ib_failed_calls); - stream->write_function(stream, " <failed-calls-out>%d</failed-calls-out>\n", profile->ob_failed_calls); + stream->write_function(stream, " <calls-in>%u</calls-in>\n", profile->ib_calls); + stream->write_function(stream, " <calls-out>%u</calls-out>\n", profile->ob_calls); + stream->write_function(stream, " <failed-calls-in>%u</failed-calls-in>\n", profile->ib_failed_calls); + stream->write_function(stream, " <failed-calls-out>%u</failed-calls-out>\n", profile->ob_failed_calls); stream->write_function(stream, " </profile-info>\n"); } stream->write_function(stream, " <registrations>\n"); @@ -2951,7 +2967,6 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t sofia_profile_t *profile = NULL; char *profile_name = argv[0]; const char *err; - switch_xml_t xml_root; if (argc < 2) { stream->write_function(stream, "Invalid Args!\n"); @@ -2959,12 +2974,10 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t } if (!strcasecmp(argv[1], "start")) { - if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) { - if ((xml_root = switch_xml_open_root(1, &err))) { - switch_xml_free(xml_root); - } - stream->write_function(stream, "Reload XML [%s]\n", err); - } + + switch_xml_reload(&err); + stream->write_function(stream, "Reload XML [%s]\n", err); + if (config_sofia(1, argv[0]) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "%s started successfully\n", argv[0]); } else { @@ -3039,12 +3052,8 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t if (!strcasecmp(argv[1], "rescan")) { - if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) { - if ((xml_root = switch_xml_open_root(1, &err))) { - switch_xml_free(xml_root); - } - stream->write_function(stream, "Reload XML [%s]\n", err); - } + switch_xml_reload(&err); + stream->write_function(stream, "Reload XML [%s]\n", err); if (reconfig_sofia(profile) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "+OK scan complete\n"); @@ -3141,12 +3150,8 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t profile->name, rsec, remain, remain == 1 ? "" : "s"); } else { - if (argc > 2 && !strcasecmp(argv[2], "reloadxml")) { - if ((xml_root = switch_xml_open_root(1, &err))) { - switch_xml_free(xml_root); - } - stream->write_function(stream, "Reload XML [%s]\n", err); - } + switch_xml_reload(&err); + stream->write_function(stream, "Reload XML [%s]\n", err); if (!strcasecmp(argv[1], "stop")) { sofia_clear_pflag_locked(profile, PFLAG_RUNNING); @@ -3171,6 +3176,21 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t goto done; } + + if (!strcasecmp(argv[1], "gwlist")) { + int up = 1; + + if (argc > 2) { + if (!strcasecmp(argv[2], "down")) { + up = 0; + } + } + + sofia_glue_gateway_list(profile, stream, up); + goto done; + } + + stream->write_function(stream, "-ERR Unknown command!\n"); done: @@ -3487,7 +3507,7 @@ SWITCH_STANDARD_API(sofia_function) const char *usage_string = "USAGE:\n" "--------------------------------------------------------------------------------\n" "sofia help\n" - "sofia profile <profile_name> [[start|stop|restart|rescan] [reloadxml]|" + "sofia profile <profile_name> [[start|stop|restart|rescan]|" "flush_inbound_reg [<call_id>] [reboot]|" "[register|unregister] [<gateway name>|all]|" "killgw <gateway name>|" @@ -3497,6 +3517,7 @@ SWITCH_STANDARD_API(sofia_function) "sofia status|xmlstatus gateway <name>\n" "sofia loglevel <all|default|tport|iptsec|nea|nta|nth_client|nth_server|nua|soa|sresolv|stun> [0-9]\n" "sofia tracelevel <console|alert|crit|err|warning|notice|info|debug>\n" + "sofa global siptrace [on|off]\n" "--------------------------------------------------------------------------------\n"; if (session) { @@ -3552,6 +3573,26 @@ SWITCH_STANDARD_API(sofia_function) } else if (!strcasecmp(argv[0], "help")) { stream->write_function(stream, "%s", usage_string); goto done; + } else if (!strcasecmp(argv[0], "global")) { + int on = -1; + + if (argc > 1) { + if (!strcasecmp(argv[1], "siptrace")) { + if (argc > 2) { + on = switch_true(argv[2]); + } + } + } + + if (on != -1) { + sofia_glue_global_siptrace(on); + stream->write_function(stream, "+OK Global siptrace %s", on ? "on" : "off"); + } else { + stream->write_function(stream, "-ERR Usage: siptrace on|off"); + } + + goto done; + } else if (!strcasecmp(argv[0], "recover")) { if (argv[1] && !strcasecmp(argv[1], "flush")) { sofia_glue_recover(SWITCH_TRUE); @@ -4353,7 +4394,8 @@ static void general_event_handler(switch_event_t *event) switch_mutex_lock(mod_sofia_globals.hash_mutex); if (mod_sofia_globals.profile_hash) { for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { - int rb = 0, x = 0; + int rb = 0; + uint32_t x = 0; switch_hash_this(hi, &var, NULL, &val); if ((profile = (sofia_profile_t *) val) && profile->auto_restart) { if (!strcmp(profile->sipip, old_ip4)) { @@ -4623,15 +4665,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_console_set_complete("add sofia help"); switch_console_set_complete("add sofia status"); switch_console_set_complete("add sofia xmlstatus"); - switch_console_set_complete("add sofia loglevel"); - switch_console_set_complete("add sofia tracelevel"); + + switch_console_set_complete("add sofia loglevel ::[all:default:tport:iptsec:nea:nta:nth_client:nth_server:nua:soa:sresolv:stun ::[0:1:2:3:4:5:6:7:8:9"); + switch_console_set_complete("add sofia tracelevel ::[console:alert:crit:err:warning:notice:info:debug"); + + switch_console_set_complete("add sofia global siptrace ::[on:off"); + switch_console_set_complete("add sofia profile"); switch_console_set_complete("add sofia profile restart all"); - switch_console_set_complete("add sofia profile ::sofia::list_profiles start reloadxml"); - switch_console_set_complete("add sofia profile ::sofia::list_profiles stop reloadxml"); - switch_console_set_complete("add sofia profile ::sofia::list_profiles rescan reloadxml"); - switch_console_set_complete("add sofia profile ::sofia::list_profiles restart reloadxml"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles start"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles stop"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles rescan"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles restart"); switch_console_set_complete("add sofia profile ::sofia::list_profiles flush_inbound_reg"); switch_console_set_complete("add sofia profile ::sofia::list_profiles register ::sofia::list_profile_gateway"); @@ -4640,6 +4686,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_console_set_complete("add sofia profile ::sofia::list_profiles siptrace on"); switch_console_set_complete("add sofia profile ::sofia::list_profiles siptrace off"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles gwlist up"); + switch_console_set_complete("add sofia profile ::sofia::list_profiles gwlist down"); + switch_console_set_complete("add sofia status profile ::sofia::list_profiles"); switch_console_set_complete("add sofia status profile ::sofia::list_profiles reg"); switch_console_set_complete("add sofia status gateway ::sofia::list_gateways"); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index aa2149503a..5674046074 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -106,6 +106,7 @@ typedef struct private_object private_object_t; #define SOFIA_CRYPTO_MANDATORY_VARIABLE "sip_crypto_mandatory" #define FREESWITCH_SUPPORT "update_display" +#include <switch_stun.h> #include <sofia-sip/nua.h> #include <sofia-sip/sip_status.h> #include <sofia-sip/sdp.h> @@ -199,6 +200,7 @@ typedef enum { PFLAG_DISABLE_NAPTR, PFLAG_AUTOFLUSH, PFLAG_NAT_OPTIONS_PING, + PFLAG_ALL_REG_OPTIONS_PING, PFLAG_AUTOFIX_TIMING, PFLAG_MESSAGE_QUERY_ON_REGISTER, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER, @@ -218,6 +220,7 @@ typedef enum { PFLAG_T38_PASSTHRU, PFLAG_CID_IN_1XX, PFLAG_IN_DIALOG_CHAT, + PFLAG_DEL_SUBS_ON_REG, /* No new flags below this line */ PFLAG_MAX } PFLAGS; @@ -275,6 +278,7 @@ typedef enum { TFLAG_RECOVERING, TFLAG_RECOVERING_BRIDGE, TFLAG_T38_PASSTHRU, + TFLAG_RECOVERED, /* No new flags below this line */ TFLAG_MAX } TFLAGS; @@ -574,6 +578,7 @@ struct private_object { switch_codec_t read_codec; switch_codec_t write_codec; uint32_t codec_ms; + uint32_t bitrate; switch_caller_profile_t *caller_profile; uint32_t timestamp_send; switch_rtp_t *rtp_session; @@ -939,6 +944,7 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int const char *sofia_glue_strip_proto(const char *uri); switch_status_t reconfig_sofia(sofia_profile_t *profile); void sofia_glue_del_gateway(sofia_gateway_t *gp); +void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up); void sofia_glue_del_every_gateway(sofia_profile_t *profile); void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent, const char *network_ip); @@ -1008,3 +1014,7 @@ char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefi void sofia_glue_tech_simplify(private_object_t *tech_pvt); switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *profile, const char *user, const char *host); switch_bool_t sofia_glue_profile_exists(const char *key); +void sofia_glue_global_siptrace(switch_bool_t on); +void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp); +switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt); +void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl); diff --git a/src/mod/endpoints/mod_sofia/sip-dig.c b/src/mod/endpoints/mod_sofia/sip-dig.c index f4714bccda..d0c9aa6aff 100644 --- a/src/mod/endpoints/mod_sofia/sip-dig.c +++ b/src/mod/endpoints/mod_sofia/sip-dig.c @@ -785,7 +785,7 @@ int dig_addr(struct dig *dig, char const *tport2 = NULL; sres_record_t **answers1 = NULL, **answers2 = NULL; unsigned count1 = 0, count2 = 0, tcount = 0; - int type1 = 0, type2 = 0, family1 = 0, family2 = 0; + uint16_t type1 = 0, type2 = 0, family1 = 0, family2 = 0; if (dig->ip6 > dig->ip4) { type1 = sres_type_aaaa, family1 = AF_INET6; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 14d05fd977..aa208c2aee 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1225,7 +1225,7 @@ static void sofia_perform_profile_start_failure(sofia_profile_t *profile, char * #define sofia_profile_start_failure(p, xp) sofia_perform_profile_start_failure(p, xp, __FILE__, __LINE__) -#define SQLLEN 1024 * 64 +#define SQLLEN 1024 * 1024 void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread, void *obj) { sofia_profile_t *profile = (sofia_profile_t *) obj; @@ -1233,11 +1233,12 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread uint32_t gateway_loops = 0; int loops = 0; uint32_t qsize; - void *pop; + void *pop = NULL; int loop_count = 0; - switch_size_t sql_len = SQLLEN; + switch_size_t sql_len = 1024 * 32; char *tmp, *sqlbuf = NULL; - + char *sql = NULL; + if (sofia_test_pflag(profile, PFLAG_SQL_IN_TRANS)) { sqlbuf = (char *) malloc(sql_len); } @@ -1253,37 +1254,43 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING)) || qsize) { if (sofia_test_pflag(profile, PFLAG_SQL_IN_TRANS)) { - if (qsize > 0 && (qsize >= 1024 || ++loop_count >= profile->trans_timeout)) { + if (qsize > 0 && (qsize >= 1024 || ++loop_count >= (int)profile->trans_timeout)) { switch_size_t newlen; - uint32_t itterations = 0; + uint32_t iterations = 0; switch_size_t len = 0; switch_mutex_lock(profile->ireg_mutex); - //sofia_glue_actually_execute_sql(profile, "begin;\n", NULL); - - while (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { - char *sql = (char *) pop; + while (sql || (switch_queue_trypop(profile->sql_queue, &pop) == SWITCH_STATUS_SUCCESS && pop)) { + if (!sql) sql = (char *) pop; newlen = strlen(sql) + 2; + iterations++; - if (newlen + 10 < SQLLEN) { - itterations++; - if (len + newlen + 10 > sql_len) { - sql_len = len + 10 + SQLLEN; + if (len + newlen + 10 > sql_len) { + switch_size_t new_mlen = len + newlen + 10 + 10240; + + if (new_mlen < SQLLEN) { + sql_len = new_mlen; + if (!(tmp = realloc(sqlbuf, sql_len))) { abort(); break; } sqlbuf = tmp; + } else { + goto skip; } - sprintf(sqlbuf + len, "%s;\n", sql); - len += newlen; } - free(pop); + sprintf(sqlbuf + len, "%s;\n", sql); + len += newlen; + free(sql); + sql = NULL; } + skip: + //printf("TRANS:\n%s\n", sqlbuf); sofia_glue_actually_execute_sql_trans(profile, sqlbuf, NULL); //sofia_glue_actually_execute_sql(profile, "commit;\n", NULL); @@ -2258,6 +2265,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_PASS_CALLEE_ID); } + } else if (!strcasecmp(var, "delete-subs-on-register")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } else { + sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } } else if (!strcasecmp(var, "in-dialog-chat")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT); @@ -2305,12 +2318,6 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); } - } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); - } else { - sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); - } } else if (!strcasecmp(var, "t38-passthru")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_T38_PASSTHRU); @@ -2549,6 +2556,12 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING); } + } else if (!strcasecmp(var, "all-reg-options-ping")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING); + } else { + sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING); + } } else if (!strcasecmp(var, "inbound-codec-negotiation")) { if (!strcasecmp(val, "greedy")) { sofia_set_pflag(profile, PFLAG_GREEDY); @@ -2860,7 +2873,7 @@ switch_status_t config_sofia(int reload, char *profile_name) goto done; } - profile->trans_timeout = 500; + profile->trans_timeout = 100; profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833; @@ -2920,6 +2933,12 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n"); } + } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } else { + sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } } else if (!strcasecmp(var, "user-agent-string")) { profile->user_agent = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "auto-restart")) { @@ -2936,6 +2955,12 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_IN_DIALOG_CHAT); } + } else if (!strcasecmp(var, "delete-subs-on-register")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } else { + sofia_clear_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + } } else if (!strcasecmp(var, "t38-passthru")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_T38_PASSTHRU); @@ -3303,6 +3328,12 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_NAT_OPTIONS_PING); } + } else if (!strcasecmp(var, "all-options-ping")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING); + } else { + sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING); + } } else if (!strcasecmp(var, "inbound-codec-negotiation")) { if (!strcasecmp(val, "greedy")) { sofia_set_pflag(profile, PFLAG_GREEDY); @@ -3914,6 +3945,23 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } } +#if 0 + if (status == 200 && switch_channel_test_flag(channel, CF_PROXY_MEDIA) && + sip->sip_payload && sip->sip_payload->pl_data && !strcasecmp(tech_pvt->iananame, "PROXY")) { + switch_core_session_t *other_session; + + sofia_glue_proxy_codec(session, sip->sip_payload->pl_data); + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_compare(session, other_session)) { + sofia_glue_proxy_codec(other_session, sip->sip_payload->pl_data); + } + switch_core_session_rwunlock(other_session); + } + } +#endif + + if ((status == 180 || status == 183 || status == 200)) { const char *x_freeswitch_support; @@ -3940,7 +3988,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } - if (channel && sip && (status == 300 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) { + if (channel && sip && (status == 300 || status == 301 || status == 302 || status == 305) && switch_channel_test_flag(channel, CF_OUTBOUND)) { sip_contact_t *p_contact = sip->sip_contact; int i = 0; char var_name[80]; @@ -4090,7 +4138,8 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } } - if (tech_pvt && tech_pvt->remote_sdp_str && switch_stristr("m=image", tech_pvt->remote_sdp_str)) { + + if (sip->sip_payload && sip->sip_payload->pl_data && switch_stristr("m=image", sip->sip_payload->pl_data)) { has_t38 = 1; } @@ -4118,6 +4167,36 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) { if (sip->sip_payload && sip->sip_payload->pl_data) { switch_t38_options_t *t38_options = sofia_glue_extract_t38_options(session, sip->sip_payload->pl_data); + char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session); + switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session); + char tmp[32] = ""; + + tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, t38_options->remote_ip); + tech_pvt->remote_sdp_audio_port = t38_options->remote_port; + + if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && + remote_port == tech_pvt->remote_sdp_audio_port) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "Audio params are unchanged for %s.\n", + switch_channel_get_name(tech_pvt->channel)); + } else { + const char *err = NULL; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "Audio params changed for %s from %s:%d to %s:%d\n", + switch_channel_get_name(tech_pvt->channel), + remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port); + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); + if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); + } + } + if (t38_options) { sofia_glue_copy_t38_options(t38_options, other_session); @@ -4145,16 +4224,13 @@ 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) { - switch_core_session_receive_message(other_session, msg); if (switch_rtp_ready(tech_pvt->rtp_session) && switch_rtp_ready(other_tech_pvt->rtp_session)) { switch_rtp_udptl_mode(tech_pvt->rtp_session); - switch_rtp_udptl_mode(other_tech_pvt->rtp_session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n"); } - } else { - switch_core_session_queue_message(other_session, msg); } + switch_core_session_queue_message(other_session, msg); switch_core_session_rwunlock(other_session); } @@ -4374,7 +4450,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (ss_state == nua_callstate_terminated) { - if ((status == 300 || status == 302 || status == 305) && session) { + if ((status == 300 || status == 301 || status == 302 || status == 305) && session) { channel = switch_core_session_get_channel(session); tech_pvt = switch_core_session_get_private(session); @@ -4447,6 +4523,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } + + state_process: switch ((enum nua_callstate) ss_state) { @@ -4521,7 +4599,20 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } break; case nua_callstate_completing: - nua_ack(nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); + { + if (sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) { + const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via"); + const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri"); + + nua_ack(nh, + TAG_IF(!zstr(invite_full_via), SIPTAG_VIA_STR(invite_full_via)), + TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)), + TAG_END()); + + } else { + nua_ack(nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); + } + } goto done; case nua_callstate_received: if (!sofia_test_flag(tech_pvt, TFLAG_SDP)) { @@ -4912,6 +5003,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag(tech_pvt, TFLAG_SDP); switch_channel_mark_answered(channel); + if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) { @@ -4932,6 +5024,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag_locked(tech_pvt, TFLAG_SDP); switch_channel_mark_answered(channel); + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if (sofia_glue_activate_rtp(tech_pvt, 0) != SWITCH_STATUS_SUCCESS) { goto done; @@ -5037,6 +5130,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } done: + if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) { sofia_glue_tech_simplify(tech_pvt); @@ -5188,7 +5282,6 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces) } - void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]) { /* Incoming refer */ @@ -5761,7 +5854,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype && sip->sip_payload && sip->sip_payload->pl_data) { - if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) { + if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "media_control+xml")) { + switch_core_session_t *other_session; + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + sofia_glue_build_vid_refresh_message(other_session, sip->sip_payload->pl_data); + switch_core_session_rwunlock(other_session); + } else { + sofia_glue_build_vid_refresh_message(session, sip->sip_payload->pl_data); + } + + } else if (!strncasecmp(sip->sip_content_type->c_type, "application", 11) && !strcasecmp(sip->sip_content_type->c_subtype, "dtmf-relay")) { /* Try and find signal information in the payload */ if ((signal_ptr = switch_stristr("Signal=", sip->sip_payload->pl_data))) { int tmp; @@ -5901,6 +6004,26 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session, { char *call_info = NULL; + if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) { + switch_channel_t *channel = switch_core_session_get_channel(session); + private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); + char network_ip[80]; + int network_port = 0; + char via_space[2048]; + char branch[16] = ""; + + sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef"); + + switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch); + switch_channel_set_variable(channel, "sip_full_via", via_space); + switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port); + switch_channel_set_variable_printf(channel, "sip_recieved_port", "%d", network_port); + switch_channel_set_variable_printf(channel, "sip_via_rport", "%d", network_port); + + sofia_glue_tech_track(tech_pvt->profile, session); + } + if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { switch_channel_t *channel = switch_core_session_get_channel(session); if (channel && sip->sip_call_info) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 82b933c981..e4933c63c1 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -41,11 +41,16 @@ switch_cache_db_handle_t *sofia_glue_get_db_handle(sofia_profile_t *profile); void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options, int insist) { - char buf[2048]; + char buf[2048] = ""; + char max_buf[128] = ""; + char max_data[128] = ""; const char *ip = t38_options->local_ip; uint32_t port = t38_options->local_port; const char *family = "IP4"; const char *username = tech_pvt->profile->username; + char MMR[32] = ""; + char JBIG[32] = ""; + char FILLBIT[32] = ""; //sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); @@ -89,6 +94,56 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * "o=%s %010u %010u IN %s %s\n" "s=%s\n" "c=IN %s %s\n" "t=0 0\n", username, tech_pvt->owner_id, tech_pvt->session_id, family, ip, username, family, ip); + if(t38_options->T38FaxFillBitRemoval) { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval"))) { + switch_snprintf(FILLBIT, sizeof(FILLBIT), "a=T38FaxFillBitRemoval:1\n"); + } else { + switch_set_string(FILLBIT, "a=T38FaxFillBitRemoval\n"); + } + } else { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval"))) { + switch_snprintf(FILLBIT, sizeof(FILLBIT), "a=T38FaxFillBitRemoval:0\n"); + } else { + switch_set_string(FILLBIT, ""); + } + } + + if( t38_options->T38FaxTranscodingMMR) { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR"))) { + switch_snprintf(MMR, sizeof(MMR), "a=T38FaxTranscodingMMR:1\n"); + } else { + switch_set_string(MMR, "a=T38FaxTranscodingMMR\n"); + } + } else { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR"))) { + switch_snprintf(MMR, sizeof(MMR), "a=T38FaxTranscodingMMR:0\n"); + } else { + switch_set_string(MMR, ""); + } + } + + if( t38_options->T38FaxTranscodingJBIG) { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG"))) { + switch_snprintf(JBIG, sizeof(JBIG), "a=T38FaxTranscodingJBIG:1\n"); + } else { + switch_set_string(JBIG, "a=T38FaxTranscodingJBIG\n"); + } + } else { + if (switch_true(switch_channel_get_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG"))) { + switch_snprintf(JBIG, sizeof(JBIG), "a=T38FaxTranscodingJBIG:0\n"); + } else { + switch_set_string(JBIG, ""); + } + } + + if (t38_options->T38FaxMaxBuffer) { + switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer); + }; + + if (t38_options->T38FaxMaxDatagram) { + switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\n", t38_options->T38FaxMaxDatagram); + }; + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=image %d udptl t38\n" @@ -98,19 +153,20 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * "%s" "%s" "a=T38FaxRateManagement:%s\n" - "a=T38FaxMaxBuffer:%d\n" - "a=T38FaxMaxDatagram:%d\n" + "%s" + "%s" "a=T38FaxUdpEC:%s\n", //"a=T38VendorInfo:%s\n", port, t38_options->T38FaxVersion, t38_options->T38MaxBitRate, - t38_options->T38FaxFillBitRemoval ? "a=T38FaxFillBitRemoval\n" : "", - t38_options->T38FaxTranscodingMMR ? "a=T38FaxTranscodingMMR\n" : "", - t38_options->T38FaxTranscodingJBIG ? "a=T38FaxTranscodingJBIG\n" : "", + FILLBIT, + MMR, + JBIG, t38_options->T38FaxRateManagement, - t38_options->T38FaxMaxBuffer, - t38_options->T38FaxMaxDatagram, t38_options->T38FaxUdpEC + max_buf, + max_data, + t38_options->T38FaxUdpEC //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0" ); @@ -146,6 +202,13 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 const char *username = tech_pvt->profile->username; const char *fmtp_out = tech_pvt->fmtp_out; const char *fmtp_out_var = switch_channel_get_variable(tech_pvt->channel, "sip_force_audio_fmtp"); + switch_event_t *map = NULL, *ptmap = NULL; + const char *b_sdp = NULL; + + if (!tech_pvt->rm_encoding && (b_sdp = switch_channel_get_variable(tech_pvt->channel, SWITCH_B_SDP_VARIABLE))) { + sofia_glue_sdp_map(b_sdp, &map, &ptmap); + } + if (fmtp_out_var) { fmtp_out = fmtp_out_var; @@ -274,7 +337,8 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 int already_did[128] = { 0 }; for (i = 0; i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; - + char *fmtp = imp->fmtp; + if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) { continue; } @@ -289,9 +353,20 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 rate = imp->samples_per_second; + if (map) { + char key[128] = ""; + char *check = NULL; + switch_snprintf(key, sizeof(key), "%s:%u", imp->iananame, imp->bits_per_second); + + if ((check = switch_event_get_header(map, key)) || (check = switch_event_get_header(map, imp->iananame))) { + fmtp = check; + } + } + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", imp->ianacode, imp->iananame, rate); - if (imp->fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, imp->fmtp); + + if (fmtp) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, fmtp); } } } @@ -423,38 +498,87 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 int i; int already_did[128] = { 0 }; +#if 0 + switch_event_t *event; + char *buf; + int level = SWITCH_LOG_INFO; + + if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(switch_core_session_get_channel(tech_pvt->session), event); + switch_event_serialize(event, &buf, SWITCH_FALSE); + switch_assert(buf); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), level, "CHANNEL_DATA:\n%s\n", buf); + switch_event_destroy(&event); + free(buf); + } +#endif + for (i = 0; i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; + char *fmtp = NULL; + uint32_t ianacode = imp->ianacode; +#if 0 + const char *str; + + + if ((str = switch_event_get_header(ptmap, imp->iananame))) { + int tmp = atoi(str); + if (tmp > 0) { + ianacode = tmp; + } + } +#endif if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { continue; } - if (imp->ianacode < 128) { - if (already_did[imp->ianacode]) { + if (ianacode < 128) { + if (already_did[ianacode]) { continue; } - already_did[imp->ianacode] = 1; + already_did[ianacode] = 1; } if (!rate) { rate = imp->samples_per_second; } - - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", imp->ianacode, imp->iananame, + + + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d %s/%d\n", ianacode, imp->iananame, imp->samples_per_second); - if (imp->fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, imp->fmtp); + + if (!zstr(ov_fmtp)) { + fmtp = (char *) ov_fmtp; } else { - if (pass_fmtp) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, pass_fmtp); + + if (map) { + fmtp = switch_event_get_header(map, imp->iananame); } + + if (zstr(fmtp)) fmtp = imp->fmtp; + + if (zstr(fmtp)) fmtp = (char *) pass_fmtp; + } + + if (!zstr(fmtp) && strcasecmp(fmtp, "_blank_")) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=fmtp:%d %s\n", imp->ianacode, fmtp); } } + } } } + + if (map) { + switch_event_destroy(&map); + } + + if (ptmap) { + switch_event_destroy(&ptmap); + } + sofia_glue_tech_set_local_sdp(tech_pvt, buf, SWITCH_TRUE); } @@ -748,32 +872,30 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc sdp_port = tech_pvt->local_sdp_audio_port; - if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_audio_ip")) - && !zstr(tech_pvt->profile->extrtpip)) { - use_ip = tech_pvt->profile->extrtpip; - } + /* Check if NAT is detected */ + if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + /* Yes, map the port through switch_nat */ + switch_nat_add_mapping(tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); + switch_nat_add_mapping(tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP, &rtcp_port, SWITCH_FALSE); - if (use_ip) { - if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, - use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ - return SWITCH_STATUS_FALSE; - } else { - if (lookup_rtpip == use_ip) { - /* sofia_glue_ext_address_lookup didn't return any error, but the return IP is the same as the original one, - which means no lookup was necessary. Check if NAT is detected */ - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { - /* Yes, map the port through switch_nat */ - switch_nat_add_mapping(tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); - switch_nat_add_mapping(tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP, &rtcp_port, SWITCH_FALSE); - } else { - /* No NAT detected */ - use_ip = tech_pvt->rtpip; - } + /* Find an IP address to use */ + if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_audio_ip")) + && !zstr(tech_pvt->profile->extrtpip)) { + use_ip = tech_pvt->profile->extrtpip; + } + + if (use_ip) { + if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, + use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { + /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ + return SWITCH_STATUS_FALSE; } else { /* Address properly resolved, use it as external ip */ use_ip = lookup_rtpip; } + } else { + /* No external ip found, use the profile's rtp ip */ + use_ip = tech_pvt->rtpip; } } else { /* No NAT traversal required, use the profile's rtp ip */ @@ -817,31 +939,29 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in sdp_port = tech_pvt->local_sdp_video_port; - if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_video_ip")) - && !zstr(tech_pvt->profile->extrtpip)) { - use_ip = tech_pvt->profile->extrtpip; - } + /* Check if NAT is detected */ + if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + /* Yes, map the port through switch_nat */ + switch_nat_add_mapping(tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); - if (use_ip) { - if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, - use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { - /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ - return SWITCH_STATUS_FALSE; - } else { - if (lookup_rtpip == use_ip) { - /* sofia_glue_ext_address_lookup didn't return any error, but the return IP is the same as the original one, - which means no lookup was necessary. Check if NAT is detected */ - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { - /* Yes, map the port through switch_nat */ - switch_nat_add_mapping(tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); - } else { - /* No NAT detected */ - use_ip = tech_pvt->rtpip; - } + /* Find an IP address to use */ + if (!(use_ip = switch_channel_get_variable(tech_pvt->channel, "rtp_adv_video_ip")) + && !zstr(tech_pvt->profile->extrtpip)) { + use_ip = tech_pvt->profile->extrtpip; + } + + if (use_ip) { + if (sofia_glue_ext_address_lookup(tech_pvt->profile, tech_pvt, &lookup_rtpip, &sdp_port, + use_ip, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { + /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ + return SWITCH_STATUS_FALSE; } else { /* Address properly resolved, use it as external ip */ use_ip = lookup_rtpip; } + } else { + /* No external ip found, use the profile's rtp ip */ + use_ip = tech_pvt->rtpip; } } else { /* No NAT traversal required, use the profile's rtp ip */ @@ -1162,7 +1282,7 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) switch_port_t remote_rtcp_port = 0; if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } @@ -1198,7 +1318,7 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) } if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } @@ -1516,7 +1636,11 @@ char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefi if (!strncasecmp(name, prefix, strlen(prefix))) { const char *hname = name + strlen(prefix); - stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n\n%s\n", boundary, hname, strlen(value) + 1, value); + if (*value == '~') { + stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n%s\n", boundary, hname, strlen(value), value + 1); + } else { + stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n\n%s\n", boundary, hname, strlen(value) + 1, value); + } x++; } } @@ -1658,7 +1782,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) sofia_private_t *sofia_private; char *invite_contact = NULL, *to_str, *use_from_str, *from_str; const char *t_var; - char *rpid_domain = "cluecon.com", *p; + char *rpid_domain = NULL, *p; const char *priv = "off"; const char *screen = "no"; const char *invite_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_params"); @@ -1670,6 +1794,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) const char *from_var = switch_channel_get_variable(tech_pvt->channel, "sip_from_uri"); const char *from_display = switch_channel_get_variable(tech_pvt->channel, "sip_from_display"); const char *invite_req_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_req_uri"); + const char *invite_domain = switch_channel_get_variable(tech_pvt->channel, "sip_invite_domain"); const char *use_name, *use_number; if (zstr(tech_pvt->dest)) { @@ -1688,7 +1813,6 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (!tech_pvt->from_str) { const char *sipip; const char *format; - const char *alt = NULL; sipip = tech_pvt->profile->sipip; @@ -1698,8 +1822,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) format = strchr(sipip, ':') ? "\"%s\" <sip:%s%s[%s]>" : "\"%s\" <sip:%s%s%s>"; - if ((alt = switch_channel_get_variable(channel, "sip_invite_domain"))) { - sipip = alt; + if (!zstr(invite_domain)) { + sipip = invite_domain; } tech_pvt->from_str = switch_core_session_sprintf(tech_pvt->session, format, cid_name, cid_num, !zstr(cid_num) ? "@" : "", sipip); @@ -1739,6 +1863,10 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } } + if (!zstr(invite_domain)) { + rpid_domain = (char *)invite_domain; + } + if (zstr(rpid_domain)) { rpid_domain = "cluecon.com"; } @@ -1864,10 +1992,22 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) switch_channel_set_variable(channel, "sip_req_uri", s); } - tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL, - NUTAG_URL(url_str), - TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)), - SIPTAG_TO_STR(to_str), SIPTAG_FROM_STR(from_str), SIPTAG_CONTACT_STR(invite_contact), TAG_END()); + if (!(tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL, + NUTAG_URL(url_str), + TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)), + SIPTAG_TO_STR(to_str), SIPTAG_FROM_STR(from_str), SIPTAG_CONTACT_STR(invite_contact), TAG_END()))) { + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, + "Error creating HANDLE!\nurl_str=[%s]\ncall_id=[%s]\nto_str=[%s]\nfrom_str=[%s]\ninvite_contact=[%s]\n", + url_str, + call_id ? call_id : "N/A", + to_str, + from_str, + invite_contact); + + switch_safe_free(d_url); + return SWITCH_STATUS_FALSE; + } if (tech_pvt->dest && (strstr(tech_pvt->dest, ";fs_nat") || strstr(tech_pvt->dest, ";received") || ((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val)))) { @@ -2055,10 +2195,16 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); } + if (sofia_test_flag(tech_pvt, TFLAG_RECOVERED)) { + session_timeout = 0; + } + if (sofia_use_soa(tech_pvt)) { nua_invite(tech_pvt->nh, NUTAG_AUTOANSWER(0), NUTAG_SESSION_TIMER(session_timeout), + TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)), + TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)), TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected)), @@ -2087,6 +2233,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) nua_invite(tech_pvt->nh, NUTAG_AUTOANSWER(0), NUTAG_SESSION_TIMER(session_timeout), + TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)), + TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)), TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected)), @@ -2230,6 +2378,9 @@ static void set_stats(switch_rtp_t *rtp_session, private_object_t *tech_pvt, con add_stat(stats->outbound.dtmf_packet_count, "out_dtmf_packet_count"); add_stat(stats->outbound.cng_packet_count, "out_cng_packet_count"); + add_stat(stats->rtcp.packet_count, "rtcp_packet_count"); + add_stat(stats->rtcp.octet_count, "rtcp_octet_count"); + } } @@ -2386,24 +2537,26 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) } } - if (switch_core_codec_init(&tech_pvt->read_codec, + if (switch_core_codec_init_with_bitrate(&tech_pvt->read_codec, tech_pvt->iananame, tech_pvt->rm_fmtp, tech_pvt->rm_rate, tech_pvt->codec_ms, 1, + tech_pvt->bitrate, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags, NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); switch_goto_status(SWITCH_STATUS_FALSE, end); } - if (switch_core_codec_init(&tech_pvt->write_codec, + if (switch_core_codec_init_with_bitrate(&tech_pvt->write_codec, tech_pvt->iananame, tech_pvt->rm_fmtp, tech_pvt->rm_rate, tech_pvt->codec_ms, 1, + tech_pvt->bitrate, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags, NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -2427,9 +2580,10 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) if (switch_rtp_ready(tech_pvt->rtp_session)) { switch_assert(tech_pvt->read_codec.implementation); - + if (switch_rtp_change_interval(tech_pvt->rtp_session, - tech_pvt->read_impl.microseconds_per_packet, tech_pvt->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) { + tech_pvt->read_impl.microseconds_per_packet, + tech_pvt->read_impl.samples_per_packet) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_goto_status(SWITCH_STATUS_FALSE, end); } @@ -2443,9 +2597,9 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) switch_goto_status(SWITCH_STATUS_FALSE, end); } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples %d bits\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->iananame, tech_pvt->rm_rate, tech_pvt->codec_ms, - tech_pvt->read_impl.samples_per_packet); + tech_pvt->read_impl.samples_per_packet, tech_pvt->read_impl.bits_per_second); tech_pvt->read_frame.codec = &tech_pvt->read_codec; tech_pvt->write_codec.agreed_pt = tech_pvt->agreed_pt; @@ -2689,6 +2843,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->local_sdp_audio_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt); + } } switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_audio_port); @@ -2702,7 +2860,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, @@ -2741,6 +2899,10 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, tech_pvt->agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->rtp_session, tech_pvt->agreed_pt); + } + } else { timer_name = tech_pvt->profile->timer_name; @@ -2833,7 +2995,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"); switch_port_t remote_port = 0; if (rport) { - remote_port = atoi(rport); + remote_port = (switch_port_t)atoi(rport); } if (!strcasecmp(val, "passthru")) { switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port); @@ -2931,13 +3093,14 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f sofia_glue_check_video_codecs(tech_pvt); if (sofia_test_flag(tech_pvt, TFLAG_VIDEO) && tech_pvt->video_rm_encoding && tech_pvt->remote_sdp_video_port) { - + /******************************************************************************************/ if (tech_pvt->video_rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { //const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE); //const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE); char *remote_host = switch_rtp_get_remote_host(tech_pvt->video_rtp_session); switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->video_rtp_session); + if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_video_ip) && remote_port == tech_pvt->remote_sdp_video_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n", @@ -2955,8 +3118,12 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n", switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_audio_ip, tech_pvt->local_sdp_video_port, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); - } + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } + } + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->local_sdp_video_port); switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip); switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp); @@ -2968,7 +3135,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { - remote_rtcp_port = atoi(rport); + remote_rtcp_port = (switch_port_t)atoi(rport); } if (switch_rtp_set_remote_address @@ -2983,6 +3150,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f /* Reactivate the NAT buster flag. */ switch_rtp_set_flag(tech_pvt->video_rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } + } goto video_up; } @@ -3008,6 +3176,9 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, tech_pvt->read_impl.microseconds_per_packet / 1000); + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } } else { timer_name = tech_pvt->profile->timer_name; @@ -3058,6 +3229,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->remote_sdp_video_port, tech_pvt->video_agreed_pt, 0, switch_rtp_ready(tech_pvt->video_rtp_session) ? "SUCCESS" : err); + + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + switch_rtp_set_default_payload(tech_pvt->video_rtp_session, tech_pvt->video_agreed_pt); + } + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { const char *ssrc; switch_channel_set_flag(tech_pvt->channel, CF_VIDEO); @@ -3076,7 +3252,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"); switch_port_t remote_port = 0; if (rport) { - remote_port = atoi(rport); + remote_port = (switch_port_t)atoi(rport); } if (!strcasecmp(val, "passthru")) { switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port); @@ -3418,11 +3594,11 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ t38_options = switch_core_session_alloc(tech_pvt->session, sizeof(switch_t38_options_t)); } - t38_options->remote_port = m->m_port; + t38_options->remote_port = (switch_port_t)m->m_port; - if (m->m_connections) { + if (m->m_connections && m->m_connections->c_address) { t38_options->remote_ip = switch_core_session_strdup(tech_pvt->session, m->m_connections->c_address); - } else if (sdp && sdp->sdp_connection) { + } else if (sdp && sdp->sdp_connection && sdp->sdp_connection->c_address) { t38_options->remote_ip = switch_core_session_strdup(tech_pvt->session, sdp->sdp_connection->c_address); } @@ -3432,11 +3608,41 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ } else if (!strcasecmp(attr->a_name, "T38MaxBitRate") && attr->a_value) { t38_options->T38MaxBitRate = (uint32_t) atoi(attr->a_value); } else if (!strcasecmp(attr->a_name, "T38FaxFillBitRemoval")) { - t38_options->T38FaxFillBitRemoval = SWITCH_TRUE; + if (switch_stristr("T38FaxFillBitRemoval:", tech_pvt->remote_sdp_str)) { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval", "true"); + if (atoi(attr->a_value) == 0) { + t38_options->T38FaxFillBitRemoval = SWITCH_FALSE; + } else { + t38_options->T38FaxFillBitRemoval = SWITCH_TRUE; + } + } else { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxFillBitRemoval", "false"); + t38_options->T38FaxFillBitRemoval = SWITCH_TRUE; + } } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingMMR")) { - t38_options->T38FaxTranscodingMMR = SWITCH_TRUE; + if (switch_stristr("T38FaxTranscodingMMR:", tech_pvt->remote_sdp_str)) { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR", "true"); + if (atoi(attr->a_value) == 0) { + t38_options->T38FaxTranscodingMMR = SWITCH_FALSE; + } else { + t38_options->T38FaxTranscodingMMR = SWITCH_TRUE; + } + } else { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingMMR", "false"); + t38_options->T38FaxTranscodingMMR = SWITCH_TRUE; + } } else if (!strcasecmp(attr->a_name, "T38FaxTranscodingJBIG")) { - t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE; + if (switch_stristr("T38FaxTranscodingJBIG:", tech_pvt->remote_sdp_str)) { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG", "true"); + if (atoi(attr->a_value) == 0) { + t38_options->T38FaxTranscodingJBIG = SWITCH_FALSE; + } else { + t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE; + } + } else { + switch_channel_set_variable(tech_pvt->channel, "broken_T38FaxTranscodingJBIG", "false"); + t38_options->T38FaxTranscodingJBIG = SWITCH_TRUE; + } } else if (!strcasecmp(attr->a_name, "T38FaxRateManagement") && attr->a_value) { t38_options->T38FaxRateManagement = switch_core_session_strdup(tech_pvt->session, attr->a_value); } else if (!strcasecmp(attr->a_name, "T38FaxMaxBuffer") && attr->a_value) { @@ -3457,6 +3663,131 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ return t38_options; } + +switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, switch_event_t **pt) +{ + sdp_media_t *m; + sdp_parser_t *parser = NULL; + sdp_session_t *sdp; + + if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { + return SWITCH_STATUS_FALSE; + } + + if (!(sdp = sdp_session(parser))) { + sdp_parser_free(parser); + return SWITCH_STATUS_FALSE; + } + + switch_event_create(&(*fmtp), SWITCH_EVENT_REQUEST_PARAMS); + switch_event_create(&(*pt), SWITCH_EVENT_REQUEST_PARAMS); + + for (m = sdp->sdp_media; m; m = m->m_next) { + if (m->m_proto == sdp_proto_rtp) { + sdp_rtpmap_t *map; + + for (map = m->m_rtpmaps; map; map = map->rm_next) { + if (map->rm_encoding) { + char buf[25] = ""; + char key[128] = ""; + char *br = NULL; + + if (map->rm_fmtp) { + if ((br = strstr(map->rm_fmtp, "bitrate="))) { + br += 8; + } + } + + switch_snprintf(buf, sizeof(buf), "%d", map->rm_pt); + + if (br) { + switch_snprintf(key, sizeof(key), "%s:%s", map->rm_encoding, br); + } else { + switch_snprintf(key, sizeof(key), "%s", map->rm_encoding); + } + + switch_event_add_header_string(*pt, SWITCH_STACK_BOTTOM, key, buf); + + if (map->rm_fmtp) { + switch_event_add_header_string(*fmtp, SWITCH_STACK_BOTTOM, key, map->rm_fmtp); + } + } + } + } + } + + sdp_parser_free(parser); + + return SWITCH_STATUS_SUCCESS; + +} + + +void sofia_glue_proxy_codec(switch_core_session_t *session, const char *r_sdp) +{ + sdp_media_t *m; + sdp_parser_t *parser = NULL; + sdp_session_t *sdp; + private_object_t *tech_pvt = switch_core_session_get_private(session); + sdp_attribute_t *attr; + int ptime = 0, dptime = 0, dmaxptime = 0, maxptime = 0; + + if (!(parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { + return; + } + + if (!(sdp = sdp_session(parser))) { + sdp_parser_free(parser); + return; + } + + switch_assert(tech_pvt != NULL); + + + for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) { + if (zstr(attr->a_name)) { + continue; + } + + if (!strcasecmp(attr->a_name, "ptime")) { + dptime = atoi(attr->a_value); + } else if (!strcasecmp(attr->a_name, "maxptime")) { + dmaxptime = atoi(attr->a_value); + } + } + + + for (m = sdp->sdp_media; m; m = m->m_next) { + + ptime = dptime; + maxptime = dmaxptime; + + if (m->m_proto == sdp_proto_rtp) { + sdp_rtpmap_t *map; + for (attr = m->m_attributes; attr; attr = attr->a_next) { + if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { + ptime = atoi(attr->a_value); + } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) { + maxptime = atoi(attr->a_value); + } + } + + for (map = m->m_rtpmaps; map; map = map->rm_next) { + tech_pvt->iananame = switch_core_session_strdup(tech_pvt->session, map->rm_encoding); + tech_pvt->rm_rate = map->rm_rate; + tech_pvt->codec_ms = ptime; + sofia_glue_tech_set_codec(tech_pvt, 0); + break; + } + + break; + } + } + + sdp_parser_free(parser); + +} + switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *session, const char *r_sdp) { sdp_media_t *m; @@ -3498,7 +3829,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s sdp_attribute_t *attr; int first = 0, last = 0; int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0; - int codec_ms = 0; int sendonly = 0; int greedy = 0, x = 0, skip = 0, mine = 0; switch_channel_t *channel = switch_core_session_get_channel(session); @@ -3579,11 +3909,12 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s if (sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_HOLD) || ((val = switch_channel_get_variable(tech_pvt->channel, "sip_disable_hold")) && switch_true(val))) { sendonly = 0; - } + } else { - if (!tech_pvt->hold_laps) { - tech_pvt->hold_laps++; - sofia_glue_toggle_hold(tech_pvt, sendonly); + if (!tech_pvt->hold_laps) { + tech_pvt->hold_laps++; + sofia_glue_toggle_hold(tech_pvt, sendonly); + } } for (m = sdp->sdp_media; m; m = m->m_next) { @@ -3603,7 +3934,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s if (got_udptl && m->m_type == sdp_media_image && m->m_port) { switch_t38_options_t *t38_options = tech_process_udptl(tech_pvt, sdp, m); - + if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) { match = 0; goto done; @@ -3618,10 +3949,46 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s if (sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU)) { pass = 0; } - + + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || + switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA) || !switch_rtp_ready(tech_pvt->rtp_session)) { + pass = 0; + } + if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); switch_core_session_message_t *msg; + char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session); + switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session); + char tmp[32] = ""; + + tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, t38_options->remote_ip); + tech_pvt->remote_sdp_audio_port = t38_options->remote_port; + + if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", + switch_channel_get_name(tech_pvt->channel)); + } else { + const char *err = NULL; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n", + switch_channel_get_name(tech_pvt->channel), + remote_host, remote_port, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port); + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip); + switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); + + if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); + switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); + } + + } + + + sofia_glue_copy_t38_options(t38_options, other_session); sofia_set_flag(tech_pvt, TFLAG_T38_PASSTHRU); @@ -3783,6 +4150,8 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s uint32_t near_rate = 0; const switch_codec_implementation_t *mimp = NULL, *near_match = NULL; const char *rm_encoding; + uint32_t map_bit_rate = 0; + int codec_ms = 0; if (x++ < skip) { continue; @@ -3823,40 +4192,37 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } if (!ptime) { - ptime = 20; + ptime = switch_default_ptime(rm_encoding, map->rm_pt); } - if (!strcasecmp((char *) rm_encoding, "ilbc")) { - char *mode = NULL; - if (map->rm_fmtp && (mode = strstr(map->rm_fmtp, "mode=")) && (mode + 5)) { - codec_ms = atoi(mode + 5); - } - if (!codec_ms) { - /* default to 30 when no mode is defined for ilbc ONLY */ - codec_ms = 30; - } - } else { + map_bit_rate = switch_known_bitrate(map->rm_pt); + + if (!codec_ms) { codec_ms = ptime; } - - for (i = first; i < last && i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; + uint32_t bit_rate = imp->bits_per_second; uint32_t codec_rate = imp->samples_per_second; if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) { continue; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d]/[%s:%d:%u:%d]\n", - rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, - imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u]/[%s:%d:%u:%d:%u]\n", + rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, map_bit_rate, + imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate); if ((zstr(map->rm_encoding) || (tech_pvt->profile->ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { match = (map->rm_pt == imp->ianacode) ? 1 : 0; } else { match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1; } + if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate) { + /* nevermind */ + match = 0; + } + if (match) { if (scrooge) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, @@ -3918,6 +4284,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s tech_pvt->pt = (switch_payload_t) map->rm_pt; tech_pvt->rm_rate = map->rm_rate; tech_pvt->codec_ms = mimp->microseconds_per_packet / 1000; + tech_pvt->bitrate = mimp->bits_per_second; tech_pvt->remote_sdp_audio_ip = switch_core_session_strdup(session, (char *) connection->c_address); tech_pvt->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp); tech_pvt->remote_sdp_audio_port = (switch_port_t) m->m_port; @@ -4251,6 +4618,28 @@ void sofia_glue_del_every_gateway(sofia_profile_t *profile) } +void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up) +{ + sofia_gateway_t *gp = NULL; + char *r = (char *) stream->data; + + switch_mutex_lock(mod_sofia_globals.hash_mutex); + for (gp = profile->gateways; gp; gp = gp->next) { + int reged = (gp->status == SOFIA_GATEWAY_UP); + + if (up ? reged : !reged) { + stream->write_function(stream, "%s ", gp->name); + } + } + + if (r) { + end_of(r) = '\0'; + } + + switch_mutex_unlock(mod_sofia_globals.hash_mutex); +} + + void sofia_glue_del_gateway(sofia_gateway_t *gp) { if (!gp->deleted) { @@ -4304,6 +4693,27 @@ void sofia_glue_restart_all_profiles(void) } + +void sofia_glue_global_siptrace(switch_bool_t on) +{ + switch_hash_index_t *hi; + const void *var; + void *val; + sofia_profile_t *pptr; + + switch_mutex_lock(mod_sofia_globals.hash_mutex); + if (mod_sofia_globals.profile_hash) { + for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + if ((pptr = (sofia_profile_t *) val)) { + nua_set_params(pptr->nua, TPTAG_LOG(on), TAG_END()); + } + } + } + switch_mutex_unlock(mod_sofia_globals.hash_mutex); + +} + void sofia_glue_del_profile(sofia_profile_t *profile) { sofia_gateway_t *gp; @@ -4457,13 +4867,13 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName } if ((tmp = switch_channel_get_variable(channel, "sip_use_pt"))) { - tech_pvt->pt = tech_pvt->agreed_pt = atoi(tmp); + tech_pvt->pt = tech_pvt->agreed_pt = (switch_payload_t)atoi(tmp); } sofia_glue_tech_set_codec(tech_pvt, 1); tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip; - tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = atoi(port); + tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = (switch_port_t)atoi(port); if ((tmp = switch_channel_get_variable(channel, "local_media_ip"))) { tech_pvt->local_sdp_audio_ip = switch_core_session_strdup(session, tmp); @@ -4472,12 +4882,12 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName if (r_ip && r_port) { tech_pvt->remote_sdp_audio_ip = (char *) r_ip; - tech_pvt->remote_sdp_audio_port = atoi(r_port); + tech_pvt->remote_sdp_audio_port = (switch_port_t)atoi(r_port); } if (switch_channel_test_flag(channel, CF_VIDEO)) { if ((tmp = switch_channel_get_variable(channel, "sip_use_video_pt"))) { - tech_pvt->video_pt = tech_pvt->video_agreed_pt = atoi(tmp); + tech_pvt->video_pt = tech_pvt->video_agreed_pt = (switch_payload_t)atoi(tmp); } @@ -4499,11 +4909,11 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName tech_pvt->video_codec_ms = atoi(tmp); } - tech_pvt->adv_sdp_video_port = tech_pvt->local_sdp_video_port = atoi(port); + tech_pvt->adv_sdp_video_port = tech_pvt->local_sdp_video_port = (switch_port_t)atoi(port); if (r_ip && r_port) { tech_pvt->remote_sdp_video_ip = (char *) r_ip; - tech_pvt->remote_sdp_video_port = atoi(r_port); + tech_pvt->remote_sdp_video_port = (switch_port_t)atoi(r_port); } //sofia_glue_tech_set_video_codec(tech_pvt, 1); } @@ -4644,7 +5054,7 @@ void sofia_glue_tech_untrack(sofia_profile_t *profile, switch_core_session_t *se } } - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); sofia_clear_flag(tech_pvt, TFLAG_TRACKED); switch_safe_free(sql); @@ -5388,6 +5798,23 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt) } +void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl) +{ + switch_core_session_message_t *msg; + msg = switch_core_session_alloc(session, sizeof(*msg)); + MESSAGE_STAMP_FFL(msg); + msg->message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ; + if (pl) { + msg->string_arg = switch_core_session_strdup(session, pl); + } + msg->from = __FILE__; + + switch_core_session_queue_message(session, msg); +} + + + + /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 73d930314b..333f31b91d 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1442,7 +1442,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * op = switch_event_get_header(helper->event, "Caller-Callee-ID-Number"); } - if (!op) { + if (zstr(op)) { op = switch_event_get_header(helper->event, "Caller-Destination-Number"); } @@ -1452,7 +1452,7 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char * if (!strcmp(astate, "early")) { if (zstr(op)) { - switch_snprintf(status_line, sizeof(status_line), "%s %s", what, status); + switch_snprintf(status_line, sizeof(status_line), "%sing", what); } else { switch_snprintf(status_line, sizeof(status_line), "%s %s", what, op); } @@ -1983,12 +1983,20 @@ void sofia_presence_handle_sip_i_subscribe(int status, is_nat = NULL; } + if (zstr(contact_host)) { + is_nat = "No contact host"; + } + if (is_nat) { contact_host = network_ip; switch_snprintf(new_port, sizeof(new_port), ":%d", network_port); port = NULL; } + if (zstr(contact_host)) { + nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END()); + return; + } if (port) { switch_snprintf(new_port, sizeof(new_port), ":%s", port); @@ -2043,7 +2051,11 @@ void sofia_presence_handle_sip_i_subscribe(int status, from_host = "n/a"; } - exp_delta = profile->force_subscription_expires ? profile->force_subscription_expires : (sip->sip_expires ? sip->sip_expires->ex_delta : 3600); + if ((exp_delta = sip->sip_expires ? sip->sip_expires->ex_delta : 3600)) { + if (profile->force_subscription_expires) { + exp_delta = profile->force_subscription_expires; + } + } if (exp_delta) { exp_abs = (long) switch_epoch_time_now(NULL) + exp_delta; diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index eb9b03d958..285dc8ae3a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -438,11 +438,14 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames switch_snprintf(to, sizeof(to), "sip:%s@%s", argv[1], argv[2]); dst = sofia_glue_get_destination(argv[3]); switch_assert(dst); - + nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(profile->url), SIPTAG_TO_STR(to), NUTAG_URL(dst->contact), SIPTAG_CONTACT_STR(profile->url), TAG_END()); nua_handle_bind(nh, &mod_sofia_globals.destroy_private); - nua_options(nh, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_END()); + nua_options(nh, + NTATAG_SIP_T2(5000), + NTATAG_SIP_T4(10000), + TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), TAG_END()); sofia_glue_free_destination(dst); @@ -514,7 +517,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames switch_event_fire(&s_event); } - if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) { + if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "away"); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->url); @@ -637,15 +640,14 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) } sofia_glue_actually_execute_sql(profile, sql, NULL); - - - + if (now) { switch_snprintf(sql, sizeof(sql), "select call_id from sip_subscriptions where (expires = -1 or (expires > 0 and expires <= %ld)) and hostname='%s'", (long) now, mod_sofia_globals.hostname); } else { - switch_snprintf(sql, sizeof(sql), "select call_id from sip_subscriptions where expires >= -1 and hostname='%s'", mod_sofia_globals.hostname); + switch_snprintf(sql, sizeof(sql), "select sub_to_user,sub_to_host,call_id from sip_subscriptions where expires >= -1 and hostname='%s'", + mod_sofia_globals.hostname); } sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sub_del_callback, profile); @@ -670,13 +672,21 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) sofia_glue_actually_execute_sql(profile, sql, NULL); - if (now && sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) { - switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid," - "expires,user_agent,server_user,server_host,profile_name" - " from sip_registrations where (status like '%%AUTO-NAT%%' " - "or status like '%%UDP-NAT%%') and hostname='%s'", mod_sofia_globals.hostname); - - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile); + if (now) { + if (sofia_test_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)) { + switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid," + "expires,user_agent,server_user,server_host,profile_name" + " from sip_registrations where hostname='%s'", mod_sofia_globals.hostname); + + sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile); + } else if (sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) { + switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid," + "expires,user_agent,server_user,server_host,profile_name" + " from sip_registrations where (status like '%%NAT%%' " + "or contact like '%%fs_nat=yes%%') and hostname='%s'", mod_sofia_globals.hostname); + + sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_nat_callback, profile); + } } switch_mutex_unlock(profile->ireg_mutex); @@ -810,6 +820,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_event_t *auth_params = NULL; int r = 0; long reg_count = 0; + int delete_subs; + const char *agent = "unknown"; + + delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG); /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */ switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL); @@ -826,6 +840,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand to = sip->sip_to; from = sip->sip_from; + if (sip->sip_user_agent) { + agent = sip->sip_user_agent->g_string; + } + if (from) { from_user = from->a_url->url_user; from_host = from->a_url->url_host; @@ -913,7 +931,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (sip->sip_path) { path_val = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_path); - path_encoded_len = (strlen(path_val) * 3) + 1; + path_encoded_len = (int)(strlen(path_val) * 3) + 1; switch_zmalloc(path_encoded, path_encoded_len); switch_copy_string(path_encoded, ";fs_path=", 10); switch_url_encode(path_val, path_encoded + 9, path_encoded_len - 9); @@ -926,7 +944,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port); } - path_encoded_len = (strlen(my_contact_str) * 3) + 1; + path_encoded_len = (int)(strlen(my_contact_str) * 3) + 1; switch_zmalloc(path_encoded, path_encoded_len); switch_copy_string(path_encoded, ";fs_path=", 10); @@ -1135,7 +1153,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } if (exptime) { - const char *agent = "dunno"; char guess_ip4[256]; const char *username = "unknown"; const char *realm = reg_host; @@ -1145,19 +1162,15 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand realm = switch_event_get_header(auth_params, "sip_auth_realm"); } - if (sip->sip_user_agent) { - agent = sip->sip_user_agent->g_string; - } - if (multi_reg) { -#ifdef DEL_SUBS - if (reg_count == 1) { - sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", - to_user, sub_host, contact_str); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + if (delete_subs) { + if (reg_count == 1) { + sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", + to_user, sub_host, contact_str); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } } -#endif if (multi_reg_contact) { @@ -1167,10 +1180,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand sql = switch_mprintf("delete from sip_registrations where call_id='%q'", call_id); } } else { -#ifdef DEL_SUBS - sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); -#endif + if (delete_subs) { + sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", to_user, reg_host); } switch_mutex_lock(profile->ireg_mutex); @@ -1185,7 +1198,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand "mwi_user,mwi_host, orig_server_host, orig_hostname) " "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q')", call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : reg_host, - contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime * 2, + contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime + 60, agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm, mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname); @@ -1290,16 +1303,16 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if ((p = strchr(icontact + 4, ':'))) { *p = '\0'; } -#ifdef DEL_SUBS - if (multi_reg_contact) { - sql = - switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, sub_host, contact_str); - } else { - sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id); - } + if (delete_subs) { + if (multi_reg_contact) { + sql = + switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q' and contact='%q'", to_user, sub_host, contact_str); + } else { + sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id); + } - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); -#endif + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } if (multi_reg_contact) { sql = @@ -1312,11 +1325,11 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_safe_free(icontact); } else { -#ifdef DEL_SUBS - if ((sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host))) { - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + if (delete_subs) { + if ((sql = switch_mprintf("delete from sip_subscriptions where sip_user='%q' and sip_host='%q'", to_user, sub_host))) { + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } } -#endif if ((sql = switch_mprintf("delete from sip_registrations where sip_user='%q' and sip_host='%q'", to_user, reg_host))) { sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } @@ -2110,7 +2123,8 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (auth_acl) { if (!switch_check_network_list_ip(ip, auth_acl)) { - int network_ip_is_proxy = 0, x = 0; + int network_ip_is_proxy = 0; + uint32_t x = 0; char *last_acl = NULL; if (profile->proxy_acl_count == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by user acl [%s] and no proxy acl present\n", ip, auth_acl); @@ -2207,7 +2221,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, if (max_registrations_perext > 0 && (sip && sip->sip_contact && (sip->sip_contact->m_expires == NULL || atol(sip->sip_contact->m_expires) > 0))) { /* if expires is null still process */ /* expires == 0 means the phone is going to unregiser, so don't count against max */ - int count = 0; + uint32_t count = 0; call_id = sip->sip_call_id->i_id; switch_assert(call_id); @@ -2292,9 +2306,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "mwi-account", mwi_account); } - if ((uparams = switch_xml_child(user, "params"))) { + if ((dparams = switch_xml_child(domain, "params"))) { xparams_type[i] = 0; - xparams[i++] = uparams; + xparams[i++] = dparams; } if (group && (gparams = switch_xml_child(group, "params"))) { @@ -2302,102 +2316,98 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, xparams[i++] = gparams; } - if ((dparams = switch_xml_child(domain, "params"))) { + if ((uparams = switch_xml_child(user, "params"))) { xparams_type[i] = 0; - xparams[i++] = dparams; - } - - if ((uparams = switch_xml_child(user, "variables"))) { - xparams_type[i] = 1; xparams[i++] = uparams; } - if (group && (gparams = switch_xml_child(group, "variables"))) { - xparams_type[i] = 1; - xparams[i++] = gparams; - } - if ((dparams = switch_xml_child(domain, "variables"))) { xparams_type[i] = 1; xparams[i++] = dparams; } + if (group && (gparams = switch_xml_child(group, "variables"))) { + xparams_type[i] = 1; + xparams[i++] = gparams; + } + + if ((uparams = switch_xml_child(user, "variables"))) { + xparams_type[i] = 1; + xparams[i++] = uparams; + } + if (i <= 6) { int j = 0; + const char *gw_val = NULL; for (j = 0; j < i; j++) { for (param = switch_xml_child(xparams[j], (xparams_type[j] ? "variable" : "param")); param; param = param->next) { const char *var = switch_xml_attr_soft(param, "name"); const char *val = switch_xml_attr_soft(param, "value"); - sofia_gateway_t *gateway_ptr = NULL; if (!zstr(var) && !zstr(val) && (xparams_type[j] == 1 || !strncasecmp(var, "sip-", 4) || !strcasecmp(var, "register-gateway"))) { - if (!switch_event_get_header(*v_event, var)) { - if (profile->debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event_add_header -> '%s' = '%s'\n", var, val); - } - switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, var, val); - } else { - continue; + if (profile->debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event_add_header -> '%s' = '%s'\n", var, val); } - - if (!strcasecmp(var, "register-gateway")) { - if (!strcasecmp(val, "all")) { - switch_xml_t gateways_tag, gateway_tag; - if ((gateways_tag = switch_xml_child(user, "gateways"))) { - for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) { - char *name = (char *) switch_xml_attr_soft(gateway_tag, "name"); - if (zstr(name)) { - name = "anonymous"; - } - - if ((gateway_ptr = sofia_reg_find_gateway(name))) { - reg_state_t ostate = gateway_ptr->state; - gateway_ptr->retry = 0; - if (exptime) { - gateway_ptr->state = REG_STATE_UNREGED; - } else { - gateway_ptr->state = REG_STATE_UNREGISTER; - } - if (ostate != gateway_ptr->state) { - sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL); - } - sofia_reg_release_gateway(gateway_ptr); - } - - } - } - } else { - int x, argc; - char *mydata, *argv[50]; - - mydata = strdup(val); - switch_assert(mydata != NULL); - - argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))); - - for (x = 0; x < argc; x++) { - if ((gateway_ptr = sofia_reg_find_gateway((char *) argv[x]))) { - reg_state_t ostate = gateway_ptr->state; - gateway_ptr->retry = 0; - if (exptime) { - gateway_ptr->state = REG_STATE_UNREGED; - } else { - gateway_ptr->state = REG_STATE_UNREGISTER; - } - if (ostate != gateway_ptr->state) { - sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL); - } - sofia_reg_release_gateway(gateway_ptr); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Gateway '%s' not found.\n", argv[x]); - } - } - - free(mydata); + switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, var, val); + } + } + } + if ((gw_val = switch_event_get_header(*v_event, "register-gateway"))) { + sofia_gateway_t *gateway_ptr = NULL; + if (!strcasecmp(gw_val, "all")) { + switch_xml_t gateways_tag, gateway_tag; + if ((gateways_tag = switch_xml_child(user, "gateways"))) { + for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) { + char *name = (char *) switch_xml_attr_soft(gateway_tag, "name"); + if (zstr(name)) { + name = "anonymous"; } + + if ((gateway_ptr = sofia_reg_find_gateway(name))) { + reg_state_t ostate = gateway_ptr->state; + gateway_ptr->retry = 0; + if (exptime) { + gateway_ptr->state = REG_STATE_UNREGED; + } else { + gateway_ptr->state = REG_STATE_UNREGISTER; + } + if (ostate != gateway_ptr->state) { + sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL); + } + sofia_reg_release_gateway(gateway_ptr); + } + } } + } else { + int x, argc; + char *mydata, *argv[50]; + + mydata = strdup(gw_val); + switch_assert(mydata != NULL); + + argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + + for (x = 0; x < argc; x++) { + if ((gateway_ptr = sofia_reg_find_gateway((char *) argv[x]))) { + reg_state_t ostate = gateway_ptr->state; + gateway_ptr->retry = 0; + if (exptime) { + gateway_ptr->state = REG_STATE_UNREGED; + } else { + gateway_ptr->state = REG_STATE_UNREGISTER; + } + if (ostate != gateway_ptr->state) { + sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL); + } + sofia_reg_release_gateway(gateway_ptr); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Gateway '%s' not found.\n", argv[x]); + } + } + + free(mydata); } } } @@ -2486,7 +2496,7 @@ sofia_gateway_t *sofia_reg_find_gateway_by_realm__(const char *file, const char switch_mutex_lock(mod_sofia_globals.hash_mutex); for (hi = switch_hash_first(NULL, mod_sofia_globals.gateway_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); - if ((gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) { + if (key && (gateway = (sofia_gateway_t *) val) && gateway->register_realm && !strcasecmp(gateway->register_realm, key)) { break; } else { gateway = NULL; diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index d3fa2e8a45..97f20b867a 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -1100,7 +1100,7 @@ static int web_callback(void *pArg, int argc, char **argv, char **columnNames) { struct holder *holder = (struct holder *) pArg; char title_b4[128] = ""; - char title_aft[128 * 3] = ""; + char title_aft[128 * 3 + 1] = ""; char *mp3, *m3u; /* diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java index 2b9353c063..e7bcb56834 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java @@ -213,12 +213,12 @@ public class CoreSession { return freeswitchJNI.CoreSession_transfer(swigCPtr, this, extension, dialplan, context); } - public String read(int min_digits, int max_digits, String prompt_audio_file, int timeout, String valid_terminators) { - return freeswitchJNI.CoreSession_read(swigCPtr, this, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators); + public String read(int min_digits, int max_digits, String prompt_audio_file, int timeout, String valid_terminators, int digit_timeout) { + return freeswitchJNI.CoreSession_read(swigCPtr, this, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout); } - public String playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, String terminators, String audio_files, String bad_input_audio_files, String digits_regex, String var_name) { - return freeswitchJNI.CoreSession_playAndGetDigits(swigCPtr, this, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name); + public String playAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, String terminators, String audio_files, String bad_input_audio_files, String digits_regex, String var_name, int digit_timeout) { + return freeswitchJNI.CoreSession_playAndGetDigits(swigCPtr, this, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout); } public int streamFile(String file, int starting_sample_count) { diff --git a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java index 541777840b..206103c4be 100644 --- a/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java +++ b/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java @@ -125,8 +125,8 @@ class freeswitchJNI { public final static native String CoreSession_getDigits__SWIG_0(long jarg1, CoreSession jarg1_, int jarg2, String jarg3, int jarg4); public final static native String CoreSession_getDigits__SWIG_1(long jarg1, CoreSession jarg1_, int jarg2, String jarg3, int jarg4, int jarg5); public final static native int CoreSession_transfer(long jarg1, CoreSession jarg1_, String jarg2, String jarg3, String jarg4); - public final static native String CoreSession_read(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, String jarg4, int jarg5, String jarg6); - public final static native String CoreSession_playAndGetDigits(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, int jarg4, int jarg5, String jarg6, String jarg7, String jarg8, String jarg9, String jarg10); + public final static native String CoreSession_read(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, String jarg4, int jarg5, String jarg6, int jarg7); + public final static native String CoreSession_playAndGetDigits(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, int jarg4, int jarg5, String jarg6, String jarg7, String jarg8, String jarg9, String jarg10, int jarg11); public final static native int CoreSession_streamFile(long jarg1, CoreSession jarg1_, String jarg2, int jarg3); public final static native int CoreSession_sleep(long jarg1, CoreSession jarg1_, int jarg2, int jarg3); public final static native int CoreSession_flushEvents(long jarg1, CoreSession jarg1_); diff --git a/src/mod/languages/mod_java/switch_swig_wrap.cpp b/src/mod/languages/mod_java/switch_swig_wrap.cpp index fc9d6c4681..b275b170d6 100644 --- a/src/mod/languages/mod_java/switch_swig_wrap.cpp +++ b/src/mod/languages/mod_java/switch_swig_wrap.cpp @@ -2405,7 +2405,7 @@ SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1tran } -SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1read(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jstring jarg4, jint jarg5, jstring jarg6) { +SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1read(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jstring jarg4, jint jarg5, jstring jarg6, jint jarg7) { jstring jresult = 0 ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -2413,6 +2413,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; (void)jenv; @@ -2432,7 +2433,8 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r arg6 = (char *)jenv->GetStringUTFChars(jarg6, 0); if (!arg6) return 0; } - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + arg7 = (int)jarg7; + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); if(result) jresult = jenv->NewStringUTF((const char *)result); if (arg4) jenv->ReleaseStringUTFChars(jarg4, (const char *)arg4); if (arg6) jenv->ReleaseStringUTFChars(jarg6, (const char *)arg6); @@ -2440,7 +2442,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1r } -SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1playAndGetDigits(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jint jarg4, jint jarg5, jstring jarg6, jstring jarg7, jstring jarg8, jstring jarg9, jstring jarg10) { +SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1playAndGetDigits(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3, jint jarg4, jint jarg5, jstring jarg6, jstring jarg7, jstring jarg8, jstring jarg9, jstring jarg10, jint jarg11) { jstring jresult = 0 ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -2452,6 +2454,7 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1p char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; (void)jenv; @@ -2487,7 +2490,8 @@ SWIGEXPORT jstring JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1p arg10 = (char *)jenv->GetStringUTFChars(jarg10, 0); if (!arg10) return 0; } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + arg11 = (int)jarg11; + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); if(result) jresult = jenv->NewStringUTF((const char *)result); if (arg6) jenv->ReleaseStringUTFChars(jarg6, (const char *)arg6); if (arg7) jenv->ReleaseStringUTFChars(jarg7, (const char *)arg7); diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index 383580103f..54bdb7bdc9 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -19,8 +19,15 @@ /* Lua function typemap */ -%typemap(in,checkfn="lua_isfunction") SWIGLUA_FN -%{ $1.L=L; $1.idx=$input; %} +%typemap(in, checkfn = "lua_isfunction") SWIGLUA_FN { + $1.L = L; + $1.idx = $input; +} + +%typemap(default) SWIGLUA_FN { + SWIGLUA_FN default_swiglua_fn = { 0 }; + $1 = default_swiglua_fn; +} %ignore SwitchToMempool; diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 17d12bc1cb..d60ae737a8 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -367,10 +367,15 @@ int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv) bool Dbh::query(char *sql, SWIGLUA_FN lua_fun) { if (connected) { - if (switch_cache_db_execute_sql_callback(dbh, sql, query_callback, &lua_fun, NULL) == SWITCH_STATUS_SUCCESS) { - return true; + if (lua_fun.L) { + if (switch_cache_db_execute_sql_callback(dbh, sql, query_callback, &lua_fun, NULL) == SWITCH_STATUS_SUCCESS) { + return true; + } + } else { /* if no lua_fun arg is passed from Lua, an empty initialized struct will be sent - see freeswitch.i */ + if (switch_cache_db_execute_sql(dbh, sql, NULL) == SWITCH_STATUS_SUCCESS) { + return true; + } } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no workie workie :(\n"); return false; } diff --git a/src/mod/languages/mod_lua/mod_lua.cpp b/src/mod/languages/mod_lua/mod_lua.cpp index 3ccbef5aaa..cf9b373ce0 100644 --- a/src/mod/languages/mod_lua/mod_lua.cpp +++ b/src/mod/languages/mod_lua/mod_lua.cpp @@ -588,7 +588,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load) SWITCH_ADD_API(api_interface, "luarun", "run a script", luarun_api_function, "<script>"); SWITCH_ADD_API(api_interface, "lua", "run a script as an api function", lua_api_function, "<script>"); - SWITCH_ADD_APP(app_interface, "lua", "Launch LUA ivr", "Run a lua ivr on a channel", lua_function, "<script>", SAF_SUPPORT_NOMEDIA); + SWITCH_ADD_APP(app_interface, "lua", "Launch LUA ivr", "Run a lua ivr on a channel", lua_function, "<script>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); SWITCH_ADD_DIALPLAN(dp_interface, "LUA", lua_dialplan_hunt); diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 991b667a62..5c189cd288 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -5175,15 +5175,17 @@ static int _wrap_CoreSession_read(lua_State* L) { char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; - SWIG_check_num_args("read",6,6) + SWIG_check_num_args("read",6,7) if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("read",1,"CoreSession *"); if(!lua_isnumber(L,2)) SWIG_fail_arg("read",2,"int"); if(!lua_isnumber(L,3)) SWIG_fail_arg("read",3,"int"); if(!lua_isstring(L,4)) SWIG_fail_arg("read",4,"char const *"); if(!lua_isnumber(L,5)) SWIG_fail_arg("read",5,"int"); if(!lua_isstring(L,6)) SWIG_fail_arg("read",6,"char const *"); + if(lua_gettop(L)>=7 && !lua_isnumber(L,7)) SWIG_fail_arg("read",7,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){ SWIG_fail_ptr("CoreSession_read",1,SWIGTYPE_p_CoreSession); @@ -5194,7 +5196,10 @@ static int _wrap_CoreSession_read(lua_State* L) { arg4 = (char *)lua_tostring(L, 4); arg5 = (int)lua_tonumber(L, 5); arg6 = (char *)lua_tostring(L, 6); - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + if(lua_gettop(L)>=7){ + arg7 = (int)lua_tonumber(L, 7); + } + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); SWIG_arg=0; lua_pushstring(L,(const char*)result); SWIG_arg++; return SWIG_arg; @@ -5219,9 +5224,10 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) { char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; - SWIG_check_num_args("playAndGetDigits",9,10) + SWIG_check_num_args("playAndGetDigits",9,11) if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("playAndGetDigits",1,"CoreSession *"); if(!lua_isnumber(L,2)) SWIG_fail_arg("playAndGetDigits",2,"int"); if(!lua_isnumber(L,3)) SWIG_fail_arg("playAndGetDigits",3,"int"); @@ -5232,6 +5238,7 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) { if(!lua_isstring(L,8)) SWIG_fail_arg("playAndGetDigits",8,"char *"); if(!lua_isstring(L,9)) SWIG_fail_arg("playAndGetDigits",9,"char *"); if(lua_gettop(L)>=10 && !lua_isstring(L,10)) SWIG_fail_arg("playAndGetDigits",10,"char const *"); + if(lua_gettop(L)>=11 && !lua_isnumber(L,11)) SWIG_fail_arg("playAndGetDigits",11,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){ SWIG_fail_ptr("CoreSession_playAndGetDigits",1,SWIGTYPE_p_CoreSession); @@ -5248,7 +5255,10 @@ static int _wrap_CoreSession_playAndGetDigits(lua_State* L) { if(lua_gettop(L)>=10){ arg10 = (char *)lua_tostring(L, 10); } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + if(lua_gettop(L)>=11){ + arg11 = (int)lua_tonumber(L, 11); + } + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); SWIG_arg=0; lua_pushstring(L,(const char*)result); SWIG_arg++; return SWIG_arg; @@ -7191,17 +7201,28 @@ static int _wrap_Dbh_query(lua_State* L) { SWIGLUA_FN arg3 ; bool result; - SWIG_check_num_args("query",3,3) + { + SWIGLUA_FN default_swiglua_fn = { + 0 + }; + arg3 = default_swiglua_fn; + } + SWIG_check_num_args("query",2,3) if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("query",1,"LUA::Dbh *"); if(!lua_isstring(L,2)) SWIG_fail_arg("query",2,"char *"); - if(!lua_isfunction(L,3)) SWIG_fail_arg("query",3,"SWIGLUA_FN"); + if(lua_gettop(L)>=3 && !lua_isfunction(L,3)) SWIG_fail_arg("query",3,"SWIGLUA_FN"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ SWIG_fail_ptr("Dbh_query",1,SWIGTYPE_p_LUA__Dbh); } arg2 = (char *)lua_tostring(L, 2); - (&arg3)->L=L; (&arg3)->idx=3; + if(lua_gettop(L)>=3){ + { + (&arg3)->L = L; + (&arg3)->idx = 3; + } + } result = (bool)(arg1)->query(arg2,arg3); SWIG_arg=0; lua_pushboolean(L,(int)(result==true)); SWIG_arg++; diff --git a/src/mod/languages/mod_managed/freeswitch.i b/src/mod/languages/mod_managed/freeswitch.i index 969839722a..ffbdf9be0f 100644 --- a/src/mod/languages/mod_managed/freeswitch.i +++ b/src/mod/languages/mod_managed/freeswitch.i @@ -193,7 +193,10 @@ char * SWIG_csharp_string_callback(const char * str) { %include switch_core_db.h %include switch_regex.h %include switch_core.h -//%include switch_loadable_module.h // todo: Sort out some linking issues +%ignore switch_module_runtime; +%ignore switch_module_load; +%ignore switch_module_shutdown; +%include switch_loadable_module.h // note: Above three ignore lines sort out some linking issues %include switch_console.h // Has unsupported varargs functions %include switch_utils.h %include switch_caller.h diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 908a851e5a..ade6bf8d8f 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -2813,6 +2813,68 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_rtp_numbers_t(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_numbers_t_packet_count_set(void * jarg1, unsigned long jarg2) { + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->packet_count = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_rtcp_numbers_t_packet_count_get(void * jarg1) { + unsigned long jresult ; + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t result; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + result = (uint32_t) ((arg1)->packet_count); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_numbers_t_octet_count_set(void * jarg1, unsigned long jarg2) { + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->octet_count = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_rtcp_numbers_t_octet_count_get(void * jarg1) { + unsigned long jresult ; + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t result; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + result = (uint32_t) ((arg1)->octet_count); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_rtcp_numbers_t() { + void * jresult ; + switch_rtcp_numbers_t *result = 0 ; + + result = (switch_rtcp_numbers_t *)new switch_rtcp_numbers_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_rtcp_numbers_t(void * jarg1) { + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_stats_t_inbound_set(void * jarg1, void * jarg2) { switch_rtp_stats_t *arg1 = (switch_rtp_stats_t *) 0 ; switch_rtp_numbers_t *arg2 = (switch_rtp_numbers_t *) 0 ; @@ -2857,6 +2919,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_stats_t_outbound_get(void * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_stats_t_rtcp_set(void * jarg1, void * jarg2) { + switch_rtp_stats_t *arg1 = (switch_rtp_stats_t *) 0 ; + switch_rtcp_numbers_t *arg2 = (switch_rtcp_numbers_t *) 0 ; + + arg1 = (switch_rtp_stats_t *)jarg1; + arg2 = (switch_rtcp_numbers_t *)jarg2; + if (arg1) (arg1)->rtcp = *arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_stats_t_rtcp_get(void * jarg1) { + void * jresult ; + switch_rtp_stats_t *arg1 = (switch_rtp_stats_t *) 0 ; + switch_rtcp_numbers_t *result = 0 ; + + arg1 = (switch_rtp_stats_t *)jarg1; + result = (switch_rtcp_numbers_t *)& ((arg1)->rtcp); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_rtp_stats_t() { void * jresult ; switch_rtp_stats_t *result = 0 ; @@ -3499,24 +3583,24 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_remote_ip_get(void * j } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->remote_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->remote_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->remote_port); + jresult = result; return jresult; } @@ -3550,24 +3634,24 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_local_ip_get(void * ja } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->local_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->local_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->local_port); + jresult = result; return jresult; } @@ -7788,7 +7872,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_timer_destroy(void * jarg1) { } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, void * jarg8, void * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init_with_bitrate(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, unsigned long jarg8, void * jarg9, void * jarg10) { int jresult ; switch_codec_t *arg1 = (switch_codec_t *) 0 ; char *arg2 = (char *) 0 ; @@ -7797,8 +7881,9 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja int arg5 ; int arg6 ; uint32_t arg7 ; - switch_codec_settings_t *arg8 = (switch_codec_settings_t *) 0 ; - switch_memory_pool_t *arg9 = (switch_memory_pool_t *) 0 ; + uint32_t arg8 ; + switch_codec_settings_t *arg9 = (switch_codec_settings_t *) 0 ; + switch_memory_pool_t *arg10 = (switch_memory_pool_t *) 0 ; switch_status_t result; arg1 = (switch_codec_t *)jarg1; @@ -7808,9 +7893,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (uint32_t)jarg7; - arg8 = (switch_codec_settings_t *)jarg8; - arg9 = (switch_memory_pool_t *)jarg9; - result = (switch_status_t)switch_core_codec_init(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,(switch_codec_settings const *)arg8,arg9); + arg8 = (uint32_t)jarg8; + arg9 = (switch_codec_settings_t *)jarg9; + arg10 = (switch_memory_pool_t *)jarg10; + result = (switch_status_t)switch_core_codec_init_with_bitrate(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,arg8,(switch_codec_settings const *)arg9,arg10); jresult = result; return jresult; } @@ -10097,6 +10183,840 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_in_thread(void * jarg1) { } +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 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->module_name = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->module_name, (const char *)arg2); + } else { + arg1->module_name = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_get(void * jarg1) { + char * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + char *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (char *) ((arg1)->module_name); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_endpoint_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_endpoint_interface_t *arg2 = (switch_endpoint_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_endpoint_interface_t *)jarg2; + if (arg1) (arg1)->endpoint_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_endpoint_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_endpoint_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_endpoint_interface_t *) ((arg1)->endpoint_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_timer_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_timer_interface_t *arg2 = (switch_timer_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_timer_interface_t *)jarg2; + if (arg1) (arg1)->timer_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_timer_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_timer_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_timer_interface_t *) ((arg1)->timer_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_dialplan_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_dialplan_interface_t *arg2 = (switch_dialplan_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_dialplan_interface_t *)jarg2; + if (arg1) (arg1)->dialplan_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_dialplan_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_dialplan_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_dialplan_interface_t *) ((arg1)->dialplan_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_codec_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_codec_interface_t *)jarg2; + if (arg1) (arg1)->codec_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_codec_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_codec_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_codec_interface_t *) ((arg1)->codec_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_application_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_application_interface_t *arg2 = (switch_application_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_application_interface_t *)jarg2; + if (arg1) (arg1)->application_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_application_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_application_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_application_interface_t *) ((arg1)->application_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_api_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_api_interface_t *arg2 = (switch_api_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_api_interface_t *)jarg2; + if (arg1) (arg1)->api_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_api_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_api_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_api_interface_t *) ((arg1)->api_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_file_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_file_interface_t *arg2 = (switch_file_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_file_interface_t *)jarg2; + if (arg1) (arg1)->file_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_file_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_file_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_file_interface_t *) ((arg1)->file_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_speech_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_speech_interface_t *arg2 = (switch_speech_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_speech_interface_t *)jarg2; + if (arg1) (arg1)->speech_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_speech_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_speech_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_speech_interface_t *) ((arg1)->speech_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_directory_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_directory_interface_t *arg2 = (switch_directory_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_directory_interface_t *)jarg2; + if (arg1) (arg1)->directory_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_directory_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_directory_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_directory_interface_t *) ((arg1)->directory_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_chat_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_chat_interface_t *arg2 = (switch_chat_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_chat_interface_t *)jarg2; + if (arg1) (arg1)->chat_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_chat_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_chat_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_chat_interface_t *) ((arg1)->chat_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_say_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_say_interface_t *arg2 = (switch_say_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_say_interface_t *)jarg2; + if (arg1) (arg1)->say_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_say_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_say_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_say_interface_t *) ((arg1)->say_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_asr_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_asr_interface_t *arg2 = (switch_asr_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_asr_interface_t *)jarg2; + if (arg1) (arg1)->asr_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_asr_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_asr_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_asr_interface_t *) ((arg1)->asr_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_management_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_management_interface_t *arg2 = (switch_management_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_management_interface_t *)jarg2; + if (arg1) (arg1)->management_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_management_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_management_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_management_interface_t *) ((arg1)->management_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_limit_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_limit_interface_t *arg2 = (switch_limit_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_limit_interface_t *)jarg2; + if (arg1) (arg1)->limit_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_limit_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_limit_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_limit_interface_t *) ((arg1)->limit_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_rwlock_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_thread_rwlock_t *arg2 = (switch_thread_rwlock_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_thread_rwlock_t *)jarg2; + if (arg1) (arg1)->rwlock = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_rwlock_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_thread_rwlock_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_thread_rwlock_t *) ((arg1)->rwlock); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_refs_set(void * jarg1, int jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + int arg2 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->refs = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_interface_refs_get(void * jarg1) { + int jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + int result; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (int) ((arg1)->refs); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_pool_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_memory_pool_t *arg2 = (switch_memory_pool_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_memory_pool_t *)jarg2; + if (arg1) (arg1)->pool = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_pool_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_memory_pool_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_memory_pool_t *) ((arg1)->pool); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_loadable_module_interface() { + void * jresult ; + switch_loadable_module_interface *result = 0 ; + + result = (switch_loadable_module_interface *)new switch_loadable_module_interface(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_loadable_module_interface(void * jarg1) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + delete arg1; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_init(int jarg1) { + int jresult ; + switch_bool_t arg1 ; + switch_status_t result; + + arg1 = (switch_bool_t)jarg1; + result = (switch_status_t)switch_loadable_module_init(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_shutdown() { + switch_loadable_module_shutdown(); +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_endpoint_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_endpoint_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_endpoint_interface_t *)switch_loadable_module_get_endpoint_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_codec_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_codec_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_codec_interface_t *)switch_loadable_module_get_codec_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_dialplan_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_dialplan_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_dialplan_interface_t *)switch_loadable_module_get_dialplan_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_enumerate_available(char * jarg1, void * jarg2, void * jarg3) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_modulename_callback_func_t arg2 = (switch_modulename_callback_func_t) 0 ; + void *arg3 = (void *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_modulename_callback_func_t)jarg2; + arg3 = (void *)jarg3; + result = (switch_status_t)switch_loadable_module_enumerate_available((char const *)arg1,arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_enumerate_loaded(void * jarg1, void * jarg2) { + int jresult ; + switch_modulename_callback_func_t arg1 = (switch_modulename_callback_func_t) 0 ; + void *arg2 = (void *) 0 ; + switch_status_t result; + + arg1 = (switch_modulename_callback_func_t)jarg1; + arg2 = (void *)jarg2; + result = (switch_status_t)switch_loadable_module_enumerate_loaded(arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_build_dynamic(char * jarg1, void * jarg2, void * jarg3, void * jarg4, int jarg5) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_module_load_t arg2 = (switch_module_load_t) 0 ; + switch_module_runtime_t arg3 = (switch_module_runtime_t) 0 ; + switch_module_shutdown_t arg4 = (switch_module_shutdown_t) 0 ; + switch_bool_t arg5 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_module_load_t)jarg2; + arg3 = (switch_module_runtime_t)jarg3; + arg4 = (switch_module_shutdown_t)jarg4; + arg5 = (switch_bool_t)jarg5; + result = (switch_status_t)switch_loadable_module_build_dynamic(arg1,arg2,arg3,arg4,arg5); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_timer_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_timer_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_timer_interface_t *)switch_loadable_module_get_timer_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_application_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_application_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_application_interface_t *)switch_loadable_module_get_application_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_api_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_api_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_api_interface_t *)switch_loadable_module_get_api_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_file_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_file_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_file_interface_t *)switch_loadable_module_get_file_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_speech_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_speech_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_speech_interface_t *)switch_loadable_module_get_speech_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_asr_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_asr_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_asr_interface_t *)switch_loadable_module_get_asr_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_directory_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_directory_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_directory_interface_t *)switch_loadable_module_get_directory_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_chat_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_chat_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_chat_interface_t *)switch_loadable_module_get_chat_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_say_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_say_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_say_interface_t *)switch_loadable_module_get_say_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_management_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_management_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_management_interface_t *)switch_loadable_module_get_management_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_limit_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_limit_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_limit_interface_t *)switch_loadable_module_get_limit_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_get_codecs(void * jarg1, int jarg2) { + int jresult ; + switch_codec_implementation_t **arg1 = (switch_codec_implementation_t **) 0 ; + int arg2 ; + int result; + + arg1 = (switch_codec_implementation_t **)jarg1; + arg2 = (int)jarg2; + result = (int)switch_loadable_module_get_codecs((switch_codec_implementation const **)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_get_codecs_sorted(void * jarg1, int jarg2, void * jarg3, int jarg4) { + int jresult ; + switch_codec_implementation_t **arg1 = (switch_codec_implementation_t **) 0 ; + int arg2 ; + char **arg3 = (char **) 0 ; + int arg4 ; + int result; + + arg1 = (switch_codec_implementation_t **)jarg1; + arg2 = (int)jarg2; + arg3 = (char **)jarg3; + arg4 = (int)jarg4; + result = (int)switch_loadable_module_get_codecs_sorted((switch_codec_implementation const **)arg1,arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_api_execute(char * jarg1, char * jarg2, void * jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_core_session_t *arg3 = (switch_core_session_t *) 0 ; + switch_stream_handle_t *arg4 = (switch_stream_handle_t *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_core_session_t *)jarg3; + arg4 = (switch_stream_handle_t *)jarg4; + result = (switch_status_t)switch_api_execute((char const *)arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_load_module(char * jarg1, char * jarg2, int jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t arg3 ; + char **arg4 = (char **) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_bool_t)jarg3; + arg4 = (char **)jarg4; + result = (switch_status_t)switch_loadable_module_load_module(arg1,arg2,arg3,(char const **)arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_exists(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + result = (switch_status_t)switch_loadable_module_exists((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_unload_module(char * jarg1, char * jarg2, int jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t arg3 ; + char **arg4 = (char **) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_bool_t)jarg3; + arg4 = (char **)jarg4; + result = (switch_status_t)switch_loadable_module_unload_module(arg1,arg2,arg3,(char const **)arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_codec_next_id() { + unsigned long jresult ; + uint32_t result; + + result = (uint32_t)switch_core_codec_next_id(); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_check_interval(unsigned long jarg1, unsigned long jarg2) { + int jresult ; + uint32_t arg1 ; + uint32_t arg2 ; + int result; + + arg1 = (uint32_t)jarg1; + arg2 = (uint32_t)jarg2; + result = (int)switch_check_interval(arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_codec_add_implementation(void * jarg1, void * jarg2, int jarg3, unsigned char jarg4, char * jarg5, char * jarg6, unsigned long jarg7, unsigned long jarg8, int jarg9, int jarg10, unsigned long jarg11, unsigned long jarg12, unsigned long jarg13, unsigned char jarg14, int jarg15, void * jarg16, void * jarg17, void * jarg18, void * jarg19) { + switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; + switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; + switch_codec_type_t arg3 ; + switch_payload_t arg4 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + uint32_t arg7 ; + uint32_t arg8 ; + int arg9 ; + int arg10 ; + uint32_t arg11 ; + uint32_t arg12 ; + uint32_t arg13 ; + uint8_t arg14 ; + int arg15 ; + switch_core_codec_init_func_t arg16 = (switch_core_codec_init_func_t) 0 ; + switch_core_codec_encode_func_t arg17 = (switch_core_codec_encode_func_t) 0 ; + switch_core_codec_decode_func_t arg18 = (switch_core_codec_decode_func_t) 0 ; + switch_core_codec_destroy_func_t arg19 = (switch_core_codec_destroy_func_t) 0 ; + + arg1 = (switch_memory_pool_t *)jarg1; + arg2 = (switch_codec_interface_t *)jarg2; + arg3 = (switch_codec_type_t)jarg3; + arg4 = (switch_payload_t)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (uint32_t)jarg7; + arg8 = (uint32_t)jarg8; + arg9 = (int)jarg9; + arg10 = (int)jarg10; + arg11 = (uint32_t)jarg11; + arg12 = (uint32_t)jarg12; + arg13 = (uint32_t)jarg13; + arg14 = (uint8_t)jarg14; + arg15 = (int)jarg15; + arg16 = (switch_core_codec_init_func_t)jarg16; + arg17 = (switch_core_codec_encode_func_t)jarg17; + arg18 = (switch_core_codec_decode_func_t)jarg18; + arg19 = (switch_core_codec_destroy_func_t)jarg19; + switch_core_codec_add_implementation(arg1,arg2,arg3,arg4,(char const *)arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16,arg17,arg18,arg19); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_ready(void * jarg1) { + int jresult ; + switch_codec_t *arg1 = (switch_codec_t *) 0 ; + switch_bool_t result; + + arg1 = (switch_codec_t *)jarg1; + result = (switch_bool_t)switch_core_codec_ready(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_CMD_CHUNK_LEN_get() { int jresult ; int result; @@ -10873,6 +11793,20 @@ SWIGEXPORT unsigned char SWIGSTDCALL CSharp_switch_char_to_rfc2833(char jarg1) { } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_default_ptime(char * jarg1, unsigned long jarg2) { + unsigned long jresult ; + char *arg1 = (char *) 0 ; + uint32_t arg2 ; + uint32_t result; + + arg1 = (char *)jarg1; + arg2 = (uint32_t)jarg2; + result = (uint32_t)switch_default_ptime((char const *)arg1,arg2); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_sanitize_number(char * jarg1) { char * jresult ; char *arg1 = (char *) 0 ; @@ -11479,6 +12413,44 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_network_list_validate_ip_token(void * j } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_dow_int2str(int jarg1) { + char * jresult ; + int arg1 ; + char *result = 0 ; + + arg1 = (int)jarg1; + result = (char *)switch_dow_int2str(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dow_str2int(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_dow_str2int((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dow_cmp(char * jarg1, int jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + int arg2 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (int)jarg2; + result = (int)switch_dow_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_number_cmp(char * jarg1, int jarg2) { int jresult ; char *arg1 = (char *) 0 ; @@ -11493,6 +12465,62 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_number_cmp(char * jarg1, int jarg2) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_tod_cmp(char * jarg1, int jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + int arg2 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (int)jarg2; + result = (int)switch_tod_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_fulldate_cmp(char * jarg1, void * jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_time_t *arg2 = (switch_time_t *) 0 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (switch_time_t *)jarg2; + result = (int)switch_fulldate_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_split_date(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { + char *arg1 = (char *) 0 ; + int *arg2 = (int *) 0 ; + int *arg3 = (int *) 0 ; + int *arg4 = (int *) 0 ; + + arg1 = (char *)jarg1; + arg2 = (int *)jarg2; + arg3 = (int *)jarg3; + arg4 = (int *)jarg4; + switch_split_date((char const *)arg1,arg2,arg3,arg4); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_split_time(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { + char *arg1 = (char *) 0 ; + int *arg2 = (int *) 0 ; + int *arg3 = (int *) 0 ; + int *arg4 = (int *) 0 ; + + arg1 = (char *)jarg1; + arg2 = (int *)jarg2; + arg3 = (int *)jarg3; + arg4 = (int *)jarg4; + switch_split_time((char const *)arg1,arg2,arg3,arg4); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_split_user_domain(char * jarg1, void * jarg2, void * jarg3) { int jresult ; char *arg1 = (char *) 0 ; @@ -12218,6 +13246,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_originatee_caller_pro } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_origination_caller_profile_set(void * jarg1, void * jarg2) { + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_caller_profile *arg2 = (switch_caller_profile *) 0 ; + + arg1 = (switch_caller_profile *)jarg1; + arg2 = (switch_caller_profile *)jarg2; + if (arg1) (arg1)->origination_caller_profile = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_origination_caller_profile_get(void * jarg1) { + void * jresult ; + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_caller_profile *result = 0 ; + + arg1 = (switch_caller_profile *)jarg1; + result = (switch_caller_profile *) ((arg1)->origination_caller_profile); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_hunt_caller_profile_set(void * jarg1, void * jarg2) { switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; switch_caller_profile *arg2 = (switch_caller_profile *) 0 ; @@ -18943,353 +19993,23 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_directory_handle(void * jarg1) } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_quality_set(void * jarg1, int jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_unused_set(void * jarg1, int jarg2) { switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int arg2 ; arg1 = (switch_codec_settings *)jarg1; arg2 = (int)jarg2; - if (arg1) (arg1)->quality = arg2; + if (arg1) (arg1)->unused = arg2; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_quality_get(void * jarg1) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_unused_get(void * jarg1) { int jresult ; switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int result; arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_complexity_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->complexity = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_complexity_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->complexity); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_enhancement_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->enhancement = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_enhancement_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->enhancement); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vad = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vbr = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vbr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vbr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->vbr_quality = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->vbr_quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_abr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->abr = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_abr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->abr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_dtx_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->dtx = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_dtx_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->dtx); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_preproc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->preproc = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_preproc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->preproc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_vad = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_agc = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_agc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_agc_level = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_agc_level); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_denoise = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_denoise); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_dereverb = arg2; -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_dereverb); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_decay = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_decay); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_level = arg2; -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_level); + result = (int) ((arg1)->unused); jresult = result; return jresult; } @@ -19313,6 +20033,112 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_settings(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_set(void * jarg1, unsigned long jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->actual_samples_per_second = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_get(void * jarg1) { + unsigned long jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (uint32_t) ((arg1)->actual_samples_per_second); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->bits_per_second = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->bits_per_second); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->microseconds_per_packet = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->microseconds_per_packet); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_set(void * jarg1, void * jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->private_info = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_get(void * jarg1) { + void * jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *result = 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (void *) ((arg1)->private_info); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec_fmtp() { + void * jresult ; + switch_codec_fmtp *result = 0 ; + + result = (switch_codec_fmtp *)new switch_codec_fmtp(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_fmtp(void * jarg1) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_interface_set(void * jarg1, void * jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; @@ -19417,28 +20243,6 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_codec_fmtp_out_get(void * jarg1) { } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_settings_set(void * jarg1, void * jarg2) { - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *arg2 = (switch_codec_settings_t *) 0 ; - - arg1 = (switch_codec *)jarg1; - arg2 = (switch_codec_settings_t *)jarg2; - if (arg1) (arg1)->codec_settings = *arg2; -} - - -SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_codec_settings_get(void * jarg1) { - void * jresult ; - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *result = 0 ; - - arg1 = (switch_codec *)jarg1; - result = (switch_codec_settings_t *)& ((arg1)->codec_settings); - jresult = (void *)result; - return jresult; -} - - SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_flags_set(void * jarg1, unsigned long jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; uint32_t arg2 ; @@ -20114,6 +20918,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_implementations_get( } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_set(void * jarg1, void * jarg2) { + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t arg2 = (switch_core_codec_fmtp_parse_func_t) 0 ; + + arg1 = (switch_codec_interface *)jarg1; + arg2 = (switch_core_codec_fmtp_parse_func_t)jarg2; + if (arg1) (arg1)->parse_fmtp = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_get(void * jarg1) { + void * jresult ; + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t result; + + arg1 = (switch_codec_interface *)jarg1; + result = (switch_core_codec_fmtp_parse_func_t) ((arg1)->parse_fmtp); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_codec_id_set(void * jarg1, unsigned long jarg2) { switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; uint32_t arg2 ; @@ -21387,6 +22213,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_originatee_caller_profil } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_origination_caller_profile(void * jarg1, void * jarg2) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_caller_profile_t *arg2 = (switch_caller_profile_t *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (switch_caller_profile_t *)jarg2; + switch_channel_set_origination_caller_profile(arg1,arg2); +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_origination_caller_profile(void * jarg1) { + void * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_caller_profile_t *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_caller_profile_t *)switch_channel_get_origination_caller_profile(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_uuid(void * jarg1) { char * jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -25058,7 +25906,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_file(void * jarg1, void * ja } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12, unsigned long jarg13) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -25072,6 +25920,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig char *arg10 = (char *) 0 ; uint32_t arg11 ; char *arg12 = (char *) 0 ; + uint32_t arg13 ; switch_status_t result; arg1 = (switch_core_session_t *)jarg1; @@ -25086,7 +25935,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig arg10 = (char *)jarg10; arg11 = (uint32_t)jarg11; arg12 = (char *)jarg12; - result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12); + arg13 = (uint32_t)jarg13; + result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12,arg13); jresult = result; return jresult; } @@ -25860,7 +26710,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_wait_for_answer(void * jarg1, void } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9, unsigned long jarg10) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -25871,6 +26721,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja switch_size_t arg7 ; uint32_t arg8 ; char *arg9 = (char *) 0 ; + uint32_t arg10 ; switch_size_t *argp7 ; switch_status_t result; @@ -25888,7 +26739,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja arg7 = *argp7; arg8 = (uint32_t)jarg8; arg9 = (char *)jarg9; - result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9); + arg10 = (uint32_t)jarg10; + result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9,arg10); jresult = result; return jresult; } @@ -27095,6 +27947,18 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_stats(void * jarg1, void * j } +SWIGEXPORT unsigned char SWIGSTDCALL CSharp_switch_rtp_check_auto_adj(void * jarg1) { + unsigned char jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_byte_t result; + + arg1 = (switch_rtp_t *)jarg1; + result = (switch_byte_t)switch_rtp_check_auto_adj(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_log_node_t_data_set(void * jarg1, char * jarg2) { switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; char *arg2 = (char *) 0 ; @@ -28171,6 +29035,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_init(void * jarg1, void * jarg2) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_reload(void * jarg1) { + int jresult ; + char **arg1 = (char **) 0 ; + switch_status_t result; + + arg1 = (char **)jarg1; + result = (switch_status_t)switch_xml_reload((char const **)arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_destroy() { int jresult ; switch_status_t result; @@ -31755,7 +32631,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Transfer(void * jarg1, char * jarg } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6, int jarg7) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -31763,6 +32639,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -31771,13 +32648,14 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i arg4 = (char *)jarg4; arg5 = (int)jarg5; arg6 = (char *)jarg6; - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + arg7 = (int)jarg7; + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, int jarg11) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -31789,6 +32667,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -31801,7 +32680,8 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, arg8 = (char *)jarg8; arg9 = (char *)jarg9; arg10 = (char *)jarg10; - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + arg11 = (int)jarg11; + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 1b13352918..b3696899ac 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -2975,6 +2975,71 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_rtp_numbers_t(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_numbers_t_packet_count_set(void * jarg1, unsigned long jarg2) { + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->packet_count = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_rtcp_numbers_t_packet_count_get(void * jarg1) { + unsigned long jresult ; + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t result; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + result = (uint32_t) ((arg1)->packet_count); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_numbers_t_octet_count_set(void * jarg1, unsigned long jarg2) { + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->octet_count = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_rtcp_numbers_t_octet_count_get(void * jarg1) { + unsigned long jresult ; + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + uint32_t result; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + result = (uint32_t) ((arg1)->octet_count); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_rtcp_numbers_t() { + void * jresult ; + switch_rtcp_numbers_t *result = 0 ; + + result = (switch_rtcp_numbers_t *)new switch_rtcp_numbers_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_rtcp_numbers_t(void * jarg1) { + switch_rtcp_numbers_t *arg1 = (switch_rtcp_numbers_t *) 0 ; + + arg1 = (switch_rtcp_numbers_t *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_stats_t_inbound_set(void * jarg1, void * jarg2) { switch_rtp_stats_t *arg1 = (switch_rtp_stats_t *) 0 ; switch_rtp_numbers_t *arg2 = (switch_rtp_numbers_t *) 0 ; @@ -3021,6 +3086,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_stats_t_outbound_get(void * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_stats_t_rtcp_set(void * jarg1, void * jarg2) { + switch_rtp_stats_t *arg1 = (switch_rtp_stats_t *) 0 ; + switch_rtcp_numbers_t *arg2 = (switch_rtcp_numbers_t *) 0 ; + + arg1 = (switch_rtp_stats_t *)jarg1; + arg2 = (switch_rtcp_numbers_t *)jarg2; + if (arg1) (arg1)->rtcp = *arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_stats_t_rtcp_get(void * jarg1) { + void * jresult ; + switch_rtp_stats_t *arg1 = (switch_rtp_stats_t *) 0 ; + switch_rtcp_numbers_t *result = 0 ; + + arg1 = (switch_rtp_stats_t *)jarg1; + result = (switch_rtcp_numbers_t *)& ((arg1)->rtcp); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_rtp_stats_t() { void * jresult ; switch_rtp_stats_t *result = 0 ; @@ -3688,25 +3776,25 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_remote_ip_get(void * j } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->remote_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_remote_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->remote_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->remote_port); + jresult = result; return jresult; } @@ -3740,25 +3828,25 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_t38_options_t_local_ip_get(void * ja } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned long jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_local_port_set(void * jarg1, unsigned short jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t arg2 ; + uint16_t arg2 ; arg1 = (switch_t38_options_t *)jarg1; - arg2 = (uint32_t)jarg2; + arg2 = (uint16_t)jarg2; if (arg1) (arg1)->local_port = arg2; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_local_port_get(void * jarg1) { + unsigned short jresult ; switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; - uint32_t result; + uint16_t result; arg1 = (switch_t38_options_t *)jarg1; - result = (uint32_t) ((arg1)->local_port); - jresult = (unsigned long)result; + result = (uint16_t) ((arg1)->local_port); + jresult = result; return jresult; } @@ -8064,7 +8152,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_timer_destroy(void * jarg1) { } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, void * jarg8, void * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init_with_bitrate(void * jarg1, char * jarg2, char * jarg3, unsigned long jarg4, int jarg5, int jarg6, unsigned long jarg7, unsigned long jarg8, void * jarg9, void * jarg10) { int jresult ; switch_codec_t *arg1 = (switch_codec_t *) 0 ; char *arg2 = (char *) 0 ; @@ -8073,8 +8161,9 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja int arg5 ; int arg6 ; uint32_t arg7 ; - switch_codec_settings_t *arg8 = (switch_codec_settings_t *) 0 ; - switch_memory_pool_t *arg9 = (switch_memory_pool_t *) 0 ; + uint32_t arg8 ; + switch_codec_settings_t *arg9 = (switch_codec_settings_t *) 0 ; + switch_memory_pool_t *arg10 = (switch_memory_pool_t *) 0 ; switch_status_t result; arg1 = (switch_codec_t *)jarg1; @@ -8084,9 +8173,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_init(void * jarg1, char * ja arg5 = (int)jarg5; arg6 = (int)jarg6; arg7 = (uint32_t)jarg7; - arg8 = (switch_codec_settings_t *)jarg8; - arg9 = (switch_memory_pool_t *)jarg9; - result = (switch_status_t)switch_core_codec_init(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,(switch_codec_settings const *)arg8,arg9); + arg8 = (uint32_t)jarg8; + arg9 = (switch_codec_settings_t *)jarg9; + arg10 = (switch_memory_pool_t *)jarg10; + result = (switch_status_t)switch_core_codec_init_with_bitrate(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5,arg6,arg7,arg8,(switch_codec_settings const *)arg9,arg10); jresult = result; return jresult; } @@ -10379,6 +10469,858 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_in_thread(void * jarg1) { } +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 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->module_name = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->module_name, (const char *)arg2); + } else { + arg1->module_name = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_get(void * jarg1) { + char * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + char *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (char *) ((arg1)->module_name); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_endpoint_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_endpoint_interface_t *arg2 = (switch_endpoint_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_endpoint_interface_t *)jarg2; + if (arg1) (arg1)->endpoint_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_endpoint_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_endpoint_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_endpoint_interface_t *) ((arg1)->endpoint_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_timer_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_timer_interface_t *arg2 = (switch_timer_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_timer_interface_t *)jarg2; + if (arg1) (arg1)->timer_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_timer_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_timer_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_timer_interface_t *) ((arg1)->timer_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_dialplan_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_dialplan_interface_t *arg2 = (switch_dialplan_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_dialplan_interface_t *)jarg2; + if (arg1) (arg1)->dialplan_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_dialplan_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_dialplan_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_dialplan_interface_t *) ((arg1)->dialplan_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_codec_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_codec_interface_t *)jarg2; + if (arg1) (arg1)->codec_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_codec_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_codec_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_codec_interface_t *) ((arg1)->codec_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_application_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_application_interface_t *arg2 = (switch_application_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_application_interface_t *)jarg2; + if (arg1) (arg1)->application_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_application_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_application_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_application_interface_t *) ((arg1)->application_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_api_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_api_interface_t *arg2 = (switch_api_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_api_interface_t *)jarg2; + if (arg1) (arg1)->api_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_api_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_api_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_api_interface_t *) ((arg1)->api_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_file_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_file_interface_t *arg2 = (switch_file_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_file_interface_t *)jarg2; + if (arg1) (arg1)->file_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_file_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_file_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_file_interface_t *) ((arg1)->file_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_speech_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_speech_interface_t *arg2 = (switch_speech_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_speech_interface_t *)jarg2; + if (arg1) (arg1)->speech_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_speech_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_speech_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_speech_interface_t *) ((arg1)->speech_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_directory_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_directory_interface_t *arg2 = (switch_directory_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_directory_interface_t *)jarg2; + if (arg1) (arg1)->directory_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_directory_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_directory_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_directory_interface_t *) ((arg1)->directory_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_chat_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_chat_interface_t *arg2 = (switch_chat_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_chat_interface_t *)jarg2; + if (arg1) (arg1)->chat_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_chat_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_chat_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_chat_interface_t *) ((arg1)->chat_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_say_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_say_interface_t *arg2 = (switch_say_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_say_interface_t *)jarg2; + if (arg1) (arg1)->say_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_say_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_say_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_say_interface_t *) ((arg1)->say_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_asr_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_asr_interface_t *arg2 = (switch_asr_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_asr_interface_t *)jarg2; + if (arg1) (arg1)->asr_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_asr_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_asr_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_asr_interface_t *) ((arg1)->asr_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_management_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_management_interface_t *arg2 = (switch_management_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_management_interface_t *)jarg2; + if (arg1) (arg1)->management_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_management_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_management_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_management_interface_t *) ((arg1)->management_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_limit_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_limit_interface_t *arg2 = (switch_limit_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_limit_interface_t *)jarg2; + if (arg1) (arg1)->limit_interface = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_limit_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_limit_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_limit_interface_t *) ((arg1)->limit_interface); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_rwlock_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_thread_rwlock_t *arg2 = (switch_thread_rwlock_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_thread_rwlock_t *)jarg2; + if (arg1) (arg1)->rwlock = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_rwlock_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_thread_rwlock_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_thread_rwlock_t *) ((arg1)->rwlock); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_refs_set(void * jarg1, int jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + int arg2 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->refs = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_interface_refs_get(void * jarg1) { + int jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + int result; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (int) ((arg1)->refs); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_pool_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_memory_pool_t *arg2 = (switch_memory_pool_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_memory_pool_t *)jarg2; + if (arg1) (arg1)->pool = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_pool_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_memory_pool_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_memory_pool_t *) ((arg1)->pool); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_loadable_module_interface() { + void * jresult ; + switch_loadable_module_interface *result = 0 ; + + result = (switch_loadable_module_interface *)new switch_loadable_module_interface(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_loadable_module_interface(void * jarg1) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + delete arg1; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_init(int jarg1) { + int jresult ; + switch_bool_t arg1 ; + switch_status_t result; + + arg1 = (switch_bool_t)jarg1; + result = (switch_status_t)switch_loadable_module_init(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_shutdown() { + switch_loadable_module_shutdown(); +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_endpoint_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_endpoint_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_endpoint_interface_t *)switch_loadable_module_get_endpoint_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_codec_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_codec_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_codec_interface_t *)switch_loadable_module_get_codec_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_dialplan_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_dialplan_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_dialplan_interface_t *)switch_loadable_module_get_dialplan_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_enumerate_available(char * jarg1, void * jarg2, void * jarg3) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_modulename_callback_func_t arg2 = (switch_modulename_callback_func_t) 0 ; + void *arg3 = (void *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_modulename_callback_func_t)jarg2; + arg3 = (void *)jarg3; + result = (switch_status_t)switch_loadable_module_enumerate_available((char const *)arg1,arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_enumerate_loaded(void * jarg1, void * jarg2) { + int jresult ; + switch_modulename_callback_func_t arg1 = (switch_modulename_callback_func_t) 0 ; + void *arg2 = (void *) 0 ; + switch_status_t result; + + arg1 = (switch_modulename_callback_func_t)jarg1; + arg2 = (void *)jarg2; + result = (switch_status_t)switch_loadable_module_enumerate_loaded(arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_build_dynamic(char * jarg1, void * jarg2, void * jarg3, void * jarg4, int jarg5) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_module_load_t arg2 = (switch_module_load_t) 0 ; + switch_module_runtime_t arg3 = (switch_module_runtime_t) 0 ; + switch_module_shutdown_t arg4 = (switch_module_shutdown_t) 0 ; + switch_bool_t arg5 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_module_load_t)jarg2; + arg3 = (switch_module_runtime_t)jarg3; + arg4 = (switch_module_shutdown_t)jarg4; + arg5 = (switch_bool_t)jarg5; + result = (switch_status_t)switch_loadable_module_build_dynamic(arg1,arg2,arg3,arg4,arg5); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_timer_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_timer_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_timer_interface_t *)switch_loadable_module_get_timer_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_application_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_application_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_application_interface_t *)switch_loadable_module_get_application_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_api_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_api_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_api_interface_t *)switch_loadable_module_get_api_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_file_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_file_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_file_interface_t *)switch_loadable_module_get_file_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_speech_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_speech_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_speech_interface_t *)switch_loadable_module_get_speech_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_asr_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_asr_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_asr_interface_t *)switch_loadable_module_get_asr_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_directory_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_directory_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_directory_interface_t *)switch_loadable_module_get_directory_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_chat_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_chat_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_chat_interface_t *)switch_loadable_module_get_chat_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_say_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_say_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_say_interface_t *)switch_loadable_module_get_say_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_management_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_management_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_management_interface_t *)switch_loadable_module_get_management_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_limit_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_limit_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_limit_interface_t *)switch_loadable_module_get_limit_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_get_codecs(void * jarg1, int jarg2) { + int jresult ; + switch_codec_implementation_t **arg1 = (switch_codec_implementation_t **) 0 ; + int arg2 ; + int result; + + arg1 = (switch_codec_implementation_t **)jarg1; + arg2 = (int)jarg2; + result = (int)switch_loadable_module_get_codecs((switch_codec_implementation const **)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_get_codecs_sorted(void * jarg1, int jarg2, void * jarg3, int jarg4) { + int jresult ; + switch_codec_implementation_t **arg1 = (switch_codec_implementation_t **) 0 ; + int arg2 ; + char **arg3 = (char **) 0 ; + int arg4 ; + int result; + + arg1 = (switch_codec_implementation_t **)jarg1; + arg2 = (int)jarg2; + arg3 = (char **)jarg3; + arg4 = (int)jarg4; + result = (int)switch_loadable_module_get_codecs_sorted((switch_codec_implementation const **)arg1,arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_api_execute(char * jarg1, char * jarg2, void * jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_core_session_t *arg3 = (switch_core_session_t *) 0 ; + switch_stream_handle_t *arg4 = (switch_stream_handle_t *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_core_session_t *)jarg3; + arg4 = (switch_stream_handle_t *)jarg4; + result = (switch_status_t)switch_api_execute((char const *)arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_load_module(char * jarg1, char * jarg2, int jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t arg3 ; + char **arg4 = (char **) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_bool_t)jarg3; + arg4 = (char **)jarg4; + result = (switch_status_t)switch_loadable_module_load_module(arg1,arg2,arg3,(char const **)arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_exists(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + result = (switch_status_t)switch_loadable_module_exists((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_unload_module(char * jarg1, char * jarg2, int jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t arg3 ; + char **arg4 = (char **) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_bool_t)jarg3; + arg4 = (char **)jarg4; + result = (switch_status_t)switch_loadable_module_unload_module(arg1,arg2,arg3,(char const **)arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_core_codec_next_id() { + unsigned long jresult ; + uint32_t result; + + result = (uint32_t)switch_core_codec_next_id(); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_check_interval(unsigned long jarg1, unsigned long jarg2) { + int jresult ; + uint32_t arg1 ; + uint32_t arg2 ; + int result; + + arg1 = (uint32_t)jarg1; + arg2 = (uint32_t)jarg2; + result = (int)switch_check_interval(arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_codec_add_implementation(void * jarg1, void * jarg2, int jarg3, unsigned char jarg4, char * jarg5, char * jarg6, unsigned long jarg7, unsigned long jarg8, int jarg9, int jarg10, unsigned long jarg11, unsigned long jarg12, unsigned long jarg13, unsigned char jarg14, int jarg15, void * jarg16, void * jarg17, void * jarg18, void * jarg19) { + switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ; + switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; + switch_codec_type_t arg3 ; + switch_payload_t arg4 ; + char *arg5 = (char *) 0 ; + char *arg6 = (char *) 0 ; + uint32_t arg7 ; + uint32_t arg8 ; + int arg9 ; + int arg10 ; + uint32_t arg11 ; + uint32_t arg12 ; + uint32_t arg13 ; + uint8_t arg14 ; + int arg15 ; + switch_core_codec_init_func_t arg16 = (switch_core_codec_init_func_t) 0 ; + switch_core_codec_encode_func_t arg17 = (switch_core_codec_encode_func_t) 0 ; + switch_core_codec_decode_func_t arg18 = (switch_core_codec_decode_func_t) 0 ; + switch_core_codec_destroy_func_t arg19 = (switch_core_codec_destroy_func_t) 0 ; + + arg1 = (switch_memory_pool_t *)jarg1; + arg2 = (switch_codec_interface_t *)jarg2; + arg3 = (switch_codec_type_t)jarg3; + arg4 = (switch_payload_t)jarg4; + arg5 = (char *)jarg5; + arg6 = (char *)jarg6; + arg7 = (uint32_t)jarg7; + arg8 = (uint32_t)jarg8; + arg9 = (int)jarg9; + arg10 = (int)jarg10; + arg11 = (uint32_t)jarg11; + arg12 = (uint32_t)jarg12; + arg13 = (uint32_t)jarg13; + arg14 = (uint8_t)jarg14; + arg15 = (int)jarg15; + arg16 = (switch_core_codec_init_func_t)jarg16; + arg17 = (switch_core_codec_encode_func_t)jarg17; + arg18 = (switch_core_codec_decode_func_t)jarg18; + arg19 = (switch_core_codec_destroy_func_t)jarg19; + switch_core_codec_add_implementation(arg1,arg2,arg3,arg4,(char const *)arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16,arg17,arg18,arg19); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_ready(void * jarg1) { + int jresult ; + switch_codec_t *arg1 = (switch_codec_t *) 0 ; + switch_bool_t result; + + arg1 = (switch_codec_t *)jarg1; + result = (switch_bool_t)switch_core_codec_ready(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_CMD_CHUNK_LEN_get() { int jresult ; int result; @@ -11158,6 +12100,20 @@ SWIGEXPORT unsigned char SWIGSTDCALL CSharp_switch_char_to_rfc2833(char jarg1) { } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_default_ptime(char * jarg1, unsigned long jarg2) { + unsigned long jresult ; + char *arg1 = (char *) 0 ; + uint32_t arg2 ; + uint32_t result; + + arg1 = (char *)jarg1; + arg2 = (uint32_t)jarg2; + result = (uint32_t)switch_default_ptime((char const *)arg1,arg2); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_sanitize_number(char * jarg1) { char * jresult ; char *arg1 = (char *) 0 ; @@ -11764,6 +12720,44 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_network_list_validate_ip_token(void * j } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_dow_int2str(int jarg1) { + char * jresult ; + int arg1 ; + char *result = 0 ; + + arg1 = (int)jarg1; + result = (char *)switch_dow_int2str(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dow_str2int(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_dow_str2int((char const *)arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dow_cmp(char * jarg1, int jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + int arg2 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (int)jarg2; + result = (int)switch_dow_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_number_cmp(char * jarg1, int jarg2) { int jresult ; char *arg1 = (char *) 0 ; @@ -11778,6 +12772,62 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_number_cmp(char * jarg1, int jarg2) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_tod_cmp(char * jarg1, int jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + int arg2 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (int)jarg2; + result = (int)switch_tod_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_fulldate_cmp(char * jarg1, void * jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_time_t *arg2 = (switch_time_t *) 0 ; + int result; + + arg1 = (char *)jarg1; + arg2 = (switch_time_t *)jarg2; + result = (int)switch_fulldate_cmp((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_split_date(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { + char *arg1 = (char *) 0 ; + int *arg2 = (int *) 0 ; + int *arg3 = (int *) 0 ; + int *arg4 = (int *) 0 ; + + arg1 = (char *)jarg1; + arg2 = (int *)jarg2; + arg3 = (int *)jarg3; + arg4 = (int *)jarg4; + switch_split_date((char const *)arg1,arg2,arg3,arg4); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_split_time(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { + char *arg1 = (char *) 0 ; + int *arg2 = (int *) 0 ; + int *arg3 = (int *) 0 ; + int *arg4 = (int *) 0 ; + + arg1 = (char *)jarg1; + arg2 = (int *)jarg2; + arg3 = (int *)jarg3; + arg4 = (int *)jarg4; + switch_split_time((char const *)arg1,arg2,arg3,arg4); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_split_user_domain(char * jarg1, void * jarg2, void * jarg3) { int jresult ; char *arg1 = (char *) 0 ; @@ -12514,6 +13564,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_originatee_caller_pro } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_origination_caller_profile_set(void * jarg1, void * jarg2) { + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_caller_profile *arg2 = (switch_caller_profile *) 0 ; + + arg1 = (switch_caller_profile *)jarg1; + arg2 = (switch_caller_profile *)jarg2; + if (arg1) (arg1)->origination_caller_profile = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_caller_profile_origination_caller_profile_get(void * jarg1) { + void * jresult ; + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_caller_profile *result = 0 ; + + arg1 = (switch_caller_profile *)jarg1; + result = (switch_caller_profile *) ((arg1)->origination_caller_profile); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_hunt_caller_profile_set(void * jarg1, void * jarg2) { switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; switch_caller_profile *arg2 = (switch_caller_profile *) 0 ; @@ -19492,369 +20565,24 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_directory_handle(void * jarg1) } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_quality_set(void * jarg1, int jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_unused_set(void * jarg1, int jarg2) { switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int arg2 ; arg1 = (switch_codec_settings *)jarg1; arg2 = (int)jarg2; - if (arg1) (arg1)->quality = arg2; + if (arg1) (arg1)->unused = arg2; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_quality_get(void * jarg1) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_unused_get(void * jarg1) { int jresult ; switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; int result; arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_complexity_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->complexity = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_complexity_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->complexity); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_enhancement_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->enhancement = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_enhancement_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->enhancement); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vad = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->vbr = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_vbr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->vbr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->vbr_quality = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_vbr_quality_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->vbr_quality); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_abr_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->abr = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_abr_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->abr); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_dtx_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->dtx = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_dtx_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->dtx); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_preproc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->preproc = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_preproc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->preproc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_vad = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_vad_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_vad); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_agc = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_agc); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_agc_level = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_agc_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_agc_level); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_denoise = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_denoise_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_denoise); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_set(void * jarg1, int jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (int)jarg2; - if (arg1) (arg1)->pp_dereverb = arg2; - -} - - -SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_get(void * jarg1) { - int jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - int result; - - arg1 = (switch_codec_settings *)jarg1; - result = (int) ((arg1)->pp_dereverb); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_decay = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_decay_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_decay); - jresult = result; - return jresult; -} - - -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_set(void * jarg1, float jarg2) { - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float arg2 ; - - arg1 = (switch_codec_settings *)jarg1; - arg2 = (float)jarg2; - if (arg1) (arg1)->pp_dereverb_level = arg2; - -} - - -SWIGEXPORT float SWIGSTDCALL CSharp_switch_codec_settings_pp_dereverb_level_get(void * jarg1) { - float jresult ; - switch_codec_settings *arg1 = (switch_codec_settings *) 0 ; - float result; - - arg1 = (switch_codec_settings *)jarg1; - result = (float) ((arg1)->pp_dereverb_level); + result = (int) ((arg1)->unused); jresult = result; return jresult; } @@ -19879,6 +20607,117 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_settings(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_set(void * jarg1, unsigned long jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->actual_samples_per_second = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_codec_fmtp_actual_samples_per_second_get(void * jarg1) { + unsigned long jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + uint32_t result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (uint32_t) ((arg1)->actual_samples_per_second); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->bits_per_second = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_bits_per_second_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->bits_per_second); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_set(void * jarg1, int jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int arg2 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->microseconds_per_packet = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_codec_fmtp_microseconds_per_packet_get(void * jarg1) { + int jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + int result; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (int) ((arg1)->microseconds_per_packet); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_set(void * jarg1, void * jarg2) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->private_info = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_fmtp_private_info_get(void * jarg1) { + void * jresult ; + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + void *result = 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + result = (void *) ((arg1)->private_info); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_codec_fmtp() { + void * jresult ; + switch_codec_fmtp *result = 0 ; + + result = (switch_codec_fmtp *)new switch_codec_fmtp(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_codec_fmtp(void * jarg1) { + switch_codec_fmtp *arg1 = (switch_codec_fmtp *) 0 ; + + arg1 = (switch_codec_fmtp *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_interface_set(void * jarg1, void * jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; switch_codec_interface_t *arg2 = (switch_codec_interface_t *) 0 ; @@ -19985,29 +20824,6 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_codec_fmtp_out_get(void * jarg1) { } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_codec_settings_set(void * jarg1, void * jarg2) { - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *arg2 = (switch_codec_settings_t *) 0 ; - - arg1 = (switch_codec *)jarg1; - arg2 = (switch_codec_settings_t *)jarg2; - if (arg1) (arg1)->codec_settings = *arg2; - -} - - -SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_codec_settings_get(void * jarg1) { - void * jresult ; - switch_codec *arg1 = (switch_codec *) 0 ; - switch_codec_settings_t *result = 0 ; - - arg1 = (switch_codec *)jarg1; - result = (switch_codec_settings_t *)& ((arg1)->codec_settings); - jresult = (void *)result; - return jresult; -} - - SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_flags_set(void * jarg1, unsigned long jarg2) { switch_codec *arg1 = (switch_codec *) 0 ; uint32_t arg2 ; @@ -20710,6 +21526,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_implementations_get( } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_set(void * jarg1, void * jarg2) { + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t arg2 = (switch_core_codec_fmtp_parse_func_t) 0 ; + + arg1 = (switch_codec_interface *)jarg1; + arg2 = (switch_core_codec_fmtp_parse_func_t)jarg2; + if (arg1) (arg1)->parse_fmtp = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_codec_interface_parse_fmtp_get(void * jarg1) { + void * jresult ; + switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; + switch_core_codec_fmtp_parse_func_t result; + + arg1 = (switch_codec_interface *)jarg1; + result = (switch_core_codec_fmtp_parse_func_t) ((arg1)->parse_fmtp); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_codec_interface_codec_id_set(void * jarg1, unsigned long jarg2) { switch_codec_interface *arg1 = (switch_codec_interface *) 0 ; uint32_t arg2 ; @@ -22015,6 +22854,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_originatee_caller_profil } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_origination_caller_profile(void * jarg1, void * jarg2) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_caller_profile_t *arg2 = (switch_caller_profile_t *) 0 ; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (switch_caller_profile_t *)jarg2; + switch_channel_set_origination_caller_profile(arg1,arg2); +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_origination_caller_profile(void * jarg1) { + void * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_caller_profile_t *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_caller_profile_t *)switch_channel_get_origination_caller_profile(arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_uuid(void * jarg1) { char * jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -25723,7 +26584,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_record_file(void * jarg1, void * ja } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, unsigned long jarg11, char * jarg12, unsigned long jarg13) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -25737,6 +26598,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig char *arg10 = (char *) 0 ; uint32_t arg11 ; char *arg12 = (char *) 0 ; + uint32_t arg13 ; switch_status_t result; arg1 = (switch_core_session_t *)jarg1; @@ -25751,7 +26613,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_play_and_get_digits(void * jarg1, unsig arg10 = (char *)jarg10; arg11 = (uint32_t)jarg11; arg12 = (char *)jarg12; - result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12); + arg13 = (uint32_t)jarg13; + result = (switch_status_t)switch_play_and_get_digits(arg1,arg2,arg3,arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9,arg10,arg11,(char const *)arg12,arg13); jresult = result; return jresult; } @@ -26525,7 +27388,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_wait_for_answer(void * jarg1, void } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long jarg2, unsigned long jarg3, char * jarg4, char * jarg5, char * jarg6, void * jarg7, unsigned long jarg8, char * jarg9, unsigned long jarg10) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; uint32_t arg2 ; @@ -26536,6 +27399,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja switch_size_t arg7 ; uint32_t arg8 ; char *arg9 = (char *) 0 ; + uint32_t arg10 ; switch_status_t result; switch_size_t *argp7 ; @@ -26553,7 +27417,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_read(void * jarg1, unsigned long ja arg7 = *argp7; arg8 = (uint32_t)jarg8; arg9 = (char *)jarg9; - result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9); + arg10 = (uint32_t)jarg10; + result = (switch_status_t)switch_ivr_read(arg1,arg2,arg3,(char const *)arg4,(char const *)arg5,arg6,arg7,arg8,(char const *)arg9,arg10); jresult = result; return jresult; } @@ -27771,6 +28636,18 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_stats(void * jarg1, void * j } +SWIGEXPORT unsigned char SWIGSTDCALL CSharp_switch_rtp_check_auto_adj(void * jarg1) { + unsigned char jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_byte_t result; + + arg1 = (switch_rtp_t *)jarg1; + result = (switch_byte_t)switch_rtp_check_auto_adj(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_log_node_t_data_set(void * jarg1, char * jarg2) { switch_log_node_t *arg1 = (switch_log_node_t *) 0 ; char *arg2 = (char *) 0 ; @@ -28855,6 +29732,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_init(void * jarg1, void * jarg2) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_reload(void * jarg1) { + int jresult ; + char **arg1 = (char **) 0 ; + switch_status_t result; + + arg1 = (char **)jarg1; + result = (switch_status_t)switch_xml_reload((char const **)arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_xml_destroy() { int jresult ; switch_status_t result; @@ -32509,7 +33398,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Transfer(void * jarg1, char * jarg } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, int jarg3, char * jarg4, int jarg5, char * jarg6, int jarg7) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -32517,6 +33406,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -32525,13 +33415,14 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_read(void * jarg1, int jarg2, i arg4 = (char *)jarg4; arg5 = (int)jarg5; arg6 = (char *)jarg6; - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + arg7 = (int)jarg7; + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } -SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10) { +SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9, char * jarg10, int jarg11) { char * jresult ; CoreSession *arg1 = (CoreSession *) 0 ; int arg2 ; @@ -32543,6 +33434,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; arg1 = (CoreSession *)jarg1; @@ -32555,7 +33447,8 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_PlayAndGetDigits(void * jarg1, arg8 = (char *)jarg8; arg9 = (char *)jarg9; arg10 = (char *)jarg10; - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + arg11 = (int)jarg11; + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 268187547f..01cc84e9aa 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -327,13 +327,13 @@ public class CoreSession : IDisposable { return ret; } - public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators) { - string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators); + public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout); return ret; } - public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name) { - string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name); + public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout); return ret; } @@ -1673,8 +1673,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_core_codec_init(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); + public static switch_status_t switch_core_codec_init_with_bitrate(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint bitrate, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init_with_bitrate(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, bitrate, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); return ret; } @@ -2078,14 +2078,14 @@ public class freeswitch { return ret; } - public static SWIGTYPE_p_switch_loadable_module_interface switch_loadable_module_create_module_interface(SWIGTYPE_p_apr_pool_t pool, string name) { + public static switch_loadable_module_interface switch_loadable_module_create_module_interface(SWIGTYPE_p_apr_pool_t pool, string name) { IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_create_module_interface(SWIGTYPE_p_apr_pool_t.getCPtr(pool), name); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } - public static SWIGTYPE_p_void switch_loadable_module_create_interface(SWIGTYPE_p_switch_loadable_module_interface mod, switch_module_interface_name_t iname) { - IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_create_interface(SWIGTYPE_p_switch_loadable_module_interface.getCPtr(mod), (int)iname); + public static SWIGTYPE_p_void switch_loadable_module_create_interface(switch_loadable_module_interface mod, switch_module_interface_name_t iname) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_create_interface(switch_loadable_module_interface.getCPtr(mod), (int)iname); SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); return ret; } @@ -2309,6 +2309,163 @@ public class freeswitch { return ret; } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); + return ret; + } + + public static void switch_loadable_module_shutdown() { + freeswitchPINVOKE.switch_loadable_module_shutdown(); + } + + public static switch_endpoint_interface switch_loadable_module_get_endpoint_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_endpoint_interface(name); + switch_endpoint_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_endpoint_interface(cPtr, false); + return ret; + } + + public static switch_codec_interface switch_loadable_module_get_codec_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_codec_interface(name); + switch_codec_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_interface(cPtr, false); + return ret; + } + + public static switch_dialplan_interface switch_loadable_module_get_dialplan_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_dialplan_interface(name); + switch_dialplan_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_dialplan_interface(cPtr, false); + return ret; + } + + public static switch_status_t switch_loadable_module_enumerate_available(string dir_path, SWIGTYPE_p_f_p_void_p_q_const__char__int callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_enumerate_available(dir_path, SWIGTYPE_p_f_p_void_p_q_const__char__int.getCPtr(callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static switch_status_t switch_loadable_module_enumerate_loaded(SWIGTYPE_p_f_p_void_p_q_const__char__int callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_enumerate_loaded(SWIGTYPE_p_f_p_void_p_q_const__char__int.getCPtr(callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static switch_status_t switch_loadable_module_build_dynamic(string filename, SWIGTYPE_p_f_p_p_switch_loadable_module_interface_p_apr_pool_t__switch_status_t switch_module_load, SWIGTYPE_p_f_void__switch_status_t switch_module_runtime, SWIGTYPE_p_f_void__switch_status_t switch_module_shutdown, switch_bool_t runtime) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_build_dynamic(filename, SWIGTYPE_p_f_p_p_switch_loadable_module_interface_p_apr_pool_t__switch_status_t.getCPtr(switch_module_load), SWIGTYPE_p_f_void__switch_status_t.getCPtr(switch_module_runtime), SWIGTYPE_p_f_void__switch_status_t.getCPtr(switch_module_shutdown), (int)runtime); + return ret; + } + + public static switch_timer_interface switch_loadable_module_get_timer_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_timer_interface(name); + switch_timer_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_timer_interface(cPtr, false); + return ret; + } + + public static switch_application_interface switch_loadable_module_get_application_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_application_interface(name); + switch_application_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_application_interface(cPtr, false); + return ret; + } + + public static switch_api_interface switch_loadable_module_get_api_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_api_interface(name); + switch_api_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_api_interface(cPtr, false); + return ret; + } + + public static switch_file_interface switch_loadable_module_get_file_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_file_interface(name); + switch_file_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_file_interface(cPtr, false); + return ret; + } + + public static switch_speech_interface switch_loadable_module_get_speech_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_speech_interface(name); + switch_speech_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_speech_interface(cPtr, false); + return ret; + } + + public static switch_asr_interface switch_loadable_module_get_asr_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_asr_interface(name); + switch_asr_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_asr_interface(cPtr, false); + return ret; + } + + public static switch_directory_interface switch_loadable_module_get_directory_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_directory_interface(name); + switch_directory_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_directory_interface(cPtr, false); + return ret; + } + + public static switch_chat_interface switch_loadable_module_get_chat_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_chat_interface(name); + switch_chat_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_chat_interface(cPtr, false); + return ret; + } + + public static switch_say_interface switch_loadable_module_get_say_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_say_interface(name); + switch_say_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_say_interface(cPtr, false); + return ret; + } + + public static switch_management_interface switch_loadable_module_get_management_interface(string relative_oid) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_management_interface(relative_oid); + switch_management_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_management_interface(cPtr, false); + return ret; + } + + public static switch_limit_interface switch_loadable_module_get_limit_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_limit_interface(name); + switch_limit_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_limit_interface(cPtr, false); + return ret; + } + + public static int switch_loadable_module_get_codecs(SWIGTYPE_p_p_switch_codec_implementation array, int arraylen) { + int ret = freeswitchPINVOKE.switch_loadable_module_get_codecs(SWIGTYPE_p_p_switch_codec_implementation.getCPtr(array), arraylen); + return ret; + } + + public static int switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation array, int arraylen, ref string prefs, int preflen) { + int ret = freeswitchPINVOKE.switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation.getCPtr(array), arraylen, ref prefs, preflen); + return ret; + } + + public static switch_status_t switch_api_execute(string cmd, string arg, SWIGTYPE_p_switch_core_session session, switch_stream_handle stream) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_api_execute(cmd, arg, SWIGTYPE_p_switch_core_session.getCPtr(session), switch_stream_handle.getCPtr(stream)); + return ret; + } + + public static switch_status_t switch_loadable_module_load_module(string dir, string fname, switch_bool_t runtime, ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_load_module(dir, fname, (int)runtime, ref err); + return ret; + } + + public static switch_status_t switch_loadable_module_exists(string mod) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_exists(mod); + return ret; + } + + public static switch_status_t switch_loadable_module_unload_module(string dir, string fname, switch_bool_t force, ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_unload_module(dir, fname, (int)force, ref err); + return ret; + } + + public static uint switch_core_codec_next_id() { + uint ret = freeswitchPINVOKE.switch_core_codec_next_id(); + return ret; + } + + public static int switch_check_interval(uint rate, uint ptime) { + int ret = freeswitchPINVOKE.switch_check_interval(rate, ptime); + return ret; + } + + public static void switch_core_codec_add_implementation(SWIGTYPE_p_apr_pool_t pool, switch_codec_interface codec_interface, switch_codec_type_t codec_type, byte ianacode, string iananame, string fmtp, uint samples_per_second, uint actual_samples_per_second, int bits_per_second, int microseconds_per_packet, uint samples_per_packet, uint decoded_bytes_per_packet, uint encoded_bytes_per_packet, byte number_of_channels, int codec_frames_per_packet, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t init, SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t encode, SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t decode, SWIGTYPE_p_f_p_switch_codec__switch_status_t destroy) { + freeswitchPINVOKE.switch_core_codec_add_implementation(SWIGTYPE_p_apr_pool_t.getCPtr(pool), switch_codec_interface.getCPtr(codec_interface), (int)codec_type, ianacode, iananame, fmtp, samples_per_second, actual_samples_per_second, bits_per_second, microseconds_per_packet, samples_per_packet, decoded_bytes_per_packet, encoded_bytes_per_packet, number_of_channels, codec_frames_per_packet, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t.getCPtr(init), SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t.getCPtr(encode), SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t.getCPtr(decode), SWIGTYPE_p_f_p_switch_codec__switch_status_t.getCPtr(destroy)); + } + + public static switch_bool_t switch_core_codec_ready(switch_codec codec) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_core_codec_ready(switch_codec.getCPtr(codec)); + return ret; + } + public static void switch_console_loop() { freeswitchPINVOKE.switch_console_loop(); } @@ -2568,6 +2725,11 @@ public class freeswitch { return ret; } + public static uint switch_default_ptime(string name, uint number) { + uint ret = freeswitchPINVOKE.switch_default_ptime(name, number); + return ret; + } + public static string switch_sanitize_number(string number) { string ret = freeswitchPINVOKE.switch_sanitize_number(number); return ret; @@ -2771,11 +2933,44 @@ public class freeswitch { return ret; } + public static string switch_dow_int2str(int val) { + string ret = freeswitchPINVOKE.switch_dow_int2str(val); + return ret; + } + + public static int switch_dow_str2int(string exp) { + int ret = freeswitchPINVOKE.switch_dow_str2int(exp); + return ret; + } + + public static int switch_dow_cmp(string exp, int val) { + int ret = freeswitchPINVOKE.switch_dow_cmp(exp, val); + return ret; + } + public static int switch_number_cmp(string exp, int val) { int ret = freeswitchPINVOKE.switch_number_cmp(exp, val); return ret; } + public static int switch_tod_cmp(string exp, int val) { + int ret = freeswitchPINVOKE.switch_tod_cmp(exp, val); + return ret; + } + + public static int switch_fulldate_cmp(string exp, SWIGTYPE_p_switch_time_t ts) { + int ret = freeswitchPINVOKE.switch_fulldate_cmp(exp, SWIGTYPE_p_switch_time_t.getCPtr(ts)); + return ret; + } + + public static void switch_split_date(string exp, SWIGTYPE_p_int year, SWIGTYPE_p_int month, SWIGTYPE_p_int day) { + freeswitchPINVOKE.switch_split_date(exp, SWIGTYPE_p_int.getCPtr(year), SWIGTYPE_p_int.getCPtr(month), SWIGTYPE_p_int.getCPtr(day)); + } + + public static void switch_split_time(string exp, SWIGTYPE_p_int hour, SWIGTYPE_p_int min, SWIGTYPE_p_int sec) { + freeswitchPINVOKE.switch_split_time(exp, SWIGTYPE_p_int.getCPtr(hour), SWIGTYPE_p_int.getCPtr(min), SWIGTYPE_p_int.getCPtr(sec)); + } + public static int switch_split_user_domain(string arg0, ref string user, ref string domain) { int ret = freeswitchPINVOKE.switch_split_user_domain(arg0, ref user, ref domain); return ret; @@ -2948,6 +3143,16 @@ public class freeswitch { return ret; } + public static void switch_channel_set_origination_caller_profile(SWIGTYPE_p_switch_channel channel, switch_caller_profile caller_profile) { + freeswitchPINVOKE.switch_channel_set_origination_caller_profile(SWIGTYPE_p_switch_channel.getCPtr(channel), switch_caller_profile.getCPtr(caller_profile)); + } + + public static switch_caller_profile switch_channel_get_origination_caller_profile(SWIGTYPE_p_switch_channel channel) { + IntPtr cPtr = freeswitchPINVOKE.switch_channel_get_origination_caller_profile(SWIGTYPE_p_switch_channel.getCPtr(channel)); + switch_caller_profile ret = (cPtr == IntPtr.Zero) ? null : new switch_caller_profile(cPtr, false); + return ret; + } + public static string switch_channel_get_uuid(SWIGTYPE_p_switch_channel channel) { string ret = freeswitchPINVOKE.switch_channel_get_uuid(SWIGTYPE_p_switch_channel.getCPtr(channel)); return ret; @@ -3819,8 +4024,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex); + public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex, digit_timeout); return ret; } @@ -4049,8 +4254,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators); + public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators, digit_timeout); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -4400,6 +4605,11 @@ public class freeswitch { return ret; } + public static byte switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp rtp_session) { + byte ret = freeswitchPINVOKE.switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); + return ret; + } + public static switch_status_t switch_log_init(SWIGTYPE_p_apr_pool_t pool, switch_bool_t colorize) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_log_init(SWIGTYPE_p_apr_pool_t.getCPtr(pool), (int)colorize); return ret; @@ -4595,6 +4805,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_xml_reload(ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_reload(ref err); + return ret; + } + public static switch_status_t switch_xml_destroy() { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_destroy(); return ret; @@ -5958,6 +6173,24 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_rtp_numbers_t")] public static extern void delete_switch_rtp_numbers_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_packet_count_set")] + public static extern void switch_rtcp_numbers_t_packet_count_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_packet_count_get")] + public static extern uint switch_rtcp_numbers_t_packet_count_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_octet_count_set")] + public static extern void switch_rtcp_numbers_t_octet_count_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_octet_count_get")] + public static extern uint switch_rtcp_numbers_t_octet_count_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_rtcp_numbers_t")] + public static extern IntPtr new_switch_rtcp_numbers_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_rtcp_numbers_t")] + public static extern void delete_switch_rtcp_numbers_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_inbound_set")] public static extern void switch_rtp_stats_t_inbound_set(HandleRef jarg1, HandleRef jarg2); @@ -5970,6 +6203,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_outbound_get")] public static extern IntPtr switch_rtp_stats_t_outbound_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_rtcp_set")] + public static extern void switch_rtp_stats_t_rtcp_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_rtcp_get")] + public static extern IntPtr switch_rtp_stats_t_rtcp_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_rtp_stats_t")] public static extern IntPtr new_switch_rtp_stats_t(); @@ -6142,10 +6381,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_remote_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_set")] - public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_get")] - public static extern uint switch_t38_options_t_remote_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_remote_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_ip_set")] public static extern void switch_t38_options_t_local_ip_set(HandleRef jarg1, string jarg2); @@ -6154,10 +6393,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_local_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_set")] - public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_get")] - public static extern uint switch_t38_options_t_local_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_local_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_t38_options_t")] public static extern IntPtr new_switch_t38_options_t(); @@ -7170,8 +7409,8 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_timer_destroy")] public static extern int switch_core_timer_destroy(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init")] - public static extern int switch_core_codec_init(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, HandleRef jarg8, HandleRef jarg9); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init_with_bitrate")] + public static extern int switch_core_codec_init_with_bitrate(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, uint jarg8, HandleRef jarg9, HandleRef jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_copy")] public static extern int switch_core_codec_copy(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -7710,6 +7949,207 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_in_thread")] public static extern int switch_core_session_in_thread(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] + public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_get")] + public static extern string switch_loadable_module_interface_module_name_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_endpoint_interface_set")] + public static extern void switch_loadable_module_interface_endpoint_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_endpoint_interface_get")] + public static extern IntPtr switch_loadable_module_interface_endpoint_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_timer_interface_set")] + public static extern void switch_loadable_module_interface_timer_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_timer_interface_get")] + public static extern IntPtr switch_loadable_module_interface_timer_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_dialplan_interface_set")] + public static extern void switch_loadable_module_interface_dialplan_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_dialplan_interface_get")] + public static extern IntPtr switch_loadable_module_interface_dialplan_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_codec_interface_set")] + public static extern void switch_loadable_module_interface_codec_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_codec_interface_get")] + public static extern IntPtr switch_loadable_module_interface_codec_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_application_interface_set")] + public static extern void switch_loadable_module_interface_application_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_application_interface_get")] + public static extern IntPtr switch_loadable_module_interface_application_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_api_interface_set")] + public static extern void switch_loadable_module_interface_api_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_api_interface_get")] + public static extern IntPtr switch_loadable_module_interface_api_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_file_interface_set")] + public static extern void switch_loadable_module_interface_file_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_file_interface_get")] + public static extern IntPtr switch_loadable_module_interface_file_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_speech_interface_set")] + public static extern void switch_loadable_module_interface_speech_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_speech_interface_get")] + public static extern IntPtr switch_loadable_module_interface_speech_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_directory_interface_set")] + public static extern void switch_loadable_module_interface_directory_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_directory_interface_get")] + public static extern IntPtr switch_loadable_module_interface_directory_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_chat_interface_set")] + public static extern void switch_loadable_module_interface_chat_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_chat_interface_get")] + public static extern IntPtr switch_loadable_module_interface_chat_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_say_interface_set")] + public static extern void switch_loadable_module_interface_say_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_say_interface_get")] + public static extern IntPtr switch_loadable_module_interface_say_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_asr_interface_set")] + public static extern void switch_loadable_module_interface_asr_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_asr_interface_get")] + public static extern IntPtr switch_loadable_module_interface_asr_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_management_interface_set")] + public static extern void switch_loadable_module_interface_management_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_management_interface_get")] + public static extern IntPtr switch_loadable_module_interface_management_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_limit_interface_set")] + public static extern void switch_loadable_module_interface_limit_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_limit_interface_get")] + public static extern IntPtr switch_loadable_module_interface_limit_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_rwlock_set")] + public static extern void switch_loadable_module_interface_rwlock_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_rwlock_get")] + public static extern IntPtr switch_loadable_module_interface_rwlock_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_refs_set")] + public static extern void switch_loadable_module_interface_refs_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_refs_get")] + public static extern int switch_loadable_module_interface_refs_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_pool_set")] + public static extern void switch_loadable_module_interface_pool_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_pool_get")] + public static extern IntPtr switch_loadable_module_interface_pool_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_loadable_module_interface")] + public static extern IntPtr new_switch_loadable_module_interface(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_loadable_module_interface")] + public static extern void delete_switch_loadable_module_interface(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_init")] + public static extern int switch_loadable_module_init(int jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_shutdown")] + public static extern void switch_loadable_module_shutdown(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_endpoint_interface")] + public static extern IntPtr switch_loadable_module_get_endpoint_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_codec_interface")] + public static extern IntPtr switch_loadable_module_get_codec_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_dialplan_interface")] + public static extern IntPtr switch_loadable_module_get_dialplan_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_enumerate_available")] + public static extern int switch_loadable_module_enumerate_available(string jarg1, HandleRef jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_enumerate_loaded")] + public static extern int switch_loadable_module_enumerate_loaded(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_build_dynamic")] + public static extern int switch_loadable_module_build_dynamic(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, int jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_timer_interface")] + public static extern IntPtr switch_loadable_module_get_timer_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_application_interface")] + public static extern IntPtr switch_loadable_module_get_application_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_api_interface")] + public static extern IntPtr switch_loadable_module_get_api_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_file_interface")] + public static extern IntPtr switch_loadable_module_get_file_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_speech_interface")] + public static extern IntPtr switch_loadable_module_get_speech_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_asr_interface")] + public static extern IntPtr switch_loadable_module_get_asr_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_directory_interface")] + public static extern IntPtr switch_loadable_module_get_directory_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_chat_interface")] + public static extern IntPtr switch_loadable_module_get_chat_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_say_interface")] + public static extern IntPtr switch_loadable_module_get_say_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_management_interface")] + public static extern IntPtr switch_loadable_module_get_management_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_limit_interface")] + public static extern IntPtr switch_loadable_module_get_limit_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_codecs")] + public static extern int switch_loadable_module_get_codecs(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_codecs_sorted")] + public static extern int switch_loadable_module_get_codecs_sorted(HandleRef jarg1, int jarg2, ref string jarg3, int jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_api_execute")] + public static extern int switch_api_execute(string jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_load_module")] + public static extern int switch_loadable_module_load_module(string jarg1, string jarg2, int jarg3, ref string jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_exists")] + public static extern int switch_loadable_module_exists(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_unload_module")] + public static extern int switch_loadable_module_unload_module(string jarg1, string jarg2, int jarg3, ref string jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_next_id")] + public static extern uint switch_core_codec_next_id(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_check_interval")] + public static extern int switch_check_interval(uint jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_add_implementation")] + public static extern void switch_core_codec_add_implementation(HandleRef jarg1, HandleRef jarg2, int jarg3, byte jarg4, string jarg5, string jarg6, uint jarg7, uint jarg8, int jarg9, int jarg10, uint jarg11, uint jarg12, uint jarg13, byte jarg14, int jarg15, HandleRef jarg16, HandleRef jarg17, HandleRef jarg18, HandleRef jarg19); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_ready")] + public static extern int switch_core_codec_ready(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CMD_CHUNK_LEN_get")] public static extern int SWITCH_CMD_CHUNK_LEN_get(); @@ -7872,6 +8312,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_char_to_rfc2833")] public static extern byte switch_char_to_rfc2833(char jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_default_ptime")] + public static extern uint switch_default_ptime(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sanitize_number")] public static extern string switch_sanitize_number(string jarg1); @@ -7992,9 +8435,30 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_network_list_validate_ip_token")] public static extern int switch_network_list_validate_ip_token(HandleRef jarg1, uint jarg2, ref string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_int2str")] + public static extern string switch_dow_int2str(int jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_str2int")] + public static extern int switch_dow_str2int(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_cmp")] + public static extern int switch_dow_cmp(string jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_number_cmp")] public static extern int switch_number_cmp(string jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_tod_cmp")] + public static extern int switch_tod_cmp(string jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_fulldate_cmp")] + public static extern int switch_fulldate_cmp(string jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_date")] + public static extern void switch_split_date(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_time")] + public static extern void switch_split_time(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_user_domain")] public static extern int switch_split_user_domain(string jarg1, ref string jarg2, ref string jarg3); @@ -8160,6 +8624,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_originatee_caller_profile_get")] public static extern IntPtr switch_caller_profile_originatee_caller_profile_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_origination_caller_profile_set")] + public static extern void switch_caller_profile_origination_caller_profile_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_origination_caller_profile_get")] + public static extern IntPtr switch_caller_profile_origination_caller_profile_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_hunt_caller_profile_set")] public static extern void switch_caller_profile_hunt_caller_profile_set(HandleRef jarg1, HandleRef jarg2); @@ -9921,101 +10391,11 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_directory_handle")] public static extern void delete_switch_directory_handle(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_set")] - public static extern void switch_codec_settings_quality_set(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_set")] + public static extern void switch_codec_settings_unused_set(HandleRef jarg1, int jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_get")] - public static extern int switch_codec_settings_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_set")] - public static extern void switch_codec_settings_complexity_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_get")] - public static extern int switch_codec_settings_complexity_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_set")] - public static extern void switch_codec_settings_enhancement_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_get")] - public static extern int switch_codec_settings_enhancement_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_set")] - public static extern void switch_codec_settings_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_get")] - public static extern int switch_codec_settings_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_set")] - public static extern void switch_codec_settings_vbr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_get")] - public static extern int switch_codec_settings_vbr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_set")] - public static extern void switch_codec_settings_vbr_quality_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_get")] - public static extern float switch_codec_settings_vbr_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_set")] - public static extern void switch_codec_settings_abr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_get")] - public static extern int switch_codec_settings_abr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_set")] - public static extern void switch_codec_settings_dtx_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_get")] - public static extern int switch_codec_settings_dtx_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_set")] - public static extern void switch_codec_settings_preproc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_get")] - public static extern int switch_codec_settings_preproc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_set")] - public static extern void switch_codec_settings_pp_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_get")] - public static extern int switch_codec_settings_pp_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_set")] - public static extern void switch_codec_settings_pp_agc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_get")] - public static extern int switch_codec_settings_pp_agc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_set")] - public static extern void switch_codec_settings_pp_agc_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_get")] - public static extern float switch_codec_settings_pp_agc_level_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_set")] - public static extern void switch_codec_settings_pp_denoise_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_get")] - public static extern int switch_codec_settings_pp_denoise_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_set")] - public static extern void switch_codec_settings_pp_dereverb_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_get")] - public static extern int switch_codec_settings_pp_dereverb_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_set")] - public static extern void switch_codec_settings_pp_dereverb_decay_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_get")] - public static extern float switch_codec_settings_pp_dereverb_decay_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_set")] - public static extern void switch_codec_settings_pp_dereverb_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_get")] - public static extern float switch_codec_settings_pp_dereverb_level_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_get")] + public static extern int switch_codec_settings_unused_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_settings")] public static extern IntPtr new_switch_codec_settings(); @@ -10023,6 +10403,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_settings")] public static extern void delete_switch_codec_settings(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_set")] + public static extern void switch_codec_fmtp_actual_samples_per_second_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_get")] + public static extern uint switch_codec_fmtp_actual_samples_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_set")] + public static extern void switch_codec_fmtp_bits_per_second_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_get")] + public static extern int switch_codec_fmtp_bits_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_set")] + public static extern void switch_codec_fmtp_microseconds_per_packet_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_get")] + public static extern int switch_codec_fmtp_microseconds_per_packet_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_set")] + public static extern void switch_codec_fmtp_private_info_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_get")] + public static extern IntPtr switch_codec_fmtp_private_info_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_fmtp")] + public static extern IntPtr new_switch_codec_fmtp(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_fmtp")] + public static extern void delete_switch_codec_fmtp(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_interface_set")] public static extern void switch_codec_codec_interface_set(HandleRef jarg1, HandleRef jarg2); @@ -10047,12 +10457,6 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_out_get")] public static extern string switch_codec_fmtp_out_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_set")] - public static extern void switch_codec_codec_settings_set(HandleRef jarg1, HandleRef jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_get")] - public static extern IntPtr switch_codec_codec_settings_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_flags_set")] public static extern void switch_codec_flags_set(HandleRef jarg1, uint jarg2); @@ -10233,6 +10637,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_implementations_get")] public static extern IntPtr switch_codec_interface_implementations_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_set")] + public static extern void switch_codec_interface_parse_fmtp_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_get")] + public static extern IntPtr switch_codec_interface_parse_fmtp_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_codec_id_set")] public static extern void switch_codec_interface_codec_id_set(HandleRef jarg1, uint jarg2); @@ -10542,6 +10952,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_originatee_caller_profile")] public static extern IntPtr switch_channel_get_originatee_caller_profile(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_origination_caller_profile")] + public static extern void switch_channel_set_origination_caller_profile(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_origination_caller_profile")] + public static extern IntPtr switch_channel_get_origination_caller_profile(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_uuid")] public static extern string switch_channel_get_uuid(HandleRef jarg1); @@ -11344,7 +11760,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_record_file(HandleRef jarg1, HandleRef jarg2, string jarg3, HandleRef jarg4, uint jarg5); [DllImport("mod_managed", EntryPoint="CSharp_switch_play_and_get_digits")] - public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12); + public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12, uint jarg13); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_speak_text_handle")] public static extern int switch_ivr_speak_text_handle(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, string jarg5, HandleRef jarg6); @@ -11482,7 +11898,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_wait_for_answer(HandleRef jarg1, HandleRef jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_read")] - public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9); + public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9, uint jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_block_dtmf_session")] public static extern int switch_ivr_block_dtmf_session(HandleRef jarg1); @@ -11754,6 +12170,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_stats")] public static extern IntPtr switch_rtp_get_stats(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_check_auto_adj")] + public static extern byte switch_rtp_check_auto_adj(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_data_set")] public static extern void switch_log_node_t_data_set(HandleRef jarg1, string jarg2); @@ -12000,6 +12419,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_init")] public static extern int switch_xml_init(HandleRef jarg1, ref string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_reload")] + public static extern int switch_xml_reload(ref string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_destroy")] public static extern int switch_xml_destroy(); @@ -12886,10 +13308,10 @@ class freeswitchPINVOKE { public static extern int CoreSession_Transfer(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_read")] - public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6); + public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_PlayAndGetDigits")] - public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10); + public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, int jarg11); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_StreamFile")] public static extern int CoreSession_StreamFile(HandleRef jarg1, string jarg2, int jarg3); @@ -13607,6 +14029,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_q_const__char_p_switch_core_session_p_switch_stream_handle__switch_status_t { private HandleRef swigCPtr; @@ -15527,6 +15979,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_void_p_q_const__char__int { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_void_p_q_const__char__int(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_void_p_q_const__char__int() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_void_p_q_const__char__int obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_void__void { private HandleRef swigCPtr; @@ -16007,6 +16489,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_codec_implementation { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_codec_implementation(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_codec_implementation() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_codec_implementation obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_console_callback_match { private HandleRef swigCPtr; @@ -17207,36 +17719,6 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; -public class SWIGTYPE_p_switch_loadable_module_interface { - private HandleRef swigCPtr; - - internal SWIGTYPE_p_switch_loadable_module_interface(IntPtr cPtr, bool futureUse) { - swigCPtr = new HandleRef(this, cPtr); - } - - protected SWIGTYPE_p_switch_loadable_module_interface() { - swigCPtr = new HandleRef(null, IntPtr.Zero); - } - - internal static HandleRef getCPtr(SWIGTYPE_p_switch_loadable_module_interface obj) { - return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; - } -} - -} -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 2.0.0 - * - * Do not make changes to this file unless you know what you are doing--modify - * the SWIG interface file instead. - * ----------------------------------------------------------------------------- */ - -namespace FreeSWITCH.Native { - -using System; -using System.Runtime.InteropServices; - public class SWIGTYPE_p_switch_media_bug { private HandleRef swigCPtr; @@ -18021,13 +18503,13 @@ public class switch_api_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_api_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_api_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_api_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -18203,13 +18685,13 @@ public class switch_application_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_application_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_application_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_application_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -18701,13 +19183,13 @@ public class switch_asr_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_asr_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_asr_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -20106,6 +20588,17 @@ public class switch_caller_profile : IDisposable { } } + public switch_caller_profile origination_caller_profile { + set { + freeswitchPINVOKE.switch_caller_profile_origination_caller_profile_set(swigCPtr, switch_caller_profile.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_caller_profile_origination_caller_profile_get(swigCPtr); + switch_caller_profile ret = (cPtr == IntPtr.Zero) ? null : new switch_caller_profile(cPtr, false); + return ret; + } + } + public switch_caller_profile hunt_caller_profile { set { freeswitchPINVOKE.switch_caller_profile_hunt_caller_profile_set(swigCPtr, switch_caller_profile.getCPtr(value)); @@ -20691,13 +21184,13 @@ public class switch_chat_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_chat_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_chat_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_chat_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -20804,17 +21297,6 @@ public class switch_codec : IDisposable { } } - public switch_codec_settings codec_settings { - set { - freeswitchPINVOKE.switch_codec_codec_settings_set(swigCPtr, switch_codec_settings.getCPtr(value)); - } - get { - IntPtr cPtr = freeswitchPINVOKE.switch_codec_codec_settings_get(swigCPtr); - switch_codec_settings ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_settings(cPtr, false); - return ret; - } - } - public uint flags { set { freeswitchPINVOKE.switch_codec_flags_set(swigCPtr, value); @@ -20921,6 +21403,96 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class switch_codec_fmtp : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_codec_fmtp(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_codec_fmtp obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_codec_fmtp() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_codec_fmtp(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public uint actual_samples_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_get(swigCPtr); + return ret; + } + } + + public int bits_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_get(swigCPtr); + return ret; + } + } + + public int microseconds_per_packet { + set { + freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_void private_info { + set { + freeswitchPINVOKE.switch_codec_fmtp_private_info_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_fmtp_private_info_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public switch_codec_fmtp() : this(freeswitchPINVOKE.new_switch_codec_fmtp(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class switch_codec_implementation : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; @@ -21226,6 +21798,17 @@ public class switch_codec_interface : IDisposable { } } + public SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t parse_fmtp { + set { + freeswitchPINVOKE.switch_codec_interface_parse_fmtp_set(swigCPtr, SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_interface_parse_fmtp_get(swigCPtr); + SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(cPtr, false); + return ret; + } + } + public uint codec_id { set { freeswitchPINVOKE.switch_codec_interface_codec_id_set(swigCPtr, value); @@ -21268,13 +21851,13 @@ public class switch_codec_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_codec_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_codec_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_codec_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -21339,162 +21922,12 @@ public class switch_codec_settings : IDisposable { } } - public int quality { + public int unused { set { - freeswitchPINVOKE.switch_codec_settings_quality_set(swigCPtr, value); + freeswitchPINVOKE.switch_codec_settings_unused_set(swigCPtr, value); } get { - int ret = freeswitchPINVOKE.switch_codec_settings_quality_get(swigCPtr); - return ret; - } - } - - public int complexity { - set { - freeswitchPINVOKE.switch_codec_settings_complexity_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_complexity_get(swigCPtr); - return ret; - } - } - - public int enhancement { - set { - freeswitchPINVOKE.switch_codec_settings_enhancement_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_enhancement_get(swigCPtr); - return ret; - } - } - - public int vad { - set { - freeswitchPINVOKE.switch_codec_settings_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vad_get(swigCPtr); - return ret; - } - } - - public int vbr { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vbr_get(swigCPtr); - return ret; - } - } - - public float vbr_quality { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_quality_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_vbr_quality_get(swigCPtr); - return ret; - } - } - - public int abr { - set { - freeswitchPINVOKE.switch_codec_settings_abr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_abr_get(swigCPtr); - return ret; - } - } - - public int dtx { - set { - freeswitchPINVOKE.switch_codec_settings_dtx_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_dtx_get(swigCPtr); - return ret; - } - } - - public int preproc { - set { - freeswitchPINVOKE.switch_codec_settings_preproc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_preproc_get(swigCPtr); - return ret; - } - } - - public int pp_vad { - set { - freeswitchPINVOKE.switch_codec_settings_pp_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_vad_get(swigCPtr); - return ret; - } - } - - public int pp_agc { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_get(swigCPtr); - return ret; - } - } - - public float pp_agc_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_level_get(swigCPtr); - return ret; - } - } - - public int pp_denoise { - set { - freeswitchPINVOKE.switch_codec_settings_pp_denoise_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_denoise_get(swigCPtr); - return ret; - } - } - - public int pp_dereverb { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_decay { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_get(swigCPtr); + int ret = freeswitchPINVOKE.switch_codec_settings_unused_get(swigCPtr); return ret; } } @@ -21849,7 +22282,8 @@ namespace FreeSWITCH.Native { SCF_USE_CLOCK_RT = (1 << 10), SCF_VERBOSE_EVENTS = (1 << 11), SCF_USE_WIN32_MONOTONIC = (1 << 12), - SCF_AUTO_SCHEMAS = (1 << 13) + SCF_AUTO_SCHEMAS = (1 << 13), + SCF_MINIMAL = (1 << 14) } } @@ -22477,13 +22911,13 @@ public class switch_dialplan_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_dialplan_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_dialplan_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_dialplan_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -22931,13 +23365,13 @@ public class switch_directory_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_directory_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_directory_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_directory_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -23180,13 +23614,13 @@ public class switch_endpoint_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_endpoint_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_endpoint_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_endpoint_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -24253,13 +24687,13 @@ public class switch_file_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_file_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_file_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_file_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -26101,13 +26535,13 @@ public class switch_limit_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_limit_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_limit_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_limit_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -26241,6 +26675,251 @@ public class switch_loadable_module_function_table_t : IDisposable { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_loadable_module_interface : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_loadable_module_interface(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_loadable_module_interface obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_loadable_module_interface() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_loadable_module_interface(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public string module_name { + set { + freeswitchPINVOKE.switch_loadable_module_interface_module_name_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_loadable_module_interface_module_name_get(swigCPtr); + return ret; + } + } + + public switch_endpoint_interface endpoint_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_endpoint_interface_set(swigCPtr, switch_endpoint_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_endpoint_interface_get(swigCPtr); + switch_endpoint_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_endpoint_interface(cPtr, false); + return ret; + } + } + + public switch_timer_interface timer_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_timer_interface_set(swigCPtr, switch_timer_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_timer_interface_get(swigCPtr); + switch_timer_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_timer_interface(cPtr, false); + return ret; + } + } + + public switch_dialplan_interface dialplan_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_dialplan_interface_set(swigCPtr, switch_dialplan_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_dialplan_interface_get(swigCPtr); + switch_dialplan_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_dialplan_interface(cPtr, false); + return ret; + } + } + + public switch_codec_interface codec_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_codec_interface_set(swigCPtr, switch_codec_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_codec_interface_get(swigCPtr); + switch_codec_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_interface(cPtr, false); + return ret; + } + } + + public switch_application_interface application_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_application_interface_set(swigCPtr, switch_application_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_application_interface_get(swigCPtr); + switch_application_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_application_interface(cPtr, false); + return ret; + } + } + + public switch_api_interface api_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_api_interface_set(swigCPtr, switch_api_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_api_interface_get(swigCPtr); + switch_api_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_api_interface(cPtr, false); + return ret; + } + } + + public switch_file_interface file_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_file_interface_set(swigCPtr, switch_file_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_file_interface_get(swigCPtr); + switch_file_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_file_interface(cPtr, false); + return ret; + } + } + + public switch_speech_interface speech_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_speech_interface_set(swigCPtr, switch_speech_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_speech_interface_get(swigCPtr); + switch_speech_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_speech_interface(cPtr, false); + return ret; + } + } + + public switch_directory_interface directory_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_directory_interface_set(swigCPtr, switch_directory_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_directory_interface_get(swigCPtr); + switch_directory_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_directory_interface(cPtr, false); + return ret; + } + } + + public switch_chat_interface chat_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_chat_interface_set(swigCPtr, switch_chat_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_chat_interface_get(swigCPtr); + switch_chat_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_chat_interface(cPtr, false); + return ret; + } + } + + public switch_say_interface say_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_say_interface_set(swigCPtr, switch_say_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_say_interface_get(swigCPtr); + switch_say_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_say_interface(cPtr, false); + return ret; + } + } + + public switch_asr_interface asr_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_asr_interface_set(swigCPtr, switch_asr_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_asr_interface_get(swigCPtr); + switch_asr_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_asr_interface(cPtr, false); + return ret; + } + } + + public switch_management_interface management_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_management_interface_set(swigCPtr, switch_management_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_management_interface_get(swigCPtr); + switch_management_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_management_interface(cPtr, false); + return ret; + } + } + + public switch_limit_interface limit_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_limit_interface_set(swigCPtr, switch_limit_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_limit_interface_get(swigCPtr); + switch_limit_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_limit_interface(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_switch_thread_rwlock_t rwlock { + set { + freeswitchPINVOKE.switch_loadable_module_interface_rwlock_set(swigCPtr, SWIGTYPE_p_switch_thread_rwlock_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_rwlock_get(swigCPtr); + SWIGTYPE_p_switch_thread_rwlock_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_thread_rwlock_t(cPtr, false); + return ret; + } + } + + public int refs { + set { + freeswitchPINVOKE.switch_loadable_module_interface_refs_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_loadable_module_interface_refs_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_apr_pool_t pool { + set { + freeswitchPINVOKE.switch_loadable_module_interface_pool_set(swigCPtr, SWIGTYPE_p_apr_pool_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_pool_get(swigCPtr); + SWIGTYPE_p_apr_pool_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_apr_pool_t(cPtr, false); + return ret; + } + } + + public switch_loadable_module_interface() : this(freeswitchPINVOKE.new_switch_loadable_module_interface(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_log_level_t { SWITCH_LOG_DEBUG10 = 110, SWITCH_LOG_DEBUG9 = 109, @@ -26518,13 +27197,13 @@ public class switch_management_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_management_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_management_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_management_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -26818,6 +27497,75 @@ public class switch_rtcp_hdr_t : IDisposable { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_rtcp_numbers_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_rtcp_numbers_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_rtcp_numbers_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_rtcp_numbers_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_rtcp_numbers_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public uint packet_count { + set { + freeswitchPINVOKE.switch_rtcp_numbers_t_packet_count_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_numbers_t_packet_count_get(swigCPtr); + return ret; + } + } + + public uint octet_count { + set { + freeswitchPINVOKE.switch_rtcp_numbers_t_octet_count_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_numbers_t_octet_count_get(swigCPtr); + return ret; + } + } + + public switch_rtcp_numbers_t() : this(freeswitchPINVOKE.new_switch_rtcp_numbers_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.0 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_rtp_bug_flag_t { RTP_BUG_NONE = 0, RTP_BUG_CISCO_SKIP_MARK_BIT_2833 = (1 << 0), @@ -27388,6 +28136,17 @@ public class switch_rtp_stats_t : IDisposable { } } + public switch_rtcp_numbers_t rtcp { + set { + freeswitchPINVOKE.switch_rtp_stats_t_rtcp_set(swigCPtr, switch_rtcp_numbers_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_rtp_stats_t_rtcp_get(swigCPtr); + switch_rtcp_numbers_t ret = (cPtr == IntPtr.Zero) ? null : new switch_rtcp_numbers_t(cPtr, false); + return ret; + } + } + public switch_rtp_stats_t() : this(freeswitchPINVOKE.new_switch_rtp_stats_t(), true) { } @@ -27586,13 +28345,13 @@ public class switch_say_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_say_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_say_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_say_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -28273,13 +29032,13 @@ public class switch_speech_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_speech_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_speech_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_speech_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -28900,12 +29659,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint remote_port { + public ushort remote_port { set { freeswitchPINVOKE.switch_t38_options_t_remote_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); return ret; } } @@ -28920,12 +29679,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint local_port { + public ushort local_port { set { freeswitchPINVOKE.switch_t38_options_t_local_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); return ret; } } @@ -29286,13 +30045,13 @@ public class switch_timer_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_timer_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_timer_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_timer_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 30859377c5..f30750a191 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -323,13 +323,13 @@ public class CoreSession : IDisposable { return ret; } - public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators) { - string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators); + public string read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_read(swigCPtr, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout); return ret; } - public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name) { - string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name); + public string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name, int digit_timeout) { + string ret = freeswitchPINVOKE.CoreSession_PlayAndGetDigits(swigCPtr, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout); return ret; } @@ -1663,8 +1663,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_core_codec_init(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); + public static switch_status_t switch_core_codec_init_with_bitrate(switch_codec codec, string codec_name, string fmtp, uint rate, int ms, int channels, uint bitrate, uint flags, switch_codec_settings codec_settings, SWIGTYPE_p_apr_pool_t pool) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_init_with_bitrate(switch_codec.getCPtr(codec), codec_name, fmtp, rate, ms, channels, bitrate, flags, switch_codec_settings.getCPtr(codec_settings), SWIGTYPE_p_apr_pool_t.getCPtr(pool)); return ret; } @@ -2068,14 +2068,14 @@ public class freeswitch { return ret; } - public static SWIGTYPE_p_switch_loadable_module_interface switch_loadable_module_create_module_interface(SWIGTYPE_p_apr_pool_t pool, string name) { + public static switch_loadable_module_interface switch_loadable_module_create_module_interface(SWIGTYPE_p_apr_pool_t pool, string name) { IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_create_module_interface(SWIGTYPE_p_apr_pool_t.getCPtr(pool), name); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } - public static SWIGTYPE_p_void switch_loadable_module_create_interface(SWIGTYPE_p_switch_loadable_module_interface mod, switch_module_interface_name_t iname) { - IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_create_interface(SWIGTYPE_p_switch_loadable_module_interface.getCPtr(mod), (int)iname); + public static SWIGTYPE_p_void switch_loadable_module_create_interface(switch_loadable_module_interface mod, switch_module_interface_name_t iname) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_create_interface(switch_loadable_module_interface.getCPtr(mod), (int)iname); SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); return ret; } @@ -2299,6 +2299,163 @@ public class freeswitch { return ret; } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); + return ret; + } + + public static void switch_loadable_module_shutdown() { + freeswitchPINVOKE.switch_loadable_module_shutdown(); + } + + public static switch_endpoint_interface switch_loadable_module_get_endpoint_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_endpoint_interface(name); + switch_endpoint_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_endpoint_interface(cPtr, false); + return ret; + } + + public static switch_codec_interface switch_loadable_module_get_codec_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_codec_interface(name); + switch_codec_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_interface(cPtr, false); + return ret; + } + + public static switch_dialplan_interface switch_loadable_module_get_dialplan_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_dialplan_interface(name); + switch_dialplan_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_dialplan_interface(cPtr, false); + return ret; + } + + public static switch_status_t switch_loadable_module_enumerate_available(string dir_path, SWIGTYPE_p_f_p_void_p_q_const__char__int callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_enumerate_available(dir_path, SWIGTYPE_p_f_p_void_p_q_const__char__int.getCPtr(callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static switch_status_t switch_loadable_module_enumerate_loaded(SWIGTYPE_p_f_p_void_p_q_const__char__int callback, SWIGTYPE_p_void user_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_enumerate_loaded(SWIGTYPE_p_f_p_void_p_q_const__char__int.getCPtr(callback), SWIGTYPE_p_void.getCPtr(user_data)); + return ret; + } + + public static switch_status_t switch_loadable_module_build_dynamic(string filename, SWIGTYPE_p_f_p_p_switch_loadable_module_interface_p_apr_pool_t__switch_status_t switch_module_load, SWIGTYPE_p_f_void__switch_status_t switch_module_runtime, SWIGTYPE_p_f_void__switch_status_t switch_module_shutdown, switch_bool_t runtime) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_build_dynamic(filename, SWIGTYPE_p_f_p_p_switch_loadable_module_interface_p_apr_pool_t__switch_status_t.getCPtr(switch_module_load), SWIGTYPE_p_f_void__switch_status_t.getCPtr(switch_module_runtime), SWIGTYPE_p_f_void__switch_status_t.getCPtr(switch_module_shutdown), (int)runtime); + return ret; + } + + public static switch_timer_interface switch_loadable_module_get_timer_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_timer_interface(name); + switch_timer_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_timer_interface(cPtr, false); + return ret; + } + + public static switch_application_interface switch_loadable_module_get_application_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_application_interface(name); + switch_application_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_application_interface(cPtr, false); + return ret; + } + + public static switch_api_interface switch_loadable_module_get_api_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_api_interface(name); + switch_api_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_api_interface(cPtr, false); + return ret; + } + + public static switch_file_interface switch_loadable_module_get_file_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_file_interface(name); + switch_file_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_file_interface(cPtr, false); + return ret; + } + + public static switch_speech_interface switch_loadable_module_get_speech_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_speech_interface(name); + switch_speech_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_speech_interface(cPtr, false); + return ret; + } + + public static switch_asr_interface switch_loadable_module_get_asr_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_asr_interface(name); + switch_asr_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_asr_interface(cPtr, false); + return ret; + } + + public static switch_directory_interface switch_loadable_module_get_directory_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_directory_interface(name); + switch_directory_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_directory_interface(cPtr, false); + return ret; + } + + public static switch_chat_interface switch_loadable_module_get_chat_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_chat_interface(name); + switch_chat_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_chat_interface(cPtr, false); + return ret; + } + + public static switch_say_interface switch_loadable_module_get_say_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_say_interface(name); + switch_say_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_say_interface(cPtr, false); + return ret; + } + + public static switch_management_interface switch_loadable_module_get_management_interface(string relative_oid) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_management_interface(relative_oid); + switch_management_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_management_interface(cPtr, false); + return ret; + } + + public static switch_limit_interface switch_loadable_module_get_limit_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_limit_interface(name); + switch_limit_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_limit_interface(cPtr, false); + return ret; + } + + public static int switch_loadable_module_get_codecs(SWIGTYPE_p_p_switch_codec_implementation array, int arraylen) { + int ret = freeswitchPINVOKE.switch_loadable_module_get_codecs(SWIGTYPE_p_p_switch_codec_implementation.getCPtr(array), arraylen); + return ret; + } + + public static int switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation array, int arraylen, ref string prefs, int preflen) { + int ret = freeswitchPINVOKE.switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation.getCPtr(array), arraylen, ref prefs, preflen); + return ret; + } + + public static switch_status_t switch_api_execute(string cmd, string arg, SWIGTYPE_p_switch_core_session session, switch_stream_handle stream) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_api_execute(cmd, arg, SWIGTYPE_p_switch_core_session.getCPtr(session), switch_stream_handle.getCPtr(stream)); + return ret; + } + + public static switch_status_t switch_loadable_module_load_module(string dir, string fname, switch_bool_t runtime, ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_load_module(dir, fname, (int)runtime, ref err); + return ret; + } + + public static switch_status_t switch_loadable_module_exists(string mod) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_exists(mod); + return ret; + } + + public static switch_status_t switch_loadable_module_unload_module(string dir, string fname, switch_bool_t force, ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_unload_module(dir, fname, (int)force, ref err); + return ret; + } + + public static uint switch_core_codec_next_id() { + uint ret = freeswitchPINVOKE.switch_core_codec_next_id(); + return ret; + } + + public static int switch_check_interval(uint rate, uint ptime) { + int ret = freeswitchPINVOKE.switch_check_interval(rate, ptime); + return ret; + } + + public static void switch_core_codec_add_implementation(SWIGTYPE_p_apr_pool_t pool, switch_codec_interface codec_interface, switch_codec_type_t codec_type, byte ianacode, string iananame, string fmtp, uint samples_per_second, uint actual_samples_per_second, int bits_per_second, int microseconds_per_packet, uint samples_per_packet, uint decoded_bytes_per_packet, uint encoded_bytes_per_packet, byte number_of_channels, int codec_frames_per_packet, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t init, SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t encode, SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t decode, SWIGTYPE_p_f_p_switch_codec__switch_status_t destroy) { + freeswitchPINVOKE.switch_core_codec_add_implementation(SWIGTYPE_p_apr_pool_t.getCPtr(pool), switch_codec_interface.getCPtr(codec_interface), (int)codec_type, ianacode, iananame, fmtp, samples_per_second, actual_samples_per_second, bits_per_second, microseconds_per_packet, samples_per_packet, decoded_bytes_per_packet, encoded_bytes_per_packet, number_of_channels, codec_frames_per_packet, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t.getCPtr(init), SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t.getCPtr(encode), SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t.getCPtr(decode), SWIGTYPE_p_f_p_switch_codec__switch_status_t.getCPtr(destroy)); + } + + public static switch_bool_t switch_core_codec_ready(switch_codec codec) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_core_codec_ready(switch_codec.getCPtr(codec)); + return ret; + } + public static void switch_console_loop() { freeswitchPINVOKE.switch_console_loop(); } @@ -2558,6 +2715,11 @@ public class freeswitch { return ret; } + public static uint switch_default_ptime(string name, uint number) { + uint ret = freeswitchPINVOKE.switch_default_ptime(name, number); + return ret; + } + public static string switch_sanitize_number(string number) { string ret = freeswitchPINVOKE.switch_sanitize_number(number); return ret; @@ -2761,11 +2923,44 @@ public class freeswitch { return ret; } + public static string switch_dow_int2str(int val) { + string ret = freeswitchPINVOKE.switch_dow_int2str(val); + return ret; + } + + public static int switch_dow_str2int(string exp) { + int ret = freeswitchPINVOKE.switch_dow_str2int(exp); + return ret; + } + + public static int switch_dow_cmp(string exp, int val) { + int ret = freeswitchPINVOKE.switch_dow_cmp(exp, val); + return ret; + } + public static int switch_number_cmp(string exp, int val) { int ret = freeswitchPINVOKE.switch_number_cmp(exp, val); return ret; } + public static int switch_tod_cmp(string exp, int val) { + int ret = freeswitchPINVOKE.switch_tod_cmp(exp, val); + return ret; + } + + public static int switch_fulldate_cmp(string exp, SWIGTYPE_p_switch_time_t ts) { + int ret = freeswitchPINVOKE.switch_fulldate_cmp(exp, SWIGTYPE_p_switch_time_t.getCPtr(ts)); + return ret; + } + + public static void switch_split_date(string exp, SWIGTYPE_p_int year, SWIGTYPE_p_int month, SWIGTYPE_p_int day) { + freeswitchPINVOKE.switch_split_date(exp, SWIGTYPE_p_int.getCPtr(year), SWIGTYPE_p_int.getCPtr(month), SWIGTYPE_p_int.getCPtr(day)); + } + + public static void switch_split_time(string exp, SWIGTYPE_p_int hour, SWIGTYPE_p_int min, SWIGTYPE_p_int sec) { + freeswitchPINVOKE.switch_split_time(exp, SWIGTYPE_p_int.getCPtr(hour), SWIGTYPE_p_int.getCPtr(min), SWIGTYPE_p_int.getCPtr(sec)); + } + public static int switch_split_user_domain(string arg0, ref string user, ref string domain) { int ret = freeswitchPINVOKE.switch_split_user_domain(arg0, ref user, ref domain); return ret; @@ -2938,6 +3133,16 @@ public class freeswitch { return ret; } + public static void switch_channel_set_origination_caller_profile(SWIGTYPE_p_switch_channel channel, switch_caller_profile caller_profile) { + freeswitchPINVOKE.switch_channel_set_origination_caller_profile(SWIGTYPE_p_switch_channel.getCPtr(channel), switch_caller_profile.getCPtr(caller_profile)); + } + + public static switch_caller_profile switch_channel_get_origination_caller_profile(SWIGTYPE_p_switch_channel channel) { + IntPtr cPtr = freeswitchPINVOKE.switch_channel_get_origination_caller_profile(SWIGTYPE_p_switch_channel.getCPtr(channel)); + switch_caller_profile ret = (cPtr == IntPtr.Zero) ? null : new switch_caller_profile(cPtr, false); + return ret; + } + public static string switch_channel_get_uuid(SWIGTYPE_p_switch_channel channel) { string ret = freeswitchPINVOKE.switch_channel_get_uuid(SWIGTYPE_p_switch_channel.getCPtr(channel)); return ret; @@ -3809,8 +4014,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex); + public static switch_status_t switch_play_and_get_digits(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, uint max_tries, uint timeout, string valid_terminators, string audio_file, string bad_input_audio_file, string var_name, string digit_buffer, uint digit_buffer_length, string digits_regex, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_play_and_get_digits(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, max_tries, timeout, valid_terminators, audio_file, bad_input_audio_file, var_name, digit_buffer, digit_buffer_length, digits_regex, digit_timeout); return ret; } @@ -4039,8 +4244,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators); + public static switch_status_t switch_ivr_read(SWIGTYPE_p_switch_core_session session, uint min_digits, uint max_digits, string prompt_audio_file, string var_name, string digit_buffer, SWIGTYPE_p_switch_size_t digit_buffer_length, uint timeout, string valid_terminators, uint digit_timeout) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_read(SWIGTYPE_p_switch_core_session.getCPtr(session), min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, SWIGTYPE_p_switch_size_t.getCPtr(digit_buffer_length), timeout, valid_terminators, digit_timeout); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -4390,6 +4595,11 @@ public class freeswitch { return ret; } + public static byte switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp rtp_session) { + byte ret = freeswitchPINVOKE.switch_rtp_check_auto_adj(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); + return ret; + } + public static switch_status_t switch_log_init(SWIGTYPE_p_apr_pool_t pool, switch_bool_t colorize) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_log_init(SWIGTYPE_p_apr_pool_t.getCPtr(pool), (int)colorize); return ret; @@ -4585,6 +4795,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_xml_reload(ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_reload(ref err); + return ret; + } + public static switch_status_t switch_xml_destroy() { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_xml_destroy(); return ret; @@ -5944,6 +6159,24 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_rtp_numbers_t")] public static extern void delete_switch_rtp_numbers_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_packet_count_set")] + public static extern void switch_rtcp_numbers_t_packet_count_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_packet_count_get")] + public static extern uint switch_rtcp_numbers_t_packet_count_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_octet_count_set")] + public static extern void switch_rtcp_numbers_t_octet_count_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_numbers_t_octet_count_get")] + public static extern uint switch_rtcp_numbers_t_octet_count_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_rtcp_numbers_t")] + public static extern IntPtr new_switch_rtcp_numbers_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_rtcp_numbers_t")] + public static extern void delete_switch_rtcp_numbers_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_inbound_set")] public static extern void switch_rtp_stats_t_inbound_set(HandleRef jarg1, HandleRef jarg2); @@ -5956,6 +6189,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_outbound_get")] public static extern IntPtr switch_rtp_stats_t_outbound_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_rtcp_set")] + public static extern void switch_rtp_stats_t_rtcp_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_stats_t_rtcp_get")] + public static extern IntPtr switch_rtp_stats_t_rtcp_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_rtp_stats_t")] public static extern IntPtr new_switch_rtp_stats_t(); @@ -6128,10 +6367,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_remote_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_set")] - public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_remote_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_remote_port_get")] - public static extern uint switch_t38_options_t_remote_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_remote_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_ip_set")] public static extern void switch_t38_options_t_local_ip_set(HandleRef jarg1, string jarg2); @@ -6140,10 +6379,10 @@ class freeswitchPINVOKE { public static extern string switch_t38_options_t_local_ip_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_set")] - public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, uint jarg2); + public static extern void switch_t38_options_t_local_port_set(HandleRef jarg1, ushort jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_local_port_get")] - public static extern uint switch_t38_options_t_local_port_get(HandleRef jarg1); + public static extern ushort switch_t38_options_t_local_port_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_t38_options_t")] public static extern IntPtr new_switch_t38_options_t(); @@ -7156,8 +7395,8 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_timer_destroy")] public static extern int switch_core_timer_destroy(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init")] - public static extern int switch_core_codec_init(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, HandleRef jarg8, HandleRef jarg9); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_init_with_bitrate")] + public static extern int switch_core_codec_init_with_bitrate(HandleRef jarg1, string jarg2, string jarg3, uint jarg4, int jarg5, int jarg6, uint jarg7, uint jarg8, HandleRef jarg9, HandleRef jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_copy")] public static extern int switch_core_codec_copy(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -7696,6 +7935,207 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_in_thread")] public static extern int switch_core_session_in_thread(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] + public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_get")] + public static extern string switch_loadable_module_interface_module_name_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_endpoint_interface_set")] + public static extern void switch_loadable_module_interface_endpoint_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_endpoint_interface_get")] + public static extern IntPtr switch_loadable_module_interface_endpoint_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_timer_interface_set")] + public static extern void switch_loadable_module_interface_timer_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_timer_interface_get")] + public static extern IntPtr switch_loadable_module_interface_timer_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_dialplan_interface_set")] + public static extern void switch_loadable_module_interface_dialplan_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_dialplan_interface_get")] + public static extern IntPtr switch_loadable_module_interface_dialplan_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_codec_interface_set")] + public static extern void switch_loadable_module_interface_codec_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_codec_interface_get")] + public static extern IntPtr switch_loadable_module_interface_codec_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_application_interface_set")] + public static extern void switch_loadable_module_interface_application_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_application_interface_get")] + public static extern IntPtr switch_loadable_module_interface_application_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_api_interface_set")] + public static extern void switch_loadable_module_interface_api_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_api_interface_get")] + public static extern IntPtr switch_loadable_module_interface_api_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_file_interface_set")] + public static extern void switch_loadable_module_interface_file_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_file_interface_get")] + public static extern IntPtr switch_loadable_module_interface_file_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_speech_interface_set")] + public static extern void switch_loadable_module_interface_speech_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_speech_interface_get")] + public static extern IntPtr switch_loadable_module_interface_speech_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_directory_interface_set")] + public static extern void switch_loadable_module_interface_directory_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_directory_interface_get")] + public static extern IntPtr switch_loadable_module_interface_directory_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_chat_interface_set")] + public static extern void switch_loadable_module_interface_chat_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_chat_interface_get")] + public static extern IntPtr switch_loadable_module_interface_chat_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_say_interface_set")] + public static extern void switch_loadable_module_interface_say_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_say_interface_get")] + public static extern IntPtr switch_loadable_module_interface_say_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_asr_interface_set")] + public static extern void switch_loadable_module_interface_asr_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_asr_interface_get")] + public static extern IntPtr switch_loadable_module_interface_asr_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_management_interface_set")] + public static extern void switch_loadable_module_interface_management_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_management_interface_get")] + public static extern IntPtr switch_loadable_module_interface_management_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_limit_interface_set")] + public static extern void switch_loadable_module_interface_limit_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_limit_interface_get")] + public static extern IntPtr switch_loadable_module_interface_limit_interface_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_rwlock_set")] + public static extern void switch_loadable_module_interface_rwlock_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_rwlock_get")] + public static extern IntPtr switch_loadable_module_interface_rwlock_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_refs_set")] + public static extern void switch_loadable_module_interface_refs_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_refs_get")] + public static extern int switch_loadable_module_interface_refs_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_pool_set")] + public static extern void switch_loadable_module_interface_pool_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_pool_get")] + public static extern IntPtr switch_loadable_module_interface_pool_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_loadable_module_interface")] + public static extern IntPtr new_switch_loadable_module_interface(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_loadable_module_interface")] + public static extern void delete_switch_loadable_module_interface(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_init")] + public static extern int switch_loadable_module_init(int jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_shutdown")] + public static extern void switch_loadable_module_shutdown(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_endpoint_interface")] + public static extern IntPtr switch_loadable_module_get_endpoint_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_codec_interface")] + public static extern IntPtr switch_loadable_module_get_codec_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_dialplan_interface")] + public static extern IntPtr switch_loadable_module_get_dialplan_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_enumerate_available")] + public static extern int switch_loadable_module_enumerate_available(string jarg1, HandleRef jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_enumerate_loaded")] + public static extern int switch_loadable_module_enumerate_loaded(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_build_dynamic")] + public static extern int switch_loadable_module_build_dynamic(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, int jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_timer_interface")] + public static extern IntPtr switch_loadable_module_get_timer_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_application_interface")] + public static extern IntPtr switch_loadable_module_get_application_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_api_interface")] + public static extern IntPtr switch_loadable_module_get_api_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_file_interface")] + public static extern IntPtr switch_loadable_module_get_file_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_speech_interface")] + public static extern IntPtr switch_loadable_module_get_speech_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_asr_interface")] + public static extern IntPtr switch_loadable_module_get_asr_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_directory_interface")] + public static extern IntPtr switch_loadable_module_get_directory_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_chat_interface")] + public static extern IntPtr switch_loadable_module_get_chat_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_say_interface")] + public static extern IntPtr switch_loadable_module_get_say_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_management_interface")] + public static extern IntPtr switch_loadable_module_get_management_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_limit_interface")] + public static extern IntPtr switch_loadable_module_get_limit_interface(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_codecs")] + public static extern int switch_loadable_module_get_codecs(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_codecs_sorted")] + public static extern int switch_loadable_module_get_codecs_sorted(HandleRef jarg1, int jarg2, ref string jarg3, int jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_api_execute")] + public static extern int switch_api_execute(string jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_load_module")] + public static extern int switch_loadable_module_load_module(string jarg1, string jarg2, int jarg3, ref string jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_exists")] + public static extern int switch_loadable_module_exists(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_unload_module")] + public static extern int switch_loadable_module_unload_module(string jarg1, string jarg2, int jarg3, ref string jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_next_id")] + public static extern uint switch_core_codec_next_id(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_check_interval")] + public static extern int switch_check_interval(uint jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_add_implementation")] + public static extern void switch_core_codec_add_implementation(HandleRef jarg1, HandleRef jarg2, int jarg3, byte jarg4, string jarg5, string jarg6, uint jarg7, uint jarg8, int jarg9, int jarg10, uint jarg11, uint jarg12, uint jarg13, byte jarg14, int jarg15, HandleRef jarg16, HandleRef jarg17, HandleRef jarg18, HandleRef jarg19); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_ready")] + public static extern int switch_core_codec_ready(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CMD_CHUNK_LEN_get")] public static extern int SWITCH_CMD_CHUNK_LEN_get(); @@ -7858,6 +8298,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_char_to_rfc2833")] public static extern byte switch_char_to_rfc2833(char jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_default_ptime")] + public static extern uint switch_default_ptime(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_sanitize_number")] public static extern string switch_sanitize_number(string jarg1); @@ -7978,9 +8421,30 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_network_list_validate_ip_token")] public static extern int switch_network_list_validate_ip_token(HandleRef jarg1, uint jarg2, ref string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_int2str")] + public static extern string switch_dow_int2str(int jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_str2int")] + public static extern int switch_dow_str2int(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dow_cmp")] + public static extern int switch_dow_cmp(string jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_number_cmp")] public static extern int switch_number_cmp(string jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_tod_cmp")] + public static extern int switch_tod_cmp(string jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_fulldate_cmp")] + public static extern int switch_fulldate_cmp(string jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_date")] + public static extern void switch_split_date(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_time")] + public static extern void switch_split_time(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_split_user_domain")] public static extern int switch_split_user_domain(string jarg1, ref string jarg2, ref string jarg3); @@ -8146,6 +8610,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_originatee_caller_profile_get")] public static extern IntPtr switch_caller_profile_originatee_caller_profile_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_origination_caller_profile_set")] + public static extern void switch_caller_profile_origination_caller_profile_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_origination_caller_profile_get")] + public static extern IntPtr switch_caller_profile_origination_caller_profile_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_hunt_caller_profile_set")] public static extern void switch_caller_profile_hunt_caller_profile_set(HandleRef jarg1, HandleRef jarg2); @@ -9907,101 +10377,11 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_directory_handle")] public static extern void delete_switch_directory_handle(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_set")] - public static extern void switch_codec_settings_quality_set(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_set")] + public static extern void switch_codec_settings_unused_set(HandleRef jarg1, int jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_quality_get")] - public static extern int switch_codec_settings_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_set")] - public static extern void switch_codec_settings_complexity_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_complexity_get")] - public static extern int switch_codec_settings_complexity_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_set")] - public static extern void switch_codec_settings_enhancement_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_enhancement_get")] - public static extern int switch_codec_settings_enhancement_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_set")] - public static extern void switch_codec_settings_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vad_get")] - public static extern int switch_codec_settings_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_set")] - public static extern void switch_codec_settings_vbr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_get")] - public static extern int switch_codec_settings_vbr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_set")] - public static extern void switch_codec_settings_vbr_quality_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_vbr_quality_get")] - public static extern float switch_codec_settings_vbr_quality_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_set")] - public static extern void switch_codec_settings_abr_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_abr_get")] - public static extern int switch_codec_settings_abr_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_set")] - public static extern void switch_codec_settings_dtx_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_dtx_get")] - public static extern int switch_codec_settings_dtx_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_set")] - public static extern void switch_codec_settings_preproc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_preproc_get")] - public static extern int switch_codec_settings_preproc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_set")] - public static extern void switch_codec_settings_pp_vad_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_vad_get")] - public static extern int switch_codec_settings_pp_vad_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_set")] - public static extern void switch_codec_settings_pp_agc_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_get")] - public static extern int switch_codec_settings_pp_agc_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_set")] - public static extern void switch_codec_settings_pp_agc_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_agc_level_get")] - public static extern float switch_codec_settings_pp_agc_level_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_set")] - public static extern void switch_codec_settings_pp_denoise_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_denoise_get")] - public static extern int switch_codec_settings_pp_denoise_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_set")] - public static extern void switch_codec_settings_pp_dereverb_set(HandleRef jarg1, int jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_get")] - public static extern int switch_codec_settings_pp_dereverb_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_set")] - public static extern void switch_codec_settings_pp_dereverb_decay_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_decay_get")] - public static extern float switch_codec_settings_pp_dereverb_decay_get(HandleRef jarg1); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_set")] - public static extern void switch_codec_settings_pp_dereverb_level_set(HandleRef jarg1, float jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_pp_dereverb_level_get")] - public static extern float switch_codec_settings_pp_dereverb_level_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_settings_unused_get")] + public static extern int switch_codec_settings_unused_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_settings")] public static extern IntPtr new_switch_codec_settings(); @@ -10009,6 +10389,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_settings")] public static extern void delete_switch_codec_settings(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_set")] + public static extern void switch_codec_fmtp_actual_samples_per_second_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_actual_samples_per_second_get")] + public static extern uint switch_codec_fmtp_actual_samples_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_set")] + public static extern void switch_codec_fmtp_bits_per_second_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_bits_per_second_get")] + public static extern int switch_codec_fmtp_bits_per_second_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_set")] + public static extern void switch_codec_fmtp_microseconds_per_packet_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_microseconds_per_packet_get")] + public static extern int switch_codec_fmtp_microseconds_per_packet_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_set")] + public static extern void switch_codec_fmtp_private_info_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_private_info_get")] + public static extern IntPtr switch_codec_fmtp_private_info_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_codec_fmtp")] + public static extern IntPtr new_switch_codec_fmtp(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_codec_fmtp")] + public static extern void delete_switch_codec_fmtp(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_interface_set")] public static extern void switch_codec_codec_interface_set(HandleRef jarg1, HandleRef jarg2); @@ -10033,12 +10443,6 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_fmtp_out_get")] public static extern string switch_codec_fmtp_out_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_set")] - public static extern void switch_codec_codec_settings_set(HandleRef jarg1, HandleRef jarg2); - - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_codec_settings_get")] - public static extern IntPtr switch_codec_codec_settings_get(HandleRef jarg1); - [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_flags_set")] public static extern void switch_codec_flags_set(HandleRef jarg1, uint jarg2); @@ -10219,6 +10623,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_implementations_get")] public static extern IntPtr switch_codec_interface_implementations_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_set")] + public static extern void switch_codec_interface_parse_fmtp_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_parse_fmtp_get")] + public static extern IntPtr switch_codec_interface_parse_fmtp_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_codec_interface_codec_id_set")] public static extern void switch_codec_interface_codec_id_set(HandleRef jarg1, uint jarg2); @@ -10528,6 +10938,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_originatee_caller_profile")] public static extern IntPtr switch_channel_get_originatee_caller_profile(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_origination_caller_profile")] + public static extern void switch_channel_set_origination_caller_profile(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_origination_caller_profile")] + public static extern IntPtr switch_channel_get_origination_caller_profile(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_uuid")] public static extern string switch_channel_get_uuid(HandleRef jarg1); @@ -11330,7 +11746,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_record_file(HandleRef jarg1, HandleRef jarg2, string jarg3, HandleRef jarg4, uint jarg5); [DllImport("mod_managed", EntryPoint="CSharp_switch_play_and_get_digits")] - public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12); + public static extern int switch_play_and_get_digits(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, uint jarg11, string jarg12, uint jarg13); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_speak_text_handle")] public static extern int switch_ivr_speak_text_handle(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, string jarg5, HandleRef jarg6); @@ -11468,7 +11884,7 @@ class freeswitchPINVOKE { public static extern int switch_ivr_wait_for_answer(HandleRef jarg1, HandleRef jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_read")] - public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9); + public static extern int switch_ivr_read(HandleRef jarg1, uint jarg2, uint jarg3, string jarg4, string jarg5, string jarg6, HandleRef jarg7, uint jarg8, string jarg9, uint jarg10); [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_block_dtmf_session")] public static extern int switch_ivr_block_dtmf_session(HandleRef jarg1); @@ -11740,6 +12156,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_stats")] public static extern IntPtr switch_rtp_get_stats(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_check_auto_adj")] + public static extern byte switch_rtp_check_auto_adj(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_log_node_t_data_set")] public static extern void switch_log_node_t_data_set(HandleRef jarg1, string jarg2); @@ -11986,6 +12405,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_init")] public static extern int switch_xml_init(HandleRef jarg1, ref string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_reload")] + public static extern int switch_xml_reload(ref string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_xml_destroy")] public static extern int switch_xml_destroy(); @@ -12872,10 +13294,10 @@ class freeswitchPINVOKE { public static extern int CoreSession_Transfer(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_read")] - public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6); + public static extern string CoreSession_read(HandleRef jarg1, int jarg2, int jarg3, string jarg4, int jarg5, string jarg6, int jarg7); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_PlayAndGetDigits")] - public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10); + public static extern string CoreSession_PlayAndGetDigits(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, string jarg6, string jarg7, string jarg8, string jarg9, string jarg10, int jarg11); [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_StreamFile")] public static extern int CoreSession_StreamFile(HandleRef jarg1, string jarg2, int jarg3); @@ -13585,6 +14007,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_q_const__char_p_switch_core_session_p_switch_stream_handle__switch_status_t { private HandleRef swigCPtr; @@ -15475,6 +15927,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_void_p_q_const__char__int { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_void_p_q_const__char__int(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_void_p_q_const__char__int() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_void_p_q_const__char__int 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_void__void { private HandleRef swigCPtr; @@ -15955,6 +16437,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_codec_implementation { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_codec_implementation(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_codec_implementation() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_codec_implementation 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_console_callback_match { private HandleRef swigCPtr; @@ -17185,36 +17697,6 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; -public class SWIGTYPE_p_switch_loadable_module_interface { - private HandleRef swigCPtr; - - internal SWIGTYPE_p_switch_loadable_module_interface(IntPtr cPtr, bool futureUse) { - swigCPtr = new HandleRef(this, cPtr); - } - - protected SWIGTYPE_p_switch_loadable_module_interface() { - swigCPtr = new HandleRef(null, IntPtr.Zero); - } - - internal static HandleRef getCPtr(SWIGTYPE_p_switch_loadable_module_interface 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_media_bug { private HandleRef swigCPtr; @@ -17997,13 +18479,13 @@ public class switch_api_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_api_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_api_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_api_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -18177,13 +18659,13 @@ public class switch_application_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_application_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_application_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_application_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -18669,13 +19151,13 @@ public class switch_asr_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_asr_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_asr_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_asr_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -20148,6 +20630,17 @@ public class switch_caller_profile : IDisposable { } } + public switch_caller_profile origination_caller_profile { + set { + freeswitchPINVOKE.switch_caller_profile_origination_caller_profile_set(swigCPtr, switch_caller_profile.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_caller_profile_origination_caller_profile_get(swigCPtr); + switch_caller_profile ret = (cPtr == IntPtr.Zero) ? null : new switch_caller_profile(cPtr, false); + return ret; + } + } + public switch_caller_profile hunt_caller_profile { set { freeswitchPINVOKE.switch_caller_profile_hunt_caller_profile_set(swigCPtr, switch_caller_profile.getCPtr(value)); @@ -20635,13 +21128,13 @@ public class switch_chat_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_chat_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_chat_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_chat_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -20746,17 +21239,6 @@ public class switch_codec : IDisposable { } } - public switch_codec_settings codec_settings { - set { - freeswitchPINVOKE.switch_codec_codec_settings_set(swigCPtr, switch_codec_settings.getCPtr(value)); - } - get { - IntPtr cPtr = freeswitchPINVOKE.switch_codec_codec_settings_get(swigCPtr); - switch_codec_settings ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_settings(cPtr, false); - return ret; - } - } - public uint flags { set { freeswitchPINVOKE.switch_codec_flags_set(swigCPtr, value); @@ -20863,6 +21345,94 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class switch_codec_fmtp : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_codec_fmtp(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_codec_fmtp obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_codec_fmtp() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_codec_fmtp(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public uint actual_samples_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_codec_fmtp_actual_samples_per_second_get(swigCPtr); + return ret; + } + } + + public int bits_per_second { + set { + freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_bits_per_second_get(swigCPtr); + return ret; + } + } + + public int microseconds_per_packet { + set { + freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_codec_fmtp_microseconds_per_packet_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_void private_info { + set { + freeswitchPINVOKE.switch_codec_fmtp_private_info_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_fmtp_private_info_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + + public switch_codec_fmtp() : this(freeswitchPINVOKE.new_switch_codec_fmtp(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class switch_codec_implementation : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; @@ -21164,6 +21734,17 @@ public class switch_codec_interface : IDisposable { } } + public SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t parse_fmtp { + set { + freeswitchPINVOKE.switch_codec_interface_parse_fmtp_set(swigCPtr, SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_codec_interface_parse_fmtp_get(swigCPtr); + SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_q_const__char_p_switch_codec_fmtp__switch_status_t(cPtr, false); + return ret; + } + } + public uint codec_id { set { freeswitchPINVOKE.switch_codec_interface_codec_id_set(swigCPtr, value); @@ -21206,13 +21787,13 @@ public class switch_codec_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_codec_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_codec_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_codec_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -21275,162 +21856,12 @@ public class switch_codec_settings : IDisposable { } } - public int quality { + public int unused { set { - freeswitchPINVOKE.switch_codec_settings_quality_set(swigCPtr, value); + freeswitchPINVOKE.switch_codec_settings_unused_set(swigCPtr, value); } get { - int ret = freeswitchPINVOKE.switch_codec_settings_quality_get(swigCPtr); - return ret; - } - } - - public int complexity { - set { - freeswitchPINVOKE.switch_codec_settings_complexity_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_complexity_get(swigCPtr); - return ret; - } - } - - public int enhancement { - set { - freeswitchPINVOKE.switch_codec_settings_enhancement_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_enhancement_get(swigCPtr); - return ret; - } - } - - public int vad { - set { - freeswitchPINVOKE.switch_codec_settings_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vad_get(swigCPtr); - return ret; - } - } - - public int vbr { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_vbr_get(swigCPtr); - return ret; - } - } - - public float vbr_quality { - set { - freeswitchPINVOKE.switch_codec_settings_vbr_quality_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_vbr_quality_get(swigCPtr); - return ret; - } - } - - public int abr { - set { - freeswitchPINVOKE.switch_codec_settings_abr_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_abr_get(swigCPtr); - return ret; - } - } - - public int dtx { - set { - freeswitchPINVOKE.switch_codec_settings_dtx_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_dtx_get(swigCPtr); - return ret; - } - } - - public int preproc { - set { - freeswitchPINVOKE.switch_codec_settings_preproc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_preproc_get(swigCPtr); - return ret; - } - } - - public int pp_vad { - set { - freeswitchPINVOKE.switch_codec_settings_pp_vad_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_vad_get(swigCPtr); - return ret; - } - } - - public int pp_agc { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_get(swigCPtr); - return ret; - } - } - - public float pp_agc_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_agc_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_agc_level_get(swigCPtr); - return ret; - } - } - - public int pp_denoise { - set { - freeswitchPINVOKE.switch_codec_settings_pp_denoise_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_denoise_get(swigCPtr); - return ret; - } - } - - public int pp_dereverb { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_set(swigCPtr, value); - } - get { - int ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_decay { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_decay_get(swigCPtr); - return ret; - } - } - - public float pp_dereverb_level { - set { - freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_set(swigCPtr, value); - } - get { - float ret = freeswitchPINVOKE.switch_codec_settings_pp_dereverb_level_get(swigCPtr); + int ret = freeswitchPINVOKE.switch_codec_settings_unused_get(swigCPtr); return ret; } } @@ -21779,7 +22210,8 @@ namespace FreeSWITCH.Native { SCF_USE_CLOCK_RT = (1 << 10), SCF_VERBOSE_EVENTS = (1 << 11), SCF_USE_WIN32_MONOTONIC = (1 << 12), - SCF_AUTO_SCHEMAS = (1 << 13) + SCF_AUTO_SCHEMAS = (1 << 13), + SCF_MINIMAL = (1 << 14) } } @@ -22399,13 +22831,13 @@ public class switch_dialplan_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_dialplan_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_dialplan_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_dialplan_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -22847,13 +23279,13 @@ public class switch_directory_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_directory_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_directory_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_directory_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -23092,13 +23524,13 @@ public class switch_endpoint_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_endpoint_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_endpoint_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_endpoint_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -24157,13 +24589,13 @@ public class switch_file_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_file_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_file_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_file_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -25971,13 +26403,13 @@ public class switch_limit_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_limit_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_limit_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_limit_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -26109,6 +26541,249 @@ public class switch_loadable_module_function_table_t : IDisposable { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_loadable_module_interface : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_loadable_module_interface(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_loadable_module_interface obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_loadable_module_interface() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_loadable_module_interface(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public string module_name { + set { + freeswitchPINVOKE.switch_loadable_module_interface_module_name_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_loadable_module_interface_module_name_get(swigCPtr); + return ret; + } + } + + public switch_endpoint_interface endpoint_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_endpoint_interface_set(swigCPtr, switch_endpoint_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_endpoint_interface_get(swigCPtr); + switch_endpoint_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_endpoint_interface(cPtr, false); + return ret; + } + } + + public switch_timer_interface timer_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_timer_interface_set(swigCPtr, switch_timer_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_timer_interface_get(swigCPtr); + switch_timer_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_timer_interface(cPtr, false); + return ret; + } + } + + public switch_dialplan_interface dialplan_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_dialplan_interface_set(swigCPtr, switch_dialplan_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_dialplan_interface_get(swigCPtr); + switch_dialplan_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_dialplan_interface(cPtr, false); + return ret; + } + } + + public switch_codec_interface codec_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_codec_interface_set(swigCPtr, switch_codec_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_codec_interface_get(swigCPtr); + switch_codec_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_codec_interface(cPtr, false); + return ret; + } + } + + public switch_application_interface application_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_application_interface_set(swigCPtr, switch_application_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_application_interface_get(swigCPtr); + switch_application_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_application_interface(cPtr, false); + return ret; + } + } + + public switch_api_interface api_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_api_interface_set(swigCPtr, switch_api_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_api_interface_get(swigCPtr); + switch_api_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_api_interface(cPtr, false); + return ret; + } + } + + public switch_file_interface file_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_file_interface_set(swigCPtr, switch_file_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_file_interface_get(swigCPtr); + switch_file_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_file_interface(cPtr, false); + return ret; + } + } + + public switch_speech_interface speech_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_speech_interface_set(swigCPtr, switch_speech_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_speech_interface_get(swigCPtr); + switch_speech_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_speech_interface(cPtr, false); + return ret; + } + } + + public switch_directory_interface directory_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_directory_interface_set(swigCPtr, switch_directory_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_directory_interface_get(swigCPtr); + switch_directory_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_directory_interface(cPtr, false); + return ret; + } + } + + public switch_chat_interface chat_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_chat_interface_set(swigCPtr, switch_chat_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_chat_interface_get(swigCPtr); + switch_chat_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_chat_interface(cPtr, false); + return ret; + } + } + + public switch_say_interface say_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_say_interface_set(swigCPtr, switch_say_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_say_interface_get(swigCPtr); + switch_say_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_say_interface(cPtr, false); + return ret; + } + } + + public switch_asr_interface asr_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_asr_interface_set(swigCPtr, switch_asr_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_asr_interface_get(swigCPtr); + switch_asr_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_asr_interface(cPtr, false); + return ret; + } + } + + public switch_management_interface management_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_management_interface_set(swigCPtr, switch_management_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_management_interface_get(swigCPtr); + switch_management_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_management_interface(cPtr, false); + return ret; + } + } + + public switch_limit_interface limit_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_limit_interface_set(swigCPtr, switch_limit_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_limit_interface_get(swigCPtr); + switch_limit_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_limit_interface(cPtr, false); + return ret; + } + } + + public SWIGTYPE_p_switch_thread_rwlock_t rwlock { + set { + freeswitchPINVOKE.switch_loadable_module_interface_rwlock_set(swigCPtr, SWIGTYPE_p_switch_thread_rwlock_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_rwlock_get(swigCPtr); + SWIGTYPE_p_switch_thread_rwlock_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_thread_rwlock_t(cPtr, false); + return ret; + } + } + + public int refs { + set { + freeswitchPINVOKE.switch_loadable_module_interface_refs_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_loadable_module_interface_refs_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_apr_pool_t pool { + set { + freeswitchPINVOKE.switch_loadable_module_interface_pool_set(swigCPtr, SWIGTYPE_p_apr_pool_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_pool_get(swigCPtr); + SWIGTYPE_p_apr_pool_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_apr_pool_t(cPtr, false); + return ret; + } + } + + public switch_loadable_module_interface() : this(freeswitchPINVOKE.new_switch_loadable_module_interface(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_log_level_t { SWITCH_LOG_DEBUG10 = 110, SWITCH_LOG_DEBUG9 = 109, @@ -26382,13 +27057,13 @@ public class switch_management_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_management_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_management_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_management_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -26680,6 +27355,73 @@ public class switch_rtcp_hdr_t : IDisposable { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_rtcp_numbers_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_rtcp_numbers_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_rtcp_numbers_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_rtcp_numbers_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_rtcp_numbers_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public uint packet_count { + set { + freeswitchPINVOKE.switch_rtcp_numbers_t_packet_count_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_numbers_t_packet_count_get(swigCPtr); + return ret; + } + } + + public uint octet_count { + set { + freeswitchPINVOKE.switch_rtcp_numbers_t_octet_count_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_numbers_t_octet_count_get(swigCPtr); + return ret; + } + } + + public switch_rtcp_numbers_t() : this(freeswitchPINVOKE.new_switch_rtcp_numbers_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_rtp_bug_flag_t { RTP_BUG_NONE = 0, RTP_BUG_CISCO_SKIP_MARK_BIT_2833 = (1 << 0), @@ -27242,6 +27984,17 @@ public class switch_rtp_stats_t : IDisposable { } } + public switch_rtcp_numbers_t rtcp { + set { + freeswitchPINVOKE.switch_rtp_stats_t_rtcp_set(swigCPtr, switch_rtcp_numbers_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_rtp_stats_t_rtcp_get(swigCPtr); + switch_rtcp_numbers_t ret = (cPtr == IntPtr.Zero) ? null : new switch_rtcp_numbers_t(cPtr, false); + return ret; + } + } + public switch_rtp_stats_t() : this(freeswitchPINVOKE.new_switch_rtp_stats_t(), true) { } @@ -27436,13 +28189,13 @@ public class switch_say_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_say_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_say_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_say_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -28117,13 +28870,13 @@ public class switch_speech_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_speech_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_speech_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_speech_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } @@ -28738,12 +29491,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint remote_port { + public ushort remote_port { set { freeswitchPINVOKE.switch_t38_options_t_remote_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_remote_port_get(swigCPtr); return ret; } } @@ -28758,12 +29511,12 @@ public class switch_t38_options_t : IDisposable { } } - public uint local_port { + public ushort local_port { set { freeswitchPINVOKE.switch_t38_options_t_local_port_set(swigCPtr, value); } get { - uint ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); + ushort ret = freeswitchPINVOKE.switch_t38_options_t_local_port_get(swigCPtr); return ret; } } @@ -29120,13 +29873,13 @@ public class switch_timer_interface : IDisposable { } } - public SWIGTYPE_p_switch_loadable_module_interface parent { + public switch_loadable_module_interface parent { set { - freeswitchPINVOKE.switch_timer_interface_parent_set(swigCPtr, SWIGTYPE_p_switch_loadable_module_interface.getCPtr(value)); + freeswitchPINVOKE.switch_timer_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_timer_interface_parent_get(swigCPtr); - SWIGTYPE_p_switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_loadable_module_interface(cPtr, false); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); return ret; } } diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp index 5ba899fbf8..370c88bc99 100644 --- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp +++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp @@ -6637,6 +6637,7 @@ XS(_wrap_CoreSession_read) { char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -6652,11 +6653,13 @@ XS(_wrap_CoreSession_read) { int res6 ; char *buf6 = 0 ; int alloc6 = 0 ; + int val7 ; + int ecode7 = 0 ; int argvi = 0; dXSARGS; - if ((items < 6) || (items > 6)) { - SWIG_croak("Usage: CoreSession_read(self,min_digits,max_digits,prompt_audio_file,timeout,valid_terminators);"); + if ((items < 6) || (items > 7)) { + SWIG_croak("Usage: CoreSession_read(self,min_digits,max_digits,prompt_audio_file,timeout,valid_terminators,digit_timeout);"); } res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { @@ -6688,7 +6691,14 @@ XS(_wrap_CoreSession_read) { SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "CoreSession_read" "', argument " "6"" of type '" "char const *""'"); } arg6 = reinterpret_cast< char * >(buf6); - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + if (items > 6) { + ecode7 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(6), &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "CoreSession_read" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + } + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; @@ -6696,6 +6706,7 @@ XS(_wrap_CoreSession_read) { if (alloc4 == SWIG_NEWOBJ) delete[] buf4; if (alloc6 == SWIG_NEWOBJ) delete[] buf6; + XSRETURN(argvi); fail: @@ -6704,6 +6715,7 @@ XS(_wrap_CoreSession_read) { if (alloc4 == SWIG_NEWOBJ) delete[] buf4; if (alloc6 == SWIG_NEWOBJ) delete[] buf6; + SWIG_croak_null(); } } @@ -6721,6 +6733,7 @@ XS(_wrap_CoreSession_playAndGetDigits) { char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -6747,11 +6760,13 @@ XS(_wrap_CoreSession_playAndGetDigits) { int res10 ; char *buf10 = 0 ; int alloc10 = 0 ; + int val11 ; + int ecode11 = 0 ; int argvi = 0; dXSARGS; - if ((items < 9) || (items > 10)) { - SWIG_croak("Usage: CoreSession_playAndGetDigits(self,min_digits,max_digits,max_tries,timeout,terminators,audio_files,bad_input_audio_files,digits_regex,var_name);"); + if ((items < 9) || (items > 11)) { + SWIG_croak("Usage: CoreSession_playAndGetDigits(self,min_digits,max_digits,max_tries,timeout,terminators,audio_files,bad_input_audio_files,digits_regex,var_name,digit_timeout);"); } res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { @@ -6805,7 +6820,14 @@ XS(_wrap_CoreSession_playAndGetDigits) { } arg10 = reinterpret_cast< char * >(buf10); } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + if (items > 10) { + ecode11 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(10), &val11); + if (!SWIG_IsOK(ecode11)) { + SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "CoreSession_playAndGetDigits" "', argument " "11"" of type '" "int""'"); + } + arg11 = static_cast< int >(val11); + } + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; @@ -6817,6 +6839,7 @@ XS(_wrap_CoreSession_playAndGetDigits) { if (alloc8 == SWIG_NEWOBJ) delete[] buf8; if (alloc9 == SWIG_NEWOBJ) delete[] buf9; if (alloc10 == SWIG_NEWOBJ) delete[] buf10; + XSRETURN(argvi); fail: @@ -6829,6 +6852,7 @@ XS(_wrap_CoreSession_playAndGetDigits) { if (alloc8 == SWIG_NEWOBJ) delete[] buf8; if (alloc9 == SWIG_NEWOBJ) delete[] buf9; if (alloc10 == SWIG_NEWOBJ) delete[] buf10; + SWIG_croak_null(); } } diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index 8dc32a2dca..0907bec98f 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -7025,6 +7025,7 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb char *arg4 = (char *) 0 ; int arg5 ; char *arg6 = (char *) 0 ; + int arg7 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -7040,14 +7041,17 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb int res6 ; char *buf6 = 0 ; int alloc6 = 0 ; + int val7 ; + int ecode7 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; PyObject * obj5 = 0 ; + PyObject * obj6 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOOO:CoreSession_read",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOOOOO|O:CoreSession_read",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_read" "', argument " "1"" of type '" "CoreSession *""'"); @@ -7078,7 +7082,14 @@ SWIGINTERN PyObject *_wrap_CoreSession_read(PyObject *SWIGUNUSEDPARM(self), PyOb SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "CoreSession_read" "', argument " "6"" of type '" "char const *""'"); } arg6 = reinterpret_cast< char * >(buf6); - result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6); + if (obj6) { + ecode7 = SWIG_AsVal_int(obj6, &val7); + if (!SWIG_IsOK(ecode7)) { + SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "CoreSession_read" "', argument " "7"" of type '" "int""'"); + } + arg7 = static_cast< int >(val7); + } + result = (char *)(arg1)->read(arg2,arg3,(char const *)arg4,arg5,(char const *)arg6,arg7); resultobj = SWIG_FromCharPtr((const char *)result); if (alloc4 == SWIG_NEWOBJ) delete[] buf4; if (alloc6 == SWIG_NEWOBJ) delete[] buf6; @@ -7102,6 +7113,7 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM char *arg8 = (char *) 0 ; char *arg9 = (char *) 0 ; char *arg10 = (char *) NULL ; + int arg11 = (int) 0 ; char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; @@ -7128,6 +7140,8 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM int res10 ; char *buf10 = 0 ; int alloc10 = 0 ; + int val11 ; + int ecode11 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; @@ -7138,8 +7152,9 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM PyObject * obj7 = 0 ; PyObject * obj8 = 0 ; PyObject * obj9 = 0 ; + PyObject * obj10 = 0 ; - if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO|O:CoreSession_playAndGetDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail; + if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO|OO:CoreSession_playAndGetDigits",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_playAndGetDigits" "', argument " "1"" of type '" "CoreSession *""'"); @@ -7192,7 +7207,14 @@ SWIGINTERN PyObject *_wrap_CoreSession_playAndGetDigits(PyObject *SWIGUNUSEDPARM } arg10 = reinterpret_cast< char * >(buf10); } - result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10); + if (obj10) { + ecode11 = SWIG_AsVal_int(obj10, &val11); + if (!SWIG_IsOK(ecode11)) { + SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "CoreSession_playAndGetDigits" "', argument " "11"" of type '" "int""'"); + } + arg11 = static_cast< int >(val11); + } + result = (char *)(arg1)->playAndGetDigits(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,(char const *)arg10,arg11); resultobj = SWIG_FromCharPtr((const char *)result); if (alloc6 == SWIG_NEWOBJ) delete[] buf6; if (alloc7 == SWIG_NEWOBJ) delete[] buf7; diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index 83f9f72c09..84643dcd0b 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -264,7 +264,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) if (globals.encode == ENCODING_TEXTXML) { headers = curl_slist_append(headers, "Content-Type: text/xml"); } else if (globals.encode) { - switch_size_t need_bytes = strlen(xml_text) * 3; + switch_size_t need_bytes = strlen(xml_text) * 3 + 1; xml_text_escaped = malloc(need_bytes); switch_assert(xml_text_escaped); diff --git a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c index 34873f78d7..2e9a1a3a1a 100644 --- a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c +++ b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c @@ -275,7 +275,6 @@ static abyss_bool is_authorized(const TSession * r, const char *command) err = 686; - status = "EXECUTION OF SPECIFIED API COMMAND NOT PERMITTED IN USER ACCOUNT"; if (!user_attributes(user, domain_name, NULL, NULL, NULL, &allowed_commands)) { goto end; @@ -305,11 +304,6 @@ static abyss_bool is_authorized(const TSession * r, const char *command) if (!ok) { ResponseStatus(r, err); - if (status) { - ResponseError2(r, status); - } else { - ResponseError(r); - } } diff --git a/src/switch.c b/src/switch.c index b59097ac89..a28baba6f0 100644 --- a/src/switch.c +++ b/src/switch.c @@ -271,13 +271,12 @@ int main(int argc, char *argv[]) switch_size_t pid_len, old_pid_len; const char *err = NULL; /* error value for return from freeswitch initialization */ #ifndef WIN32 - int bf = 0; + int nf = 0; /* TRUE if we are running in nofork mode */ char *runas_user = NULL; char *runas_group = NULL; #else int win32_service = 0; #endif - int nf = 0; /* TRUE if we are running in nofork mode */ int nc = 0; /* TRUE if we are running in noconsole mode */ pid_t pid = 0; int i, x; @@ -329,7 +328,6 @@ int main(int argc, char *argv[]) "\t-monotonic-clock -- use monotonic clock as timer source\n" #else "\t-nf -- no forking\n" - "\t-bf -- block until fully started, then fork\n" "\t-u [user] -- specify user to switch to\n" "\t-g [group] -- specify group to switch to\n" #endif "\t-help -- this message\n" "\t-version -- print the version and exit\n" @@ -463,11 +461,6 @@ int main(int argc, char *argv[]) known_opt++; } - if (local_argv[x] && !strcmp(local_argv[x], "-bf")) { - bf++; - known_opt++; - } - if (local_argv[x] && !strcmp(local_argv[x], "-version")) { fprintf(stdout, "FreeSWITCH version: %s\n", SWITCH_VERSION_FULL); return 0; @@ -530,14 +523,8 @@ int main(int argc, char *argv[]) } if (local_argv[x] && !strcmp(local_argv[x], "-nc")) { - if (!nf) { - nc++; - known_opt++; - } else { - /* The flags -nc and -nf are mutually exclusive. Ignoring -nc. */ - nc = 0; - known_opt++; - } + nc++; + known_opt++; } if (local_argv[x] && !strcmp(local_argv[x], "-c")) { @@ -698,7 +685,7 @@ int main(int argc, char *argv[]) #ifdef WIN32 FreeConsole(); #else - if (!nf && !bf) { + if (!nf) { daemonize(); } #endif @@ -813,12 +800,6 @@ int main(int argc, char *argv[]) return 255; } -#ifndef WIN32 - if(bf) { - daemonize(); - } -#endif - switch_core_runtime_loop(nc); destroy_status = switch_core_destroy(); diff --git a/src/switch_channel.c b/src/switch_channel.c index e3d77d7239..ece3fa27bb 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1291,19 +1291,24 @@ SWITCH_DECLARE(int) switch_channel_test_private_flag(switch_channel_t *channel, SWITCH_DECLARE(void) switch_channel_set_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags) { uint32_t *flagp = NULL; - + switch_byte_t new = 0; + switch_assert(channel != NULL); switch_mutex_lock(channel->flag_mutex); - - if (channel->app_flag_hash) { - flagp = switch_core_hash_find(channel->app_flag_hash, key); - } else { + + if (!channel->app_flag_hash) { switch_core_hash_init(&channel->app_flag_hash, switch_core_session_get_pool(channel->session)); + new++; + } + + if (new || !(flagp = switch_core_hash_find(channel->app_flag_hash, key))) { flagp = switch_core_session_alloc(channel->session, sizeof(uint32_t)); switch_core_hash_insert(channel->app_flag_hash, key, flagp); } - if (flagp) *flagp |= flags; + switch_assert(flagp); + *flagp |= flags; + switch_mutex_unlock(channel->flag_mutex); } @@ -1829,6 +1834,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann if (impl.iananame) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Name", impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Rate", "%u", impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Read-Codec-Bit-Rate", "%d", impl.bits_per_second); } switch_core_session_get_write_impl(channel->session, &impl); @@ -1836,6 +1842,7 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann if (impl.iananame) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%u", impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Bit-Rate", "%d", impl.bits_per_second); } /* Index Caller's Profile */ diff --git a/src/switch_console.c b/src/switch_console.c index 30d1d97fed..9f13823198 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -483,9 +483,29 @@ static int comp_callback(void *pArg, int argc, char **argv, char **columnNames) return -1; } + if (!zstr(target) && *target == ':' && *(target + 1) == ':' && *(target + 2) == '[') { + char *p = target + 3, *list = NULL; + + if (p) { + char *argv[100] = { 0 }; + char *r_argv[1] = { 0 }, *r_cols[1] = {0}; + list = strdup(p); + + argc = switch_separate_string(list, ':', argv, (sizeof(argv) / sizeof(argv[0]))); + + for (i = 0; (int)i < argc; i++) { + if (!cur || !strncmp(argv[i], cur, strlen(cur))) { + r_argv[0] = argv[i]; + comp_callback(h, 1, r_argv, r_cols); + } + } + switch_safe_free(list); + } + return 0; + } + if (!zstr(target) && *target == ':' && *(target + 1) == ':') { - char *r_argv[1] = { 0 }, *r_cols[1] = { - 0}; + char *r_argv[1] = { 0 }, *r_cols[1] = {0}; switch_console_callback_match_t *matches; if (switch_console_run_complete_func(target, str, cur, &matches) == SWITCH_STATUS_SUCCESS) { switch_console_callback_match_node_t *m; @@ -797,6 +817,7 @@ SWITCH_DECLARE(unsigned char) switch_console_complete(const char *line, const ch } stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_variable("hostname"), h.words + 1); + switch_cache_db_execute_sql_callback(db, stream.data, comp_callback, &h, &errmsg); if (errmsg) { diff --git a/src/switch_core.c b/src/switch_core.c index 4bfc02e655..2c33b341de 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1222,7 +1222,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc } runtime.runlevel++; - + runtime.sql_buffer_len = 1024 * 32; + runtime.max_sql_buffer_len = 1024 * 1024; runtime.dummy_cng_frame.data = runtime.dummy_data; runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data); runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data); @@ -1315,6 +1316,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc switch_log_init(runtime.memory_pool, runtime.colorize_console); + if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; + runtime.tipping_point = 5000; runtime.timer_affinity = -1; @@ -1438,6 +1441,37 @@ static void switch_load_core_config(const char *file) if (tmp > -1 && tmp < 11) { switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp); } + } else if (!strcasecmp(var, "sql-buffer-len")) { + int tmp = atoi(val); + + if (end_of(val) == 'k') { + tmp *= 1024; + } else if (end_of(val) == 'm') { + tmp *= (1024 * 1024); + } + + if (tmp >= 32000 && tmp < 10500000) { + runtime.sql_buffer_len = tmp; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql-buffer-len: Value is not within rage 32k to 10m\n"); + } + } else if (!strcasecmp(var, "max-sql-buffer-len")) { + int tmp = atoi(val); + + if (end_of(val) == 'k') { + tmp *= 1024; + } else if (end_of(val) == 'm') { + tmp *= (1024 * 1024); + } + + if (tmp < runtime.sql_buffer_len) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Value is not larger than sql-buffer-len\n"); + } else if (tmp >= 32000 && tmp < 10500000) { + runtime.sql_buffer_len = tmp; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "max-sql-buffer-len: Value is not within rage 32k to 10m\n"); + } + } else if (!strcasecmp(var, "auto-create-schemas")) { if (switch_true(val)) { switch_set_flag((&runtime), SCF_AUTO_SCHEMAS); @@ -1594,7 +1628,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n"); - if (switch_loadable_module_init() != SWITCH_STATUS_SUCCESS) { + if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) { *err = "Cannot load modules"; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Error: %s\n", *err); return SWITCH_STATUS_GENERR; @@ -1902,6 +1936,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) switch_scheduler_task_thread_stop(); switch_rtp_shutdown(); + if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) { switch_nat_shutdown(); } diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index ba84b0301c..edaf8b87e9 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -165,6 +165,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_s switch_channel_event_set_data(session->channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-read-codec-name", session->read_impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-rate", "%d", session->read_impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-bit-rate", "%d", session->read_impl.bits_per_second); if (session->read_impl.actual_samples_per_second != session->read_impl.samples_per_second) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-reported-read-codec-rate", "%d", session->read_impl.samples_per_second); } @@ -317,6 +318,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_write_codec(switch_core_ switch_channel_event_set_data(session->channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Name", session->write_impl.iananame); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-Codec-Rate", "%d", session->write_impl.actual_samples_per_second); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Write-codec-bit-rate", "%d", session->write_impl.bits_per_second); if (session->write_impl.actual_samples_per_second != session->write_impl.samples_per_second) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-Reported-Write-Codec-Rate", "%d", session->write_impl.actual_samples_per_second); @@ -494,8 +496,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, sw return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, const char *codec_name, const char *fmtp, - uint32_t rate, int ms, int channels, uint32_t flags, +SWITCH_DECLARE(switch_status_t) switch_core_codec_init_with_bitrate(switch_codec_t *codec, const char *codec_name, const char *fmtp, + uint32_t rate, int ms, int channels, uint32_t bitrate, uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool) { switch_codec_interface_t *codec_interface; @@ -519,7 +521,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, co /* If no specific codec interval is requested opt for 20ms above all else because lots of stuff assumes it */ if (!ms) { for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) { - if ((!rate || rate == iptr->samples_per_second) && + if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) && (20 == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) { implementation = iptr; goto found; @@ -529,7 +531,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, co /* Either looking for a specific interval or there was no interval specified and there wasn't one @20ms available */ for (iptr = codec_interface->implementations; iptr; iptr = iptr->next) { - if ((!rate || rate == iptr->samples_per_second) && + if ((!rate || rate == iptr->samples_per_second) && (!bitrate || bitrate == (uint32_t)iptr->bits_per_second) && (!ms || ms == (iptr->microseconds_per_packet / 1000)) && (!channels || channels == iptr->number_of_channels)) { implementation = iptr; break; diff --git a/src/switch_core_file.c b/src/switch_core_file.c index c995b229a6..7d5df8882a 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -173,7 +173,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, } if (fh->samplerate && rate && fh->samplerate != rate) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Sample rate doesn't match\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "File %s sample rate %d doesn't match requested rate %d\n", file_path, fh->samplerate, rate); if ((flags & SWITCH_FILE_FLAG_READ)) { fh->samplerate = rate; } diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 3a5e0bb6e2..7e427b5f03 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -34,8 +34,7 @@ #include <switch.h> #include "private/switch_core_pvt.h" - -#define SQLLEN 32768 +//*#define DEBUG_SQL 1 static struct { switch_cache_db_handle_t *event_db; @@ -43,11 +42,15 @@ static struct { switch_memory_pool_t *memory_pool; switch_event_node_t *event_node; switch_thread_t *thread; + switch_thread_t *db_thread; int thread_running; + int db_thread_running; switch_bool_t manage; switch_mutex_t *io_mutex; switch_mutex_t *dbh_mutex; switch_hash_t *dbh_hash; + switch_thread_cond_t *cond; + switch_mutex_t *cond_mutex; } sql_manager; @@ -346,7 +349,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h { if (!switch_odbc_available()) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! OBDC NOT AVAILABLE!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure! ODBC NOT AVAILABLE!\n"); goto end; } @@ -464,6 +467,19 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t return status; } +static void wake_thread(int force) +{ + if (force) { + switch_thread_cond_signal(sql_manager.cond); + return; + } + + if (switch_mutex_trylock(sql_manager.cond_mutex) == SWITCH_STATUS_SUCCESS) { + switch_thread_cond_signal(sql_manager.cond); + switch_mutex_unlock(sql_manager.cond_mutex); + } +} + /** OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions? **/ @@ -539,7 +555,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_hand switch (dbh->type) { default: { - status = switch_cache_db_execute_sql_chunked(dbh, (char *) sql, SQLLEN, err); + status = switch_cache_db_execute_sql_chunked(dbh, (char *) sql, 32768, err); } break; } @@ -846,30 +862,40 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive(switch_cache_db_hand } +static void *SWITCH_THREAD_FUNC switch_core_sql_db_thread(switch_thread_t *thread, void *obj) +{ + int sec = 0; + sql_manager.db_thread_running = 1; + + while (sql_manager.db_thread_running == 1) { + if (++sec == SQL_CACHE_TIMEOUT) { + sql_close(switch_epoch_time_now(NULL)); + wake_thread(1); + sec = 0; + } + switch_yield(1000); + } + + + return NULL; +} static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, void *obj) { - void *pop; - uint32_t itterations = 0; - uint8_t trans = 0, nothing_in_queue = 0; - uint32_t target = 100000; - switch_size_t len = 0, sql_len = SQLLEN; - char *sqlbuf = (char *) malloc(sql_len); + void *pop = NULL; + uint32_t iterations = 0; + uint8_t trans = 0; + uint32_t target = 20000; + switch_size_t len = 0, sql_len = runtime.sql_buffer_len; + char *tmp, *sqlbuf = (char *) malloc(sql_len); char *sql = NULL; switch_size_t newlen; int lc = 0; - uint32_t loops = 0, sec = 0; - uint32_t l1 = 1000; uint32_t sanity = 120; - int item_remained = 0; switch_assert(sqlbuf); - if (!sql_manager.manage) { - l1 = 10; - } - while (!sql_manager.event_db) { if (switch_core_db_handle(&sql_manager.event_db) == SWITCH_STATUS_SUCCESS && sql_manager.event_db) break; @@ -883,83 +909,91 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, return NULL; } - sql_manager.thread_running = 1; + switch_mutex_lock(sql_manager.cond_mutex); + while (sql_manager.thread_running == 1) { - if (++loops == l1) { - if (++sec == SQL_CACHE_TIMEOUT) { - sql_close(switch_epoch_time_now(NULL)); - sec = 0; - } - loops = 0; - } - - if (!sql_manager.manage) { - switch_yield(100000); - continue; - } - - //printf("SIZE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1])); - - if (item_remained || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || + if (sql || switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS || switch_queue_trypop(sql_manager.sql_queue[1], &pop) == SWITCH_STATUS_SUCCESS) { - if (item_remained) { - item_remained = 0; - } else { - sql = (char *) pop; - } - + if (!sql) sql = (char *) pop; + if (sql) { newlen = strlen(sql) + 2; - if (itterations == 0) { + if (iterations == 0) { trans = 1; } - /* ignore abnormally large strings sql strings as potential buffer overflow */ - if (newlen < SQLLEN) { - itterations++; + if (len + newlen > sql_len) { + int new_mlen = len + newlen + 10240; - if (len + newlen < sql_len) { - sprintf(sqlbuf + len, "%s;\n", sql); - len += newlen; + if (new_mlen < runtime.max_sql_buffer_len) { + sql_len = new_mlen; +#ifdef DEBUG_SQL + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "REALLOC %ld %d %d\n", (long int)sql_len, switch_queue_size(sql_manager.sql_queue[0]), + switch_queue_size(sql_manager.sql_queue[1])); +#endif + if (!(tmp = realloc(sqlbuf, sql_len))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread ending on mem err\n"); + abort(); + break; + } + sqlbuf = tmp; } else { - item_remained = 1; +#ifdef DEBUG_SQL + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "SAVE %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1])); +#endif + goto skip; } } - - if (!item_remained) { - free(sql); - } + + iterations++; + sprintf(sqlbuf + len, "%s;\n", sql); + len += newlen; + free(sql); + sql = NULL; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "SQL thread ending\n"); break; } - } else { - nothing_in_queue = 1; } - - if ((item_remained || (trans && ((itterations == target) || (nothing_in_queue && ++lc >= 500)))) && - (sql_manager.event_db->native_handle.core_db_dbh)) { + skip: + + lc = sql ? 1 : 0 + switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]); + + if (trans && iterations && (iterations > target || !lc)) { +#ifdef DEBUG_SQL + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "RUN %d %d %d\n", switch_queue_size(sql_manager.sql_queue[0]), switch_queue_size(sql_manager.sql_queue[1]), iterations); +#endif if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n"); } - itterations = 0; +#ifdef DEBUG_SQL + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DONE\n"); +#endif + iterations = 0; trans = 0; - nothing_in_queue = 0; len = 0; *sqlbuf = '\0'; lc = 0; + switch_yield(400000); } - if (nothing_in_queue) { - switch_cond_next(); + lc = sql ? 1 : 0 + switch_queue_size(sql_manager.sql_queue[0]) + switch_queue_size(sql_manager.sql_queue[1]); + + if (!lc) { + switch_thread_cond_wait(sql_manager.cond, sql_manager.cond_mutex); } } + switch_mutex_unlock(sql_manager.cond_mutex); + while (switch_queue_trypop(sql_manager.sql_queue[0], &pop) == SWITCH_STATUS_SUCCESS) { free(pop); } @@ -1108,11 +1142,13 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CODEC: new_sql() = switch_mprintf - ("update channels set read_codec='%q',read_rate='%q',write_codec='%q',write_rate='%q' where uuid='%q' and hostname='%q'", + ("update channels set read_codec='%q',read_rate='%q',read_bit_rate='%q',write_codec='%q',write_rate='%q',write_bit_rate='%q' where uuid='%q' and hostname='%q'", switch_event_get_header_nil(event, "channel-read-codec-name"), switch_event_get_header_nil(event, "channel-read-codec-rate"), + switch_event_get_header_nil(event, "channel-read-codec-bit-rate"), switch_event_get_header_nil(event, "channel-write-codec-name"), switch_event_get_header_nil(event, "channel-write-codec-rate"), + switch_event_get_header_nil(event, "channel-write-codec-bit-rate"), switch_event_get_header_nil(event, "unique-id"), switch_core_get_variable("hostname")); break; case SWITCH_EVENT_CHANNEL_HOLD: @@ -1389,6 +1425,7 @@ static void core_event_handler(switch_event_t *event) switch_queue_push(sql_manager.sql_queue[0], sql[i]); } sql[i] = NULL; + wake_thread(1); } } } @@ -1436,8 +1473,10 @@ static char create_channels_sql[] = " context VARCHAR(128),\n" " read_codec VARCHAR(128),\n" " read_rate VARCHAR(32),\n" + " read_bit_rate VARCHAR(32),\n" " write_codec VARCHAR(128),\n" " write_rate VARCHAR(32),\n" + " write_bit_rate VARCHAR(32),\n" " secure VARCHAR(32),\n" " hostname VARCHAR(256),\n" " presence_id VARCHAR(4096),\n" @@ -1505,12 +1544,16 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ { switch_threadattr_t *thd_attr; switch_cache_db_handle_t *dbh; + uint32_t sanity = 400; sql_manager.memory_pool = pool; sql_manager.manage = manage; switch_mutex_init(&sql_manager.dbh_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); switch_mutex_init(&sql_manager.io_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); + switch_mutex_init(&sql_manager.cond_mutex, SWITCH_MUTEX_NESTED, sql_manager.memory_pool); + + switch_thread_cond_create(&sql_manager.cond, sql_manager.memory_pool); switch_core_hash_init(&sql_manager.dbh_hash, sql_manager.memory_pool); @@ -1574,7 +1617,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ case SCDB_TYPE_ODBC: { char *err; - switch_cache_db_test_reactive(dbh, "select call_uuid from channels", "DROP TABLE channels", create_channels_sql); + switch_cache_db_test_reactive(dbh, "select call_uuid, read_bit_rate from channels", "DROP TABLE channels", create_channels_sql); switch_cache_db_test_reactive(dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); switch_cache_db_test_reactive(dbh, "select ikey from interfaces", "DROP TABLE interfaces", create_interfaces_sql); switch_cache_db_test_reactive(dbh, "select hostname from tasks", "DROP TABLE tasks", create_tasks_sql); @@ -1636,9 +1679,12 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_threadattr_create(&thd_attr, sql_manager.memory_pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool); + if (sql_manager.manage) { + switch_thread_create(&sql_manager.thread, thd_attr, switch_core_sql_thread, NULL, sql_manager.memory_pool); + } + switch_thread_create(&sql_manager.db_thread, thd_attr, switch_core_sql_db_thread, NULL, sql_manager.memory_pool); - while (!sql_manager.thread_running) { + while (sql_manager.manage && !sql_manager.thread_running && --sanity) { switch_yield(10000); } @@ -1659,12 +1705,19 @@ void switch_core_sqldb_stop(void) switch_queue_push(sql_manager.sql_queue[0], NULL); switch_queue_push(sql_manager.sql_queue[1], NULL); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Waiting for unfinished SQL transactions\n"); + wake_thread(1); } sql_manager.thread_running = -1; switch_thread_join(&st, sql_manager.thread); } + + if (sql_manager.thread && sql_manager.db_thread_running) { + sql_manager.db_thread_running = -1; + switch_thread_join(&st, sql_manager.db_thread); + } + switch_cache_db_flush_handles(); sql_close(0); diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 5368cdddeb..469ae18c4b 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -775,7 +775,8 @@ SWITCH_DECLARE(char *) CoreSession::read(int min_digits, int max_digits, const char *prompt_audio_file, int timeout, - const char *valid_terminators) + const char *valid_terminators, + int digit_timeout) { this_check((char *)""); sanity_check((char *)""); @@ -792,7 +793,8 @@ SWITCH_DECLARE(char *) CoreSession::read(int min_digits, } begin_allow_threads(); - switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, NULL, dtmf_buf, sizeof(dtmf_buf), timeout, valid_terminators); + switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, NULL, dtmf_buf, + sizeof(dtmf_buf), timeout, valid_terminators, (uint32_t)digit_timeout); end_allow_threads(); return dtmf_buf; @@ -806,7 +808,8 @@ SWITCH_DECLARE(char *) CoreSession::playAndGetDigits(int min_digits, char *audio_files, char *bad_input_audio_files, char *digits_regex, - const char *var_name) + const char *var_name, + int digit_timeout) { switch_status_t status; sanity_check((char *)""); @@ -824,7 +827,8 @@ SWITCH_DECLARE(char *) CoreSession::playAndGetDigits(int min_digits, var_name, dtmf_buf, sizeof(dtmf_buf), - digits_regex); + digits_regex, + (uint32_t) digit_timeout); end_allow_threads(); return dtmf_buf; diff --git a/src/switch_event.c b/src/switch_event.c index cfd6a7a139..4b1e28aebf 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -274,7 +274,7 @@ static void *SWITCH_THREAD_FUNC switch_event_dispatch_thread(switch_thread_t *th switch_mutex_lock(EVENT_QUEUE_MUTEX); - EVENT_DISPATCH_QUEUE_RUNNING[my_id] = 1; + EVENT_DISPATCH_QUEUE_RUNNING[my_id] = 0; THREAD_COUNT--; switch_mutex_unlock(EVENT_QUEUE_MUTEX); diff --git a/src/switch_ivr.c b/src/switch_ivr.c index c1dc33651c..7e7e8cda20 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -876,7 +876,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s switch_time_t abs_started = 0, digit_started = 0; uint32_t abs_elapsed = 0, digit_elapsed = 0; - if (!args || !args->input_callback) { + if (!args) { return SWITCH_STATUS_GENERR; } @@ -917,6 +917,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s if (switch_channel_has_dtmf(channel)) { + if (!args->input_callback && !args->buf) { + status = SWITCH_STATUS_BREAK; + break; + } switch_channel_dequeue_dtmf(channel, &dtmf); status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); if (digit_timeout) { @@ -1417,13 +1421,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ if (profile->callee_id_name) { switch_channel_set_variable(channel, "pre_transfer_caller_id_name", new_profile->caller_id_name); new_profile->caller_id_name = switch_core_strdup(new_profile->pool, profile->callee_id_name); - profile->callee_id_name = NULL; + profile->callee_id_name = SWITCH_BLANK_STRING; } if (profile->callee_id_number) { switch_channel_set_variable(channel, "pre_transfer_caller_id_number", new_profile->caller_id_number); new_profile->caller_id_number = switch_core_strdup(new_profile->pool, profile->callee_id_number); - profile->callee_id_number = NULL; + profile->callee_id_number = SWITCH_BLANK_STRING; } } @@ -1841,7 +1845,7 @@ SWITCH_DECLARE(int) switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channe for (; hi; hi = hi->next) { if (!zstr(hi->name) && !zstr(hi->value) && ((variable = switch_xml_add_child_d(xml, hi->name, off++)))) { char *data; - switch_size_t dlen = strlen(hi->value) * 3; + switch_size_t dlen = strlen(hi->value) * 3 + 1; if ((data = malloc(dlen))) { memset(data, 0, dlen); @@ -2175,6 +2179,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3 if ((jb_frame = stfu_n_read_a_frame(jb))) { write_frame.data = jb_frame->data; write_frame.datalen = (uint32_t) jb_frame->dlen; + write_frame.buflen = (uint32_t) jb_frame->dlen; status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { break; @@ -2256,6 +2261,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, goto done; } + if (!module_name) { + module_name = chan_lang; + } + if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) { sound_path = (char *) switch_xml_attr(language, "sound_path"); } diff --git a/src/switch_ivr_menu.c b/src/switch_ivr_menu.c index 4883326e4f..255ab61c76 100644 --- a/src/switch_ivr_menu.c +++ b/src/switch_ivr_menu.c @@ -214,12 +214,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_init(switch_ivr_menu_t ** new_me SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *menu, switch_ivr_action_t ivr_action, const char *arg, const char *bind) { - switch_ivr_menu_action_t *action; + switch_ivr_menu_action_t *action, *ap; uint32_t len; if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) { action->bind = switch_core_strdup(menu->pool, bind); - action->next = menu->actions; action->arg = switch_core_strdup(menu->pool, arg); if (*action->bind == '/') { action->re = 1; @@ -230,7 +229,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *m } } action->ivr_action = ivr_action; + + if (menu->actions) { + for(ap = menu->actions; ap && ap->next; ap = ap->next); + ap->next = action; + } else { menu->actions = action; + } + return SWITCH_STATUS_SUCCESS; } @@ -240,13 +246,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_action(switch_ivr_menu_t *m SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_function(switch_ivr_menu_t *menu, switch_ivr_menu_action_function_t *function, const char *arg, const char *bind) { - switch_ivr_menu_action_t *action; + switch_ivr_menu_action_t *action, *ap; uint32_t len; if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) { action->bind = switch_core_strdup(menu->pool, bind); - action->next = menu->actions; action->arg = switch_core_strdup(menu->pool, arg); + if (*action->bind == '/') { action->re = 1; } else { @@ -255,8 +261,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_bind_function(switch_ivr_menu_t menu->inlen = len; } } + action->function = function; + + if (menu->actions) { + for(ap = menu->actions; ap && ap->next; ap = ap->next); + ap->next = action; + } else { menu->actions = action; + } + return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 22b26eb4e0..1cbd2b9d39 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -212,7 +212,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void status = switch_ivr_read(collect->session, len, len, - collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL); + collect->file, NULL, buf, sizeof(buf), collect->confirm_timeout, NULL, 0); if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_TOO_SMALL) { @@ -2595,6 +2595,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if ((inner_var_count = switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) { + + /* this is stupid but necessary: if the value begins with ^^ take the very next char as a delim, + increment the string to start the next char after that and replace every instance of the delim with a , */ + + if (*inner_var_array[1] == '^' && *(inner_var_array[1] + 1) == '^') { + char *iv; + char d = 0; + inner_var_array[1] += 2; + d = *inner_var_array[1]++; + + if (d) { + for(iv = inner_var_array[1]; iv && *iv; iv++) { + if (*iv == d) *iv = ','; + } + } + } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "local variable string %d = [%s=%s]\n", x, inner_var_array[0], inner_var_array[1]); diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 75ed2d6283..d75af10a5e 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1645,7 +1645,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, uint32_t max_digits, const char *prompt_audio_file, const char *var_name, - char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators) + char *digit_buffer, + switch_size_t digit_buffer_length, + uint32_t timeout, + const char *valid_terminators, + uint32_t digit_timeout) + { switch_channel_t *channel; switch_input_args_t args = { 0 }; @@ -1696,7 +1701,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, if ((min_digits && len < min_digits) || len < max_digits) { args.buf = digit_buffer + len; args.buflen = (uint32_t) (digit_buffer_length - len); - status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], timeout, 0, 0); + status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], + len ? digit_timeout : timeout, digit_timeout, 0); } @@ -1745,7 +1751,10 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t const char *prompt_audio_file, const char *bad_input_audio_file, const char *var_name, - char *digit_buffer, uint32_t digit_buffer_length, const char *digits_regex) + char *digit_buffer, + uint32_t digit_buffer_length, + const char *digits_regex, + uint32_t digit_timeout) { switch_channel_t *channel = switch_core_session_get_channel(session); @@ -1755,7 +1764,7 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t memset(digit_buffer, 0, digit_buffer_length); switch_channel_flush_dtmf(channel); status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, - digit_buffer, digit_buffer_length, timeout, valid_terminators); + digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout); if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) { status = SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 67325648b2..7e08f71472 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -183,8 +183,9 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable if (load_interface) { for (impl = ptr->implementations; impl; impl = impl->next) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Adding Codec '%s' (%s) %dhz %dms\n", - impl->iananame, ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000); + "Adding Codec %s %d %s %dhz %dms %dbps\n", + impl->iananame, impl->ianacode, + ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000, impl->bits_per_second); if (!switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) { switch_core_hash_insert(loadable_modules.codec_hash, impl->iananame, (const void *) ptr); } @@ -515,8 +516,9 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t if (load_interface) { for (impl = ptr->implementations; impl; impl = impl->next) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Deleting Codec '%s' (%s) %dhz %dms\n", - impl->iananame, ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000); + "Deleting Codec %s %d %s %dhz %dms\n", + impl->iananame, impl->ianacode, + ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000); switch_core_session_hupall_matching_var("read_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST); switch_core_session_hupall_matching_var("write_codec", impl->iananame, SWITCH_CAUSE_MANAGER_REQUEST); if (switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) { @@ -1218,7 +1220,7 @@ static void switch_loadable_module_path_init() } #endif -SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() +SWITCH_DECLARE(switch_status_t) switch_loadable_module_init(switch_bool_t autoload) { apr_finfo_t finfo = { 0 }; @@ -1268,6 +1270,8 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() switch_core_hash_init_nocase(&loadable_modules.dialplan_hash, loadable_modules.pool); switch_mutex_init(&loadable_modules.mutex, SWITCH_MUTEX_NESTED, loadable_modules.pool); + if (!autoload) return SWITCH_STATUS_SUCCESS; + switch_loadable_module_load_module("", "CORE_SOFTTIMER_MODULE", SWITCH_FALSE, &err); switch_loadable_module_load_module("", "CORE_PCM_MODULE", SWITCH_FALSE, &err); @@ -1277,6 +1281,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) { switch_bool_t global = SWITCH_FALSE; const char *val = switch_xml_attr_soft(ld, "module"); + const char *path = switch_xml_attr_soft(ld, "path"); const char *critical = switch_xml_attr_soft(ld, "critical"); const char *sglobal = switch_xml_attr_soft(ld, "global"); if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) { @@ -1285,7 +1290,10 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() } global = switch_true(sglobal); - if (switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err) == SWITCH_STATUS_FALSE) { + if (path && zstr(path)) { + path = SWITCH_GLOBAL_dirs.mod_dir; + } + if (switch_loadable_module_load_module_ex((char *) path, (char *) val, SWITCH_FALSE, global, &err) == SWITCH_STATUS_FALSE) { if (critical && switch_true(critical)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to load critical module '%s', abort()\n", val); abort(); @@ -1307,13 +1315,18 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init() for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) { switch_bool_t global = SWITCH_FALSE; const char *val = switch_xml_attr_soft(ld, "module"); + const char *path = switch_xml_attr_soft(ld, "path"); const char *sglobal = switch_xml_attr_soft(ld, "global"); if (zstr(val) || (strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val); continue; } global = switch_true(sglobal); - switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err); + + if (path && zstr(path)) { + path = SWITCH_GLOBAL_dirs.mod_dir; + } + switch_loadable_module_load_module_ex((char *) path, (char *) val, SWITCH_FALSE, global, &err); count++; } } @@ -1546,13 +1559,16 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_impleme for (hi = switch_hash_first(NULL, loadable_modules.codec_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, NULL, NULL, &val); codec_interface = (switch_codec_interface_t *) val; - /* Look for a 20ms implementation because it's the safest choice */ + + /* Look for the default ptime of the codec because it's the safest choice */ for (imp = codec_interface->implementations; imp; imp = imp->next) { + uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode); + if (lock && imp->microseconds_per_packet != lock) { continue; } - if (imp->microseconds_per_packet / 1000 == 20) { + if (imp->microseconds_per_packet / 1000 == (int)default_ptime) { array[i++] = imp; goto found; } @@ -1586,7 +1602,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ for (x = 0; x < preflen; x++) { char *cur, *last = NULL, *next = NULL, *name, *p, buf[256]; - uint32_t interval = 0, rate = 0; + uint32_t interval = 0, rate = 0, bit = 0; switch_copy_string(buf, prefs[x], sizeof(buf)); last = name = next = cur = buf; @@ -1606,21 +1622,24 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ interval = atoi(cur); } else if ((strchr(cur, 'k') || strchr(cur, 'h'))) { rate = atoi(cur); + } else if (strchr(cur, 'b')) { + bit = atoi(cur); } } cur = next; } if ((codec_interface = switch_loadable_module_get_codec_interface(name)) != 0) { - /* If no specific codec interval is requested opt for 20ms above all else because lots of stuff assumes it */ + /* If no specific codec interval is requested opt for the default above all else because lots of stuff assumes it */ for (imp = codec_interface->implementations; imp; imp = imp->next) { - + uint32_t default_ptime = switch_default_ptime(imp->iananame, imp->ianacode); + if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { if (lock && imp->microseconds_per_packet != lock) { continue; } - - if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != 20) || + + if ((!interval && (uint32_t) (imp->microseconds_per_packet / 1000) != default_ptime) || (interval && (uint32_t) (imp->microseconds_per_packet / 1000) != interval)) { continue; } @@ -1628,6 +1647,11 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ if (((!rate && (uint32_t) imp->samples_per_second != 8000) || (rate && (uint32_t) imp->samples_per_second != rate))) { continue; } + + if (bit && (uint32_t) imp->bits_per_second != bit) { + continue; + } + } @@ -1636,7 +1660,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ } - /* Either looking for a specific interval or there was no interval specified and there wasn't one @20ms available */ + /* Either looking for a specific interval or there was no interval specified and there wasn't one at the default ptime available */ for (imp = codec_interface->implementations; imp; imp = imp->next) { if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { @@ -1651,6 +1675,11 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ if (rate && (uint32_t) imp->samples_per_second != rate) { continue; } + + if (bit && (uint32_t) imp->bits_per_second != bit) { + continue; + } + } array[i++] = imp; diff --git a/src/switch_nat.c b/src/switch_nat.c index 66d75e8210..536baeedff 100644 --- a/src/switch_nat.c +++ b/src/switch_nat.c @@ -690,7 +690,7 @@ SWITCH_DECLARE(void) switch_nat_late_init(void) { if (nat_globals_perm.running == 1) { switch_scheduler_add_task(switch_epoch_time_now(NULL) + NAT_REFRESH_INTERVAL, switch_nat_republish_sched, "nat_republish", "core", 0, NULL, - SSHF_NONE); + SSHF_OWN_THREAD); } } diff --git a/src/switch_regex.c b/src/switch_regex.c index 88152f978f..38c527cc0a 100644 --- a/src/switch_regex.c +++ b/src/switch_regex.c @@ -215,7 +215,7 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c if (match_count > 0) { *partial = 0; return SWITCH_STATUS_SUCCESS; - } else if (match_count == PCRE_ERROR_PARTIAL) { + } else if (match_count == PCRE_ERROR_PARTIAL || match_count == PCRE_ERROR_BADPARTIAL) { /* yes it is already set, but the code is clearer this way */ *partial = 1; return SWITCH_STATUS_SUCCESS; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index c9f9bfa3cf..66fc4cc7f3 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -239,6 +239,7 @@ struct switch_rtp { #endif switch_time_t send_time; + switch_byte_t auto_adj_used; }; struct switch_rtcp_senderinfo { @@ -662,6 +663,10 @@ SWITCH_DECLARE(void) switch_rtp_shutdown(void) const void *var; void *val; + if (!global_init) { + return; + } + switch_mutex_lock(port_lock); for (hi = switch_hash_first(NULL, alloc_hash); hi; hi = switch_hash_next(hi)) { @@ -1619,6 +1624,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port) { const char *err = NULL; + + if (!rtp_session->ms_per_packet) { + return SWITCH_STATUS_FALSE; + } switch_set_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP); @@ -2191,6 +2200,9 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->rtcp_fresh_frame = 1; + rtp_session->stats.rtcp.packet_count += sr->pc; + rtp_session->stats.rtcp.octet_count += sr->oc; + /* sender report */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"Received a SR with %d report blocks, " \ "length in words = %d, " \ @@ -2301,6 +2313,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ pt = 20000; } + if ((io_flags & SWITCH_IO_FLAG_NOBLOCK)) { + pt = 0; + } + poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt); if (rtp_session->dtmf_data.out_digit_dur > 0) { do_2833(rtp_session); @@ -2326,7 +2342,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - if (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { + if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) && (rtp_session->dtmf_data.out_digit_dur == 0 || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO))) { return_cng_frame(); } } @@ -2349,6 +2365,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if ((other_session = switch_core_session_locate(uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); if ((other_rtp_session = switch_channel_get_private(other_channel, "__rtcp_audio_rtp_session")) && + other_rtp_session->rtcp_sock_output && switch_test_flag(other_rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { *other_rtp_session->rtcp_send_msg.body = *rtp_session->rtcp_recv_msg.body; @@ -2519,13 +2536,14 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ switch_channel_set_variable(channel, "remote_media_port", adj_port); switch_channel_set_variable(channel, "rtp_auto_adjust", "true"); } - + rtp_session->auto_adj_used = 1; switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->from_addr), 0, SWITCH_FALSE, &err); switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Correct ip/port confirmed.\n"); switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + rtp_session->auto_adj_used = 0; } } @@ -2865,6 +2883,12 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ return ret; } + +SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session) +{ + return rtp_session->auto_adj_used; +} + SWITCH_DECLARE(switch_size_t) switch_rtp_has_dtmf(switch_rtp_t *rtp_session) { switch_size_t has = 0; @@ -3429,7 +3453,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session, rtp_session->last_write_ts = this_ts; - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) && + if (rtp_session->rtcp_sock_output && + switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) && rtp_session->rtcp_interval && (rtp_session->stats.outbound.packet_count % rtp_session->rtcp_interval) == 0) { struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_send_msg.body; diff --git a/src/switch_utils.c b/src/switch_utils.c index 91b78f7bbb..b887904960 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -2090,6 +2090,137 @@ SWITCH_DECLARE(char *) switch_url_decode(char *s) return s; } +SWITCH_DECLARE(void) switch_split_time(const char *exp, int *hour, int *min, int *sec) +{ + char *dup = strdup(exp); + char *shour = NULL; + char *smin = NULL; + char *ssec = NULL; + + switch_assert(dup); + + shour = dup; + if ((smin=strchr(dup, ':'))) { + *smin++ = '\0'; + if ((ssec=strchr(smin, ':'))) { + *ssec++ = '\0'; + } else { + ssec = "00"; + } + if (hour && shour) { + *hour = atol(shour); + } + if (min && smin) { + *min = atol(smin); + } + if (sec && ssec) { + *sec = atol(ssec); + } + + } + switch_safe_free(dup); + return; + +} + +SWITCH_DECLARE(void) switch_split_date(const char *exp, int *year, int *month, int *day) +{ + char *dup = strdup(exp); + char *syear = NULL; + char *smonth = NULL; + char *sday = NULL; + + switch_assert(dup); + + syear = dup; + if ((smonth=strchr(dup, '-'))) { + *smonth++ = '\0'; + if ((sday=strchr(smonth, '-'))) { + *sday++ = '\0'; + if (year && syear) { + *year = atol(syear); + } + if (month && smonth) { + *month = atol(smonth); + } + if (day && sday) { + *day = atol(sday); + } + } + } + switch_safe_free(dup); + return; + +} + +/* Ex exp value "2009-10-10 14:33:22~2009-11-10 17:32:31" */ +SWITCH_DECLARE(int) switch_fulldate_cmp(const char *exp, switch_time_t *ts) +{ + char *dup = strdup(exp); + char *sStart; + char *sEnd; + char *sDate; + char *sTime; + switch_time_t tsStart; + switch_time_t tsEnd; + + switch_assert(dup); + + sStart = dup; + if ((sEnd=strchr(dup, '~'))) { + *sEnd++ = '\0'; + sDate = sStart; + if ((sTime=strchr(sStart, ' '))) { + struct tm tmTmp; + int year, month, day; + int hour, min, sec; + + *sTime++ = '\0'; + + switch_split_date(sDate, &year, &month, &day); + switch_split_time(sTime, &hour, &min, &sec); + tmTmp.tm_year = year; + tmTmp.tm_mon = month; + tmTmp.tm_mday = day; + + tmTmp.tm_hour = hour; + tmTmp.tm_min = min; + tmTmp.tm_sec = sec; + tmTmp.tm_isdst = 0; + tsStart = mktime(&tmTmp); + + sDate = sEnd; + if ((sTime=strchr(sEnd, ' '))) { + struct tm tmTmp; + int year, month, day; + int hour, min, sec; + + *sTime++ = '\0'; + + switch_split_date(sDate, &year, &month, &day); + switch_split_time(sTime, &hour, &min, &sec); + tmTmp.tm_year = year; + tmTmp.tm_mon = month; + tmTmp.tm_mday = day; + + tmTmp.tm_hour = hour; + tmTmp.tm_min = min; + tmTmp.tm_sec = sec; + tmTmp.tm_isdst = 0; + tsEnd = mktime(&tmTmp); + + if (tsStart <= *ts && tsEnd > *ts) { + switch_safe_free(dup); + return 1; + } + } + } + } + switch_safe_free(dup); + return 0; + +} + /* Written by Marc Espie, public domain */ #define SWITCH_CTYPE_NUM_CHARS 256 @@ -2335,6 +2466,82 @@ SWITCH_DECLARE(int) switch_isxdigit(int c) return (c < 0 ? 0 : c > 255 ? 0 : ((_switch_ctype_ + 1)[(unsigned char) c] & (_N | _X))); } +static const char *DOW[] = { + "sat", + "sun", + "mon", + "tue", + "wed", + "thu", + "fri", + "sat", + "sun", + NULL +}; + +SWITCH_DECLARE(const char *) switch_dow_int2str(int val) { + if (val >= sizeof(DOW) / sizeof (const char*)) { + return NULL; + } + return DOW[val]; +} + +SWITCH_DECLARE(int) switch_dow_str2int(const char *exp) { + int ret = -1; + int x = -1; + for (x = 0;; x++) { + if (!DOW[x]) { + break; + } + + if (!strcasecmp(DOW[x], exp)) { + ret = x; + break; + } + } + return ret; +} + +SWITCH_DECLARE(int) switch_dow_cmp(const char *exp, int val) +{ + char *dup = strdup(exp); + char *p_start; + char *p_end; + int ret = 0; + int start, end; + + switch_assert(dup); + + p_start = dup; + + if ((p_end=strchr(dup, '-'))) { + *p_end++ = '\0'; + } else { + p_end = p_start; + } + if (strlen(p_start) == 3) { + start = switch_dow_str2int(p_start); + } else { + start = atol(p_start); + } + if (strlen(p_end) == 3) { + end = switch_dow_str2int(p_end); + } else { + end = atol(p_end); + } + /* Following used for this example : mon-sat = 2-0, so we need to make 0(sat) + 7 */ + if (end < start) { + end += 7; + } + if (start != -1 && end != -1 && val >= start && val <= end) { + ret = 1; + } + + switch_safe_free(dup); + + return ret; +} + SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val) { char *p; @@ -2375,6 +2582,49 @@ SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val) } +SWITCH_DECLARE(int) switch_tod_cmp(const char *exp, int val) +{ + char *dup = strdup(exp); + char *minh; + char *minm; + char *mins; + char *maxh; + char *maxm; + char *maxs; + + switch_assert(dup); + + minh = dup; + if ((minm=strchr(dup, ':'))) { + *minm++ = '\0'; + if ((maxh=strchr(minm, '-'))) { + if ((maxm=strchr(maxh, ':'))) { + *maxh++ = '\0'; + *maxm++ = '\0'; + /* Check if min/max seconds are present */ + if ((mins=strchr(minm, ':'))) { + *mins++ = '\0'; + } else { + mins = "00"; + } + if ((maxs=strchr(maxm, ':'))) { + *maxs++ = '\0'; + } else { + maxs = "00"; + } + + if (val >= (atol(minh) * 60 * 60) + (atol(minm) * 60) + atol(mins) && val < (atol(maxh) * 60 * 60) + (atol(maxm) * 60) + atol(maxs)) { + switch_safe_free(dup); + return 1; + } + } + } + } + switch_safe_free(dup); + return 0; + +} + SWITCH_DECLARE(int) switch_split_user_domain(char *in, char **user, char **domain) { char *p = NULL, *h = NULL, *u = in; diff --git a/src/switch_xml.c b/src/switch_xml.c index efaede83fb..95b82cb20d 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2039,6 +2039,18 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_open_root(uint8_t reload, const char **e return r; } +SWITCH_DECLARE(switch_status_t) switch_xml_reload(const char **err) +{ + switch_xml_t xml_root; + + if ((xml_root = switch_xml_open_root(1, err))) { + switch_xml_free(xml_root); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_GENERR; +} + SWITCH_DECLARE(switch_status_t) switch_xml_init(switch_memory_pool_t *pool, const char **err) { switch_xml_t xml; @@ -2640,6 +2652,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_cut(switch_xml_t xml) SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) { + const char *xdt = switch_xml_attr(xcond, "date-time"); const char *xyear = switch_xml_attr(xcond, "year"); const char *xyday = switch_xml_attr(xcond, "yday"); const char *xmon = switch_xml_attr(xcond, "mon"); @@ -2650,6 +2663,7 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) { const char *xhour = switch_xml_attr(xcond, "hour"); const char *xminute = switch_xml_attr(xcond, "minute"); const char *xminday = switch_xml_attr(xcond, "minute-of-day"); + const char *xtod = switch_xml_attr(xcond, "time-of-day"); switch_time_t ts = switch_micro_time_now(); int time_match = -1; @@ -2657,6 +2671,15 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) { switch_time_exp_lt(&tm, ts); + if (time_match && xdt) { + char tmpdate[80]; + switch_size_t retsize; + switch_strftime(tmpdate, &retsize, sizeof(tmpdate), "%Y-%m-%d %H:%M:%S", &tm); + time_match = switch_fulldate_cmp(xdt, &ts); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "XML DateTime Check: date time[%s] =~ %s (%s)\n", tmpdate, xdt, time_match ? "PASS" : "FAIL"); + } + if (time_match && xyear) { int test = tm.tm_year + 1900; time_match = switch_number_cmp(xyear, test); @@ -2710,9 +2733,9 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) { if (time_match && xwday) { int test = tm.tm_wday + 1; - time_match = switch_number_cmp(xwday, test); + time_match = switch_dow_cmp(xwday, test); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, - "XML DateTime Check: day of week[%d] =~ %s (%s)\n", test, xwday, time_match ? "PASS" : "FAIL"); + "XML DateTime Check: day of week[%s] =~ %s (%s)\n", switch_dow_int2str(test), xwday, time_match ? "PASS" : "FAIL"); } if (time_match && xhour) { int test = tm.tm_hour; @@ -2735,6 +2758,15 @@ SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond) { "XML DateTime Check: minute of day[%d] =~ %s (%s)\n", test, xminday, time_match ? "PASS" : "FAIL"); } + if (time_match && xtod) { + int test = (tm.tm_hour * 60 * 60) + (tm.tm_min * 60) + tm.tm_sec; + char tmpdate[10]; + switch_snprintf(tmpdate, 6, "%d:%d:%d", tm.tm_hour, tm.tm_min, tm.tm_sec); + time_match = switch_tod_cmp(xtod, test); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, + "XML DateTime Check: time of day[%s] =~ %s (%s)\n", tmpdate, xtod, time_match ? "PASS" : "FAIL"); + } + return time_match; } diff --git a/src/tone2wav.c b/src/tone2wav.c new file mode 100644 index 0000000000..4415860802 --- /dev/null +++ b/src/tone2wav.c @@ -0,0 +1,193 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org> + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II <anthm@freeswitch.org> + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II <anthm@freeswitch.org> + * Michael Jerris <mike@jerris.com> + * Pawel Pierscionek <pawel@voiceworks.pl> + * Bret McDanel <trixter AT 0xdecafbad.com> + * + * + * tone2wav.c -- Generate a .wav from teletone spec + * + */ + +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 +#endif + +#ifndef WIN32 +#ifdef HAVE_SETRLIMIT +#include <sys/resource.h> +#endif +#endif + +#include <switch.h> +#include <switch_version.h> + + + +/* Picky compiler */ +#ifdef __ICC +#pragma warning (disable:167) +#endif + + +static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map) +{ + switch_file_handle_t *fh = (switch_file_handle_t *) ts->user_data; + int wrote; + switch_size_t len; + + wrote = teletone_mux_tones(ts, map); + + len = wrote; + if (switch_core_file_write(fh, ts->buffer, &len) != SWITCH_STATUS_SUCCESS) { + return -1; + } + + return 0; +} + +#define fail() r = 255; goto end + +/* the main application entry point */ +int main(int argc, char *argv[]) +{ + teletone_generation_session_t ts; + int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; + int r = 0; + int rate = 8000; + char *file = NULL, *script = NULL; + switch_file_handle_t fh = { 0 }; + const char *err = NULL; + switch_bool_t verbose = SWITCH_FALSE; + int i = 0, c = 1, help = 0; + + for(i = 1; i < argc; i++) { + if (!strstr(argv[i], "-")) break; + + if (!strcmp(argv[i], "-v")) { + verbose = SWITCH_TRUE; + } + + if (!strcmp(argv[i], "-s")) { + c = 2; + } + + if (!strcmp(argv[i], "-h")) { + help = 1; + } + + if (!strncmp(argv[i], "-R", 2)) { + char *p = argv[i] + 2; + + if (p) { + int tmp = atoi(p); + if (tmp > 0) { + rate = tmp; + } + } + } + } + + if (argc - i != 2 || help) { + char *app = NULL; + + if (!help) printf("Invalid input!\n"); + + if ((app = strrchr(argv[0], '/'))) { + app++; + } else { + app = argv[0]; + } + + + printf("USAGE: %s [options] <file> <tones>\n", app); + printf("================================================================================\n"); + printf("Options:\n" + "-s\t\tStereo\n" + "-h\t\tHelp\n" + "-R<rate>\tSet Rate (8000,16000,32000,48000) etc.\n" + "-v\t\tVerbose Logging\n" + "<file>\t\tAny file supported by libsndfile\n" + "<tones>\t\tA valid teletone script http://wiki.freeswitch.org/wiki/TGML" + "\n\n\n" + ); + return 255; + } + + file = argv[i]; + script = argv[i+1]; + + if (switch_core_init(SCF_MINIMAL, verbose, &err) != SWITCH_STATUS_SUCCESS) { + printf("Cannot init core [%s]\n", err); + fail(); + } + + switch_loadable_module_init(SWITCH_FALSE); + + if (switch_loadable_module_load_module((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) "mod_sndfile", SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + printf("Cannot init mod_sndfile [%s]\n", err); + fail(); + } + + if (switch_core_file_open(&fh, file, c, rate, file_flags, NULL) != SWITCH_STATUS_SUCCESS) { + printf("Cannot open file %s\n", file); + fail(); + } + + teletone_init_session(&ts, 0, teletone_handler, &fh); + ts.rate = rate; + ts.channels = c; + ts.duration = 250 * (rate / 1000 / c); + ts.wait = 50 * (rate / 1000 / c); + if (verbose) { + ts.debug = 10; + ts.debug_stream = stdout; + } + teletone_run(&ts, script); + teletone_destroy_session(&ts); + switch_core_file_close(&fh); + + printf("File: %s generated.....\n\nPlease support:\nFreeSWITCH http://www.freeswitch.org\nClueCon http://www.cluecon.com\n", file); + + end: + + switch_core_destroy(); + + return r; + +} + +/* 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: + */