diff --git a/Makefile.am b/Makefile.am index df1ee2e0d0..8d35068c35 100644 --- a/Makefile.am +++ b/Makefile.am @@ -251,7 +251,8 @@ libfreeswitch_la_SOURCES = \ libs/miniupnpc/upnperrors.c \ libs/libnatpmp/natpmp.c \ libs/libnatpmp/getgateway.c\ - libs/spandsp/src/plc.c + libs/spandsp/src/plc.c \ + libs/spandsp/src/bit_operations.c if ENABLE_CPP libfreeswitch_la_SOURCES += src/switch_cpp.cpp diff --git a/build/modules.conf.in b/build/modules.conf.in index 69d90a8dd4..2be000f6b3 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -35,6 +35,7 @@ applications/mod_valet_parking #applications/mod_snapshot #applications/mod_snipe_hunt #applications/mod_callcenter +#applications/mod_fsk codecs/mod_g723_1 codecs/mod_amr #codecs/mod_amrwb diff --git a/build/sounds_version.txt b/build/sounds_version.txt index cb0c481b13..20cb29cbd7 100644 --- a/build/sounds_version.txt +++ b/build/sounds_version.txt @@ -1,3 +1,3 @@ -en-us-callie 1.0.13 +en-us-callie 1.0.14 ru-RU-elena 1.0.12 diff --git a/conf/autoload_configs/acl.conf.xml b/conf/autoload_configs/acl.conf.xml index a1708a55f3..0c117d07bf 100644 --- a/conf/autoload_configs/acl.conf.xml +++ b/conf/autoload_configs/acl.conf.xml @@ -21,7 +21,10 @@ digest authenticated. --> + + + diff --git a/conf/autoload_configs/modules.conf.xml b/conf/autoload_configs/modules.conf.xml index 51c62f2059..b7100bd304 100644 --- a/conf/autoload_configs/modules.conf.xml +++ b/conf/autoload_configs/modules.conf.xml @@ -56,6 +56,7 @@ + diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml index fba809ba2c..8342f120fc 100644 --- a/conf/autoload_configs/switch.conf.xml +++ b/conf/autoload_configs/switch.conf.xml @@ -16,7 +16,7 @@ - + diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml index 3e756a85c0..426264a1c5 100644 --- a/conf/sip_profiles/internal.xml +++ b/conf/sip_profiles/internal.xml @@ -114,6 +114,8 @@ + + @@ -337,6 +339,9 @@ A completed transaction is kept around for the duration of T4 in order to catch late responses. The T4 is the maximum duration for the messages to stay in the network and the duration of SIP timer K. --> + + + diff --git a/debian/freeswitch.init b/debian/freeswitch.init index ddde2f5518..283400aabc 100755 --- a/debian/freeswitch.init +++ b/debian/freeswitch.init @@ -9,7 +9,7 @@ # Description: An advanced platform for voice services ### END INIT INFO -# Author: Anthony Minesalle III +# Author: Anthony Minesalle II # # Do NOT "set -e" diff --git a/freeswitch-sounds-en-us-callie.spec b/freeswitch-sounds-en-us-callie.spec new file mode 100644 index 0000000000..c4764570f5 --- /dev/null +++ b/freeswitch-sounds-en-us-callie.spec @@ -0,0 +1,339 @@ +############################################################################## +# Copyright and license +############################################################################## +# +# Spec file for package freeswitch-sounds-en-us-callie (version 1.0.12-8) +# +# Copyright (c) 2009 Patrick Laimbock +# Some fixes and additions (c) 2011 Michal Bielicki +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# + +############################################################################## +# Determine distribution +############################################################################## + +%define is_rhel5 %(test -f /etc/redhat-release && egrep -q 'release 5' /etc/redhat-release && echo 1 || echo 0) + +############################################################################## +# Set variables +############################################################################## + +%define version 1.0.14 +%define release 1 + +%define fsname freeswitch +# you could add a version number to be more strict + +%define prefix /opt/freeswitch +%define _prefix %{prefix} + +############################################################################## +# General +############################################################################## + +Summary: FreeSWITCH en-us Callie prompts +Name: freeswitch-sounds-en-us-callie +Version: %{version} +Release: %{release}%{?dist} +License: MPL +Group: Applications/Communications +Packager: Patrick Laimbock +URL: http://www.freeswitch.org +Source0:http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz +BuildArch: noarch +BuildRequires: sox +Requires: freeswitch +Requires: freeswitch-sounds-en-us-callie-48000 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +%description +FreeSWITCH 48kHz en-us Callie prompts plus, during the installation, +it will also install locally generated 8KHz, 16KHz and 32KHz prompts + +%package -n freeswitch-sounds-en-us-callie-8000 +Summary: FreeSWITCH 8kHz en-us Callie prompts +Group: Applications/Communications +BuildArch: noarch +Requires: %{fsname} + +%description -n freeswitch-sounds-en-us-callie-8000 +FreeSWITCH 8kHz en-us Callie prompts + +%package -n freeswitch-sounds-en-us-callie-16000 +Summary: FreeSWITCH 16kHz en-us Callie prompts +Group: Applications/Communications +BuildArch: noarch +Requires: %{fsname} + +%description -n freeswitch-sounds-en-us-callie-16000 +FreeSWITCH 16kHz en-us Callie prompts + +%package -n freeswitch-sounds-en-us-callie-32000 +Summary: FreeSWITCH 32kHz en-us Callie prompts +Group: Applications/Communications +BuildArch: noarch +Requires: %{fsname} + +%description -n freeswitch-sounds-en-us-callie-32000 +FreeSWITCH 32kHz en-us Callie prompts + +%package -n freeswitch-sounds-en-us-callie-48000 +Summary: FreeSWITCH 48kHz en-us Callie prompts +Group: Applications/Communications +BuildArch: noarch +Requires: %{fsname} + +%description -n freeswitch-sounds-en-us-callie-48000 +FreeSWITCH 48kHz en-us Callie prompts + +%package -n freeswitch-sounds-en-us-callie-all +Summary: FreeSWITCH en-us Callie prompts +Group: Applications/Communications +BuildArch: noarch +Requires: %{fsname} +Requires: freeswitch-sounds-en-us-callie-8000 = %{version} +Requires: freeswitch-sounds-en-us-callie-16000 = %{version} +Requires: freeswitch-sounds-en-us-callie-32000 = %{version} +Requires: freeswitch-sounds-en-us-callie-48000 = %{version} + +%description -n freeswitch-sounds-en-us-callie-all +FreeSWITCH Callie prompts package that pulls in the 8KHz, 16KHz, +32KHz and 48KHz RPMs + +############################################################################## +# Prep +############################################################################## + +%prep +%setup -b0 -q -n en +mkdir -p ./usr/callie +# create buildsounds-callie.sh script in working dir +echo '#!/bin/bash + +sounds_location=$1 +for rate in 32000 16000 8000 +do + for i in ascii base256 conference currency digits directory ivr misc phonetic-ascii time voicemail zrtp + do + mkdir -p $sounds_location/$i/$rate + for f in `find $sounds_location/$i/48000 -name \*.wav` + do + echo "generating" $sounds_location/$i/$rate/`basename $f` + sox $f -r $rate $sounds_location/$i/$rate/`basename $f` + done + done +done' > ./us/callie/buildsounds-callie.sh +%{__chmod} 0750 ./us/callie/buildsounds-callie.sh + +############################################################################## +# Build +############################################################################## + +%build +# nothing to do here + +############################################################################## +# Install +############################################################################## + +%install +[ "%{buildroot}" != '/' ] && rm -rf %{buildroot} + +# create the sounds directories +%{__install} -d -m 0750 %{buildroot}%{_prefix}/sounds/en/us/callie + +pushd us/callie +# first install the 48KHz sounds +%{__cp} -prv ./* %{buildroot}%{_prefix}/sounds/en/us/callie +# now resample the 48KHz ones to 8KHz, 16KHz and 32KHz +./buildsounds-callie.sh %{buildroot}%{_prefix}/sounds/en/us/callie +popd + +############################################################################## +# Clean +############################################################################## + +%clean +[ "%{buildroot}" != '/' ] && rm -rf %{buildroot} + +############################################################################## +# Post +############################################################################## + +%post +# generate the 8KHz, 16KHz and 32KHz prompts from the 48KHz ones +cd %{_prefix}/sounds/en/us/callie +./buildsounds-callie.sh %{_prefix}/sounds/en/us/callie + +############################################################################## +# Postun +############################################################################## + +%postun +# you could check if there are sound files in 8000/ or +# 16000/ or 32000/ and remove them *only* if the files +# do not belong to an rpm + +############################################################################## +# Files +############################################################################## + +%files +%defattr(-,root,root) +%attr(0750,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/buildsounds-callie.sh + +%files -n freeswitch-sounds-en-us-callie-8000 +%defattr(-,root,root,-) +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/8000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/8000 +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/8000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/8000/*.wav + +%files -n freeswitch-sounds-en-us-callie-16000 +%defattr(-,root,root,-) +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/16000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/16000 +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/16000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/16000/*.wav + +%files -n freeswitch-sounds-en-us-callie-32000 +%defattr(-,root,root,-) +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/32000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/32000 +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/32000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/32000/*.wav + +%files -n freeswitch-sounds-en-us-callie-48000 +%defattr(-,root,root,-) +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/48000 +%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/48000 +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/48000/*.wav +%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/48000/*.wav + +%files -n freeswitch-sounds-en-us-callie-all + +############################################################################## +# Changelog +############################################################################## + +%changelog +* Tue Jan 18 2011 Michal Bielicki - 1.0.14-1 +- bump up version +- include script into freeswitch core +- include specfile into freeswitch core +- runtime does not require sox, only building + +* Thu Dec 17 2009 Patrick Laimbock - 1.0.12-8 +- update perms and user/group to sync with the old situation + +* Wed Dec 16 2009 Patrick Laimbock - 1.0.12-7 +- make main package require freeswitch-sounds-en-us-callie-48000 and +- generate the 8KHz, 16KHz and 32KHz sounds from there +- add license to spec file + +* Wed Dec 16 2009 Patrick Laimbock - 1.0.12-5 +- put 48KHz in a separate package and let the main package Require 48KHz +- and then use the script to generate the 8KHz, 16KHz and 32KHz sounds + +* Wed Dec 16 2009 Patrick Laimbock - 1.0.12-4 +- add freeswitch-sounds-en-us-callie-all package that pulls in the 8KHz, +- 16KHz, 32KHz and 48KHz RPM packages + +* Tue Dec 15 2009 Patrick Laimbock - 1.0.12-3 +- override subpackage name with -n so it no longer builds an empty main RPM +- rework spec file +- add sox as a requirement +- run buildsounds-callie.sh in post to generate 8KHz, 16KHz and 32KHz prompts + +* Tue Dec 15 2009 Patrick Laimbock - 1.0.12-2 +- can't override Name in subpackage so put all versions in RPM subpackages +- with an empty main RPM package + +* Tue Dec 15 2009 Patrick Laimbock - 1.0.12-1 +- create spec file with the following requirement: +- source only contains the 48KHz sound prompts +- during build the 48KHz sound prompts are resampled to 8KHz, 16KHz and 32KHz +- the 8KHz, 16KHz, 32KHz and 48KHz sound prompts are packaged separately + diff --git a/freeswitch.spec b/freeswitch.spec index 05401b8e8a..7fb9f80d8e 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -53,7 +53,7 @@ Vendor: http://www.freeswitch.org/ # Source files and where to get them # ###################################################################################################################### -Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2 +Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2 Source1: http://files.freeswitch.org/downloads/libs/celt-0.7.1.tar.gz Source2: http://files.freeswitch.org/downloads/libs/flite-1.3.99-latest.tar.gz Source3: http://files.freeswitch.org/downloads/libs/lame-3.97.tar.gz @@ -89,8 +89,13 @@ BuildRequires: libtool >= 1.5.17 BuildRequires: ncurses-devel BuildRequires: openssl-devel BuildRequires: perl +%if 0%{?fedora_version} >= 8 +BuildRequires: perl-ExtUtils-Embed +%endif BuildRequires: pkgconfig +%if %{_vendor} == redhat && 0%{?fedora} <= 6 BuildRequires: termcap +%endif BuildRequires: unixODBC-devel BuildRequires: gdbm-devel BuildRequires: db4-devel @@ -613,7 +618,6 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.ttml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/extensions.conf -%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/m3ua.conf %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/mime.types %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/acl.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/alsa.conf.xml @@ -894,7 +898,7 @@ fi %files python %defattr(-,freeswitch,daemon) %{prefix}/mod/mod_python*.so* -%attr(0644, root, bin) /usr/lib/python2.4/site-packages/freeswitch.py* +%attr(0644, root, bin) /usr/lib/python*/site-packages/freeswitch.py* %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/python.conf.xml @@ -952,6 +956,8 @@ fi # ###################################################################################################################### %changelog +* Tue Jan 18 2011 - michal.bielicki@seventhsignal.de +- Fedora adjustments * Fri Oct 15 2010 - michal.bielicki@seventhsignal.de - added mod_curl * Sat Oct 09 2010 - michal.bielicki@seventhsignal.de diff --git a/libs/.gitignore b/libs/.gitignore index cc42ba4fa4..b31646500e 100644 --- a/libs/.gitignore +++ b/libs/.gitignore @@ -1001,6 +1001,7 @@ /unimrcp/build/acmacros/lt~obsolete.m4 /*.tar.gz /celt-0.7.1/ +/celt-0.10.0/ /flite-1.3.99/ /freeradius-client-1.1.6/ /iksemel/test/tst-dom diff --git a/libs/esl/managed/ESL.2010.vcxproj b/libs/esl/managed/ESL.2010.vcxproj new file mode 100644 index 0000000000..1656ddd1db --- /dev/null +++ b/libs/esl/managed/ESL.2010.vcxproj @@ -0,0 +1,195 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ESL + {FEA2D0AE-6713-4E41-A473-A143849BC7FF} + ESL + ManagedCProj + + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + Unicode + true + true + + + DynamicLibrary + MultiByte + true + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\src\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + + + esl.lib;Ws2_32.lib;%(AdditionalDependencies) + ..\..\..\libs\esl\src\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) + true + true + NotSet + + + + + ..\src\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + esl.lib;Ws2_32.lib;%(AdditionalDependencies) + ..\..\..\libs\esl\src\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) + true + MachineX86 + + + + + X64 + + + Disabled + ..\src\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + + + esl.lib;Ws2_32.lib;%(AdditionalDependencies) + ..\..\..\libs\esl\src\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) + true + true + MachineX64 + + + + + X64 + + + ..\src\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + esl.lib;Ws2_32.lib;%(AdditionalDependencies) + ..\..\..\libs\esl\src\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories) + true + MachineX64 + + + + + true + true + + + true + true + + + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/libs/esl/managed/ESL.2010.vcxproj.filters b/libs/esl/managed/ESL.2010.vcxproj.filters new file mode 100644 index 0000000000..0f46492f09 --- /dev/null +++ b/libs/esl/managed/ESL.2010.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/libs/esl/managed/ManagedEsl.2010.csproj b/libs/esl/managed/ManagedEsl.2010.csproj new file mode 100644 index 0000000000..7be21f44cb --- /dev/null +++ b/libs/esl/managed/ManagedEsl.2010.csproj @@ -0,0 +1,93 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {DEE5837B-E01D-4223-B351-EDF9418F3F8E} + Library + Properties + ManagedEsl + ManagedEsl + v4.0 + 512 + + + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/libs/esl/managed/ManagedEslTest/ManagedEslTest.2010.csproj b/libs/esl/managed/ManagedEslTest/ManagedEslTest.2010.csproj new file mode 100644 index 0000000000..8b97ffc2df --- /dev/null +++ b/libs/esl/managed/ManagedEslTest/ManagedEslTest.2010.csproj @@ -0,0 +1,98 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {2321D01A-D64B-4461-9837-FACF38652212} + Exe + Properties + ManagedEslTest + ManagedEslTest + v4.0 + 512 + + + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + ..\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + ..\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + + + + + + + + {DEE5837B-E01D-4223-B351-EDF9418F3F8E} + ManagedEsl + True + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + \ No newline at end of file diff --git a/libs/esl/managed/managed_esl.2010.sln b/libs/esl/managed/managed_esl.2010.sln new file mode 100644 index 0000000000..3460af4746 --- /dev/null +++ b/libs/esl/managed/managed_esl.2010.sln @@ -0,0 +1,74 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ESL", "ESL.2010.vcxproj", "{FEA2D0AE-6713-4E41-A473-A143849BC7FF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedEsl.2010", "ManagedEsl.2010.csproj", "{DEE5837B-E01D-4223-B351-EDF9418F3F8E}" + ProjectSection(ProjectDependencies) = postProject + {FEA2D0AE-6713-4E41-A473-A143849BC7FF} = {FEA2D0AE-6713-4E41-A473-A143849BC7FF} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedEslTest.2010", "ManagedEslTest\ManagedEslTest.2010.csproj", "{2321D01A-D64B-4461-9837-FACF38652212}" + ProjectSection(ProjectDependencies) = postProject + {FEA2D0AE-6713-4E41-A473-A143849BC7FF} = {FEA2D0AE-6713-4E41-A473-A143849BC7FF} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Debug|Win32.ActiveCfg = Debug|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Debug|Win32.Build.0 = Debug|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Debug|x64.ActiveCfg = Debug|x64 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Debug|x64.Build.0 = Debug|x64 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Release|Any CPU.ActiveCfg = Release|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Release|Mixed Platforms.Build.0 = Release|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Release|Win32.ActiveCfg = Release|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Release|Win32.Build.0 = Release|Win32 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Release|x64.ActiveCfg = Release|x64 + {FEA2D0AE-6713-4E41-A473-A143849BC7FF}.Release|x64.Build.0 = Release|x64 + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Debug|Win32.ActiveCfg = Debug|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Debug|x64.Build.0 = Debug|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Release|Any CPU.Build.0 = Release|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Release|Win32.ActiveCfg = Release|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Release|x64.ActiveCfg = Release|Any CPU + {DEE5837B-E01D-4223-B351-EDF9418F3F8E}.Release|x64.Build.0 = Release|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Debug|x64.ActiveCfg = Debug|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Debug|x64.Build.0 = Debug|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Release|Any CPU.Build.0 = Release|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Release|Win32.ActiveCfg = Release|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Release|x64.ActiveCfg = Release|Any CPU + {2321D01A-D64B-4461-9837-FACF38652212}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index f5bab62fcb..078c5de973 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -1094,9 +1094,9 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ esl_log(ESL_LOG_DEBUG, "RECV INNER HEADER [%s] = [%s]\n", hname, hval); if (!strcasecmp(hname, "event-name")) { esl_event_del_header(handle->last_ievent, "event-name"); + esl_name_event(hval, &handle->last_ievent->event_id); } esl_event_add_header_string(handle->last_ievent, ESL_STACK_BOTTOM, hname, hval); - esl_name_event(hval, &handle->last_ievent->event_id); } beg = c + 1; diff --git a/libs/esl/src/esl_buffer.c b/libs/esl/src/esl_buffer.c index 8032169fe3..173c9cb76c 100644 --- a/libs/esl/src/esl_buffer.c +++ b/libs/esl/src/esl_buffer.c @@ -82,7 +82,7 @@ ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t bl ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer) { - assert(buffer != NULL); + esl_assert(buffer != NULL); return buffer->datalen; @@ -91,8 +91,7 @@ ESL_DECLARE(esl_size_t) esl_buffer_len(esl_buffer_t *buffer) ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer) { - assert(buffer != NULL); - + esl_assert(buffer != NULL); if (buffer->max_len) { return (esl_size_t) (buffer->max_len - buffer->used); @@ -103,7 +102,7 @@ ESL_DECLARE(esl_size_t) esl_buffer_freespace(esl_buffer_t *buffer) ESL_DECLARE(esl_size_t) esl_buffer_inuse(esl_buffer_t *buffer) { - assert(buffer != NULL); + esl_assert(buffer != NULL); return buffer->used; } @@ -112,7 +111,7 @@ ESL_DECLARE(esl_size_t) esl_buffer_seek(esl_buffer_t *buffer, esl_size_t datalen { esl_size_t reading = 0; - assert(buffer != NULL); + esl_assert(buffer != NULL); if (buffer->used < 1) { buffer->used = 0; @@ -133,7 +132,7 @@ ESL_DECLARE(esl_size_t) esl_buffer_toss(esl_buffer_t *buffer, esl_size_t datalen { esl_size_t reading = 0; - assert(buffer != NULL); + esl_assert(buffer != NULL); if (buffer->used < 1) { buffer->used = 0; @@ -174,8 +173,8 @@ ESL_DECLARE(esl_size_t) esl_buffer_read(esl_buffer_t *buffer, void *data, esl_si { esl_size_t reading = 0; - assert(buffer != NULL); - assert(data != NULL); + esl_assert(buffer != NULL); + esl_assert(data != NULL); if (buffer->used < 1) { @@ -201,7 +200,7 @@ ESL_DECLARE(esl_size_t) esl_buffer_packet_count(esl_buffer_t *buffer) char *pe, *p, *e, *head = (char *) buffer->head; esl_size_t x = 0; - assert(buffer != NULL); + esl_assert(buffer != NULL); e = (head + buffer->used); @@ -224,8 +223,8 @@ ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data, char *pe, *p, *e, *head = (char *) buffer->head; esl_size_t datalen = 0; - assert(buffer != NULL); - assert(data != NULL); + esl_assert(buffer != NULL); + esl_assert(data != NULL); e = (head + buffer->used); @@ -251,9 +250,9 @@ ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, { esl_size_t freespace, actual_freespace; - assert(buffer != NULL); - assert(data != NULL); - assert(buffer->data != NULL); + esl_assert(buffer != NULL); + esl_assert(data != NULL); + esl_assert(buffer->data != NULL); if (!datalen) { return buffer->used; @@ -312,8 +311,8 @@ ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, ESL_DECLARE(void) esl_buffer_zero(esl_buffer_t *buffer) { - assert(buffer != NULL); - assert(buffer->data != NULL); + esl_assert(buffer != NULL); + esl_assert(buffer->data != NULL); buffer->used = 0; buffer->actually_used = 0; diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 2ab5c29e18..96f1c9a10f 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -94,6 +94,7 @@ library_include_HEADERS = \ $(SRC)/include/ftdm_declare.h \ $(SRC)/include/ftdm_threadmutex.h \ $(SRC)/include/ftdm_os.h \ + $(SRC)/include/ftdm_call_utils.h \ $(SRC)/include/ftdm_dso.h lib_LTLIBRARIES = libfreetdm.la diff --git a/libs/freetdm/TODO b/libs/freetdm/TODO index 45b134bad3..6b8ef8f826 100644 --- a/libs/freetdm/TODO +++ b/libs/freetdm/TODO @@ -5,5 +5,9 @@ then ftdm_event_t would be renamed to ftdm_oob_event_t and the enum_id renamed to type, then ftdm_span_next_event() will only return OOB events -- query span hw status (connected/disconnected) on startup +- Deprecate last_error members. + It requires a lot of discipline to set the last_error string for every failure. + It does not add much value to the user either, most of the errors are criptic and + cannot be shown to end users, we already provide extensive logging for problem + troubleshooting. diff --git a/libs/freetdm/bootstrap b/libs/freetdm/bootstrap index 8ca4856832..247d396da5 100755 --- a/libs/freetdm/bootstrap +++ b/libs/freetdm/bootstrap @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh autoheader libtoolize --force --copy aclocal diff --git a/libs/freetdm/docs/async.txt b/libs/freetdm/docs/async.txt new file mode 100644 index 0000000000..04069ebebd --- /dev/null +++ b/libs/freetdm/docs/async.txt @@ -0,0 +1,14 @@ +APIs that result in an event when the API returns FTDM_SUCCESS + +ftdm_channel_call_answer() +ftdm_channel_call_indicate() + FTDM_SIGEVENT_INDICATION_COMPLETED + *note that FTDM_SIGEVENT_INDICATION_COMPLETED has associated data to indicate the result of the indication + *note this event is only delivered on non-blocking channels + +ftdm_call_place + FTDM_SIGEVENT_DIALING + +ftdm_channel_call_hangup + FTDM_SIGEVENT_RELEASED + diff --git a/libs/freetdm/docs/glare.txt b/libs/freetdm/docs/glare.txt new file mode 100644 index 0000000000..0753db817f --- /dev/null +++ b/libs/freetdm/docs/glare.txt @@ -0,0 +1,25 @@ +Glare is a PITA. + +Although configuration of ISDN links can be done to minimize glare, we also must have a clear policy +on how the FreeTDM API is supposed to behave on glare across signaling modules. + +There is a well-known race in the FreeTDM API since the beginning. When a user wants to place a call with +the old APIs: + +1. ftdm_channel_open_xx (to hunt the channel by group, span or select a channel individually) +2. ftdm_channel_call_place() to place the actual call. + +Since the user has no access to channel locking, between opening a channel and placing a call, an incoming call could be +received. Therefore things can get complicated and that is why you should STOP USING those 2 deprecated functions. + +The replacement is ftdm_call_place(). + +ftdm_call_place receives the information required to hunt the channel and place the call. + +If glare is detected after placing the call and the signaling stack decides to drop the local call, a regular +SIGEVENT_STOP will be sent with the hangup cause FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL. + +ftdm_call_place may return FTDM_BREAK if glare is detected while placing the call, in such cases you can try +calling ftdm_call_place again to hunt another channel. + + diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 7bbdef6dae..970cb5b993 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * Moises Silva * David Yat Sin * @@ -1073,6 +1073,66 @@ static const char* channel_get_variable(switch_core_session_t *session, switch_e return NULL; } +typedef struct { + switch_event_t *var_event; + switch_core_session_t *new_session; + private_t *tech_pvt; + switch_caller_profile_t *caller_profile; +} hunt_data_t; + +static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data) +{ + uint32_t span_id, chan_id; + const char *var; + char *sess_uuid; + char name[128]; + ftdm_status_t status; + hunt_data_t *hdata = caller_data->priv; + switch_channel_t *channel = switch_core_session_get_channel(hdata->new_session); + + if ((var = switch_event_get_header(hdata->var_event, "freetdm_pre_buffer_size"))) { + int tmp = atoi(var); + if (tmp > -1) { + ftdm_channel_command(fchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp); + } + } + + span_id = ftdm_channel_get_span_id(fchan); + chan_id = ftdm_channel_get_id(fchan); + + tech_init(hdata->tech_pvt, hdata->new_session, fchan); + + snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name); + switch_channel_set_name(channel, name); + switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(fchan)); + switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id); + switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chan_id); + + switch_channel_set_caller_profile(channel, hdata->caller_profile); + hdata->tech_pvt->caller_profile = hdata->caller_profile; + + switch_channel_set_state(channel, CS_INIT); + sess_uuid = switch_core_session_get_uuid(hdata->new_session); + status = ftdm_channel_add_token(fchan, sess_uuid, ftdm_channel_get_token_count(fchan)); + switch_assert(status == FTDM_SUCCESS); + + if (SPAN_CONFIG[span_id].limit_calls) { + char spanresource[512]; + snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(fchan), + caller_data->dnis.digits); + ftdm_log(FTDM_LOG_DEBUG, "Adding rate limit resource on channel %d:%d (%s/%s/%d/%d)\n", + span_id, chan_id, FREETDM_LIMIT_REALM, + spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds); + if (switch_limit_incr("hash", hdata->new_session, FREETDM_LIMIT_REALM, spanresource, + SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds) != SWITCH_STATUS_SUCCESS) { + return FTDM_BREAK; + } + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attached session %s to channel %d:%d\n", sess_uuid, span_id, chan_id); + return FTDM_SUCCESS; +} + /* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines that allocate memory or you will have 1 channel with memory allocated from another channel's pool! */ @@ -1081,13 +1141,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) { - + hunt_data_t hunt_data; const char *dest = NULL; char *data = NULL; int span_id = -1, group_id = -1, chan_id = 0; - ftdm_channel_t *ftdmchan = NULL; switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - char name[128]; ftdm_status_t status; int direction = FTDM_TOP_DOWN; ftdm_caller_data_t caller_data = {{ 0 }}; @@ -1097,6 +1155,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi int argc = 0; const char *var; const char *dest_num = NULL, *callerid_num = NULL; + ftdm_hunting_scheme_t hunting; if (!outbound_profile) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n"); @@ -1125,7 +1184,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi if ((argc = switch_separate_string(data, '/', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n"); - return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } if (switch_is_number(argv[0])) { @@ -1255,11 +1314,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) { - caller_data.screen = 1; + caller_data.screen = FTDM_SCREENING_VERIFIED_PASSED; } if (switch_test_flag(outbound_profile, SWITCH_CPF_HIDE_NUMBER)) { - caller_data.pres = 1; + caller_data.pres = FTDM_PRES_RESTRICTED; } if ((var = channel_get_variable(session, var_event, "freetdm_bearer_capability"))) { @@ -1309,30 +1368,21 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi ftdm_set_string(caller_data.cid_name, outbound_profile->caller_id_name); ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(outbound_profile->caller_id_number)); + memset(&hunting, 0, sizeof(hunting)); + if (group_id >= 0) { - status = ftdm_channel_open_by_group(group_id, direction, &caller_data, &ftdmchan); + hunting.mode = FTDM_HUNT_GROUP; + hunting.mode_data.group.group_id = group_id; + hunting.mode_data.group.direction = direction; } else if (chan_id) { - status = ftdm_channel_open(span_id, chan_id, &ftdmchan); + hunting.mode = FTDM_HUNT_CHAN; + hunting.mode_data.chan.span_id = span_id; + hunting.mode_data.chan.chan_id = chan_id; } else { - status = ftdm_channel_open_by_span(span_id, direction, &caller_data, &ftdmchan); + hunting.mode = FTDM_HUNT_SPAN; + hunting.mode_data.span.span_id = span_id; + hunting.mode_data.span.direction = direction; } - - if (status != FTDM_SUCCESS) { - if (caller_data.hangup_cause == SWITCH_CAUSE_NONE) { - caller_data.hangup_cause = SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - return caller_data.hangup_cause; - } - - if ((var = switch_event_get_header(var_event, "freetdm_pre_buffer_size"))) { - int tmp = atoi(var); - if (tmp > -1) { - ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp); - } - } - - span_id = ftdm_channel_get_span_id(ftdmchan); - chan_id = ftdm_channel_get_id(ftdmchan); for (h = var_event->headers; h; h = h->next) { if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) { @@ -1343,57 +1393,31 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } } } - + if ((*new_session = switch_core_session_request(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) { private_t *tech_pvt; switch_caller_profile_t *caller_profile; - switch_channel_t *channel = switch_core_session_get_channel(*new_session); switch_core_session_add_stream(*new_session, NULL); - if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) { - tech_init(tech_pvt, *new_session, ftdmchan); - } else { + if (!(tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(new_session); cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; goto fail; } - snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, dest); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name); - switch_channel_set_name(channel, name); - switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(ftdmchan)); - switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id); - switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chan_id); - ftdm_channel_set_caller_data(ftdmchan, &caller_data); caller_profile = switch_caller_profile_clone(*new_session, outbound_profile); caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num)); caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, switch_str_nil(callerid_num)); - switch_channel_set_caller_profile(channel, caller_profile); - tech_pvt->caller_profile = caller_profile; - - - switch_channel_set_state(channel, CS_INIT); - if (ftdm_channel_add_token(ftdmchan, switch_core_session_get_uuid(*new_session), ftdm_channel_get_token_count(ftdmchan)) != FTDM_SUCCESS) { - switch_core_session_destroy(new_session); - cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - goto fail; - } + hunting.result_cb = on_channel_found; + hunt_data.var_event = var_event; + hunt_data.new_session = *new_session; + hunt_data.caller_profile = caller_profile; + hunt_data.tech_pvt = tech_pvt; + caller_data.priv = &hunt_data; - if (SPAN_CONFIG[span_id].limit_calls) { - char spanresource[512]; - snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(ftdmchan), caller_data.dnis.digits); - ftdm_log(FTDM_LOG_DEBUG, "Adding rate limit resource on channel %d:%d (%s/%s/%d/%d)\n", span_id, chan_id, FREETDM_LIMIT_REALM, - spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds); - if (switch_limit_incr("hash", *new_session, FREETDM_LIMIT_REALM, spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds) != SWITCH_STATUS_SUCCESS) { - switch_core_session_destroy(new_session); - cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; - goto fail; - } - } - - if ((status = ftdm_channel_call_place(ftdmchan)) != FTDM_SUCCESS) { + if ((status = ftdm_call_place(&caller_data, &hunting)) != FTDM_SUCCESS) { if (tech_pvt->read_codec.implementation) { switch_core_codec_destroy(&tech_pvt->read_codec); } @@ -1402,28 +1426,22 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi switch_core_codec_destroy(&tech_pvt->write_codec); } switch_core_session_destroy(new_session); - if (status == FTDM_BREAK) { /* glare, we don't want to touch the channel since is being used for incoming call now */ + if (status == FTDM_BREAK || status == FTDM_EBUSY) { cause = SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION; - ftdmchan = NULL; } else { cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } - goto fail; + goto fail; } - ftdm_channel_init(ftdmchan); + ftdm_channel_init(caller_data.fchan); return SWITCH_CAUSE_SUCCESS; } fail: - if (ftdmchan) { - ftdm_channel_call_hangup_with_cause(ftdmchan, FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE); - } - return cause; - } static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel) @@ -1645,6 +1663,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal) case FTDM_SIGEVENT_RELEASED: case FTDM_SIGEVENT_INDICATION_COMPLETED: + case FTDM_SIGEVENT_DIALING: { /* Swallow these events */ return FTDM_BREAK; @@ -3744,9 +3763,7 @@ SWITCH_STANDARD_API(ft_function) flags = "call swap"; } fchan = ftdm_span_get_channel(SPAN_CONFIG[j].span, 1); - if (fchan) { - ftdm_channel_get_alarms(fchan, &alarmbits); - } + ftdm_channel_get_alarms(fchan, &alarmbits); if ((FTDM_SUCCESS == ftdm_span_get_sig_status(SPAN_CONFIG[j].span, &sigstatus))) { stream->write_function(stream, @@ -4177,6 +4194,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load) freetdm_endpoint_interface->state_handler = &freetdm_state_handlers; SWITCH_ADD_API(commands_api_interface, "ftdm", "FreeTDM commands", ft_function, FT_SYNTAX); + switch_console_set_complete("add ftdm start"); + switch_console_set_complete("add ftdm stop"); + switch_console_set_complete("add ftdm retart"); + switch_console_set_complete("add ftdm dump"); + switch_console_set_complete("add ftdm sigstatus get"); + switch_console_set_complete("add ftdm sigstatus set"); + switch_console_set_complete("add ftdm trace"); + switch_console_set_complete("add ftdm notrace"); + switch_console_set_complete("add ftdm q931_pcap"); + switch_console_set_complete("add ftdm gains"); + switch_console_set_complete("add ftdm dtmf on"); + switch_console_set_complete("add ftdm dtmf off"); + SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "disable_dtmf", "Disable DTMF Detection", "Disable DTMF Detection", disable_dtmf_function, "", SAF_NONE); diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 21354c4442..b5f9fab93d 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -278,7 +278,10 @@ FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID) FTDM_ENUM_NAMES(TRACE_DIR_NAMES, TRACE_DIR_STRINGS) -FTDM_STR2ENUM(ftdm_str2ftdm_trace_dir, ftdm_trace_dir2str, ftdm_trace_dir_t, TRACE_DIR_NAMES, FTDM_TRACE_INVALID) +FTDM_STR2ENUM(ftdm_str2ftdm_trace_dir, ftdm_trace_dir2str, ftdm_trace_dir_t, TRACE_DIR_NAMES, FTDM_TRACE_DIR_INVALID) + +FTDM_ENUM_NAMES(TRACE_TYPE_NAMES, TRACE_TYPE_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_trace_type, ftdm_trace_type2str, ftdm_trace_type_t, TRACE_TYPE_NAMES, FTDM_TRACE_TYPE_INVALID) FTDM_ENUM_NAMES(TON_NAMES, TON_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t, TON_NAMES, FTDM_TON_INVALID) @@ -401,39 +404,39 @@ static __inline__ void ftdm_std_free(void *pool, void *ptr) free(ptr); } -static void ftdm_set_echocancel_call_begin(ftdm_channel_t *chan) +FT_DECLARE(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 the ec is disabled on idle, we need to enable it unless is a digital call */ if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) { + ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec for call in channel state %s\n", ftdm_channel_state2str(chan->state)); ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL); } } else { + /* If the ec is enabled on idle, we do nothing unless is a digital call that needs it disabled */ if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) { + ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec for digital call in channel state %s\n", ftdm_channel_state2str(chan->state)); ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL); } } } } -static void ftdm_set_echocancel_call_end(ftdm_channel_t *chan) +FT_DECLARE(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); - } + ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec on call end in channel state %s\n", ftdm_channel_state2str(chan->state)); + 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); - } + ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec back on call end in channel state %s\n", ftdm_channel_state2str(chan->state)); + ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL); } } } - FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler = { /*.pool =*/ NULL, @@ -631,6 +634,10 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span) ftdm_mutex_lock(span->mutex); /* stop the signaling */ + + /* This is a forced stopped */ + ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE); + ftdm_span_stop(span); /* destroy the channels */ @@ -675,43 +682,54 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_alarms(ftdm_channel_t *ftdmchan, ftdm { ftdm_status_t status = FTDM_FAIL; - ftdm_assert_return(alarmbits != NULL, FTDM_FAIL, "null argument\n"); + ftdm_assert_return(alarmbits != NULL, FTDM_EINVAL, "null alarmbits argument\n"); + ftdm_assert_return(ftdmchan != NULL, FTDM_EINVAL, "null channel argument\n"); + ftdm_assert_return(ftdmchan->span != NULL, FTDM_EINVAL, "null span\n"); + ftdm_assert_return(ftdmchan->span->fio != NULL, FTDM_EINVAL, "null io\n"); *alarmbits = FTDM_ALARM_NONE; + if (!ftdmchan->span->fio->get_alarms) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No get_alarms interface for this channel\n"); + return FTDM_ENOSYS; + } + + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CONFIGURED)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot get alarms from an unconfigured channel\n"); + return FTDM_EINVAL; + } + ftdm_channel_lock(ftdmchan); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CONFIGURED)) { - if (ftdmchan->span->fio->get_alarms) { - if ((status = ftdmchan->span->fio->get_alarms(ftdmchan)) == FTDM_SUCCESS) { - *ftdmchan->last_error = '\0'; - *alarmbits = ftdmchan->alarm_flags; - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RED)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RED/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_YELLOW)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "YELLOW/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RAI)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RAI/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_BLUE)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "BLUE/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_AIS)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "AIS/"); - } - if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_GENERAL)) { - snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "GENERAL"); - } - *(ftdmchan->last_error + strlen(ftdmchan->last_error) - 1) = '\0'; - - } - } else { - status = FTDM_NOTIMPL; - } + if ((status = ftdmchan->span->fio->get_alarms(ftdmchan)) != FTDM_SUCCESS) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to get alarms from channel\n"); + goto done; } + *ftdmchan->last_error = '\0'; + *alarmbits = ftdmchan->alarm_flags; + if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RED)) { + snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RED/"); + } + if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_YELLOW)) { + snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "YELLOW/"); + } + if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RAI)) { + snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RAI/"); + } + if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_BLUE)) { + snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "BLUE/"); + } + if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_AIS)) { + snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "AIS/"); + } + if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_GENERAL)) { + snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "GENERAL"); + } + *(ftdmchan->last_error + strlen(ftdmchan->last_error) - 1) = '\0'; + +done: + ftdm_channel_unlock(ftdmchan); return status; @@ -736,6 +754,11 @@ FT_DECLARE(ftdm_status_t) ftdm_span_stop(ftdm_span_t *span) ftdm_status_t status = FTDM_SUCCESS; ftdm_mutex_lock(span->mutex); + + if (ftdm_test_flag(span, FTDM_SPAN_NON_STOPPABLE)) { + status = FTDM_NOTIMPL; + goto done; + } if (!ftdm_test_flag(span, FTDM_SPAN_STARTED)) { status = FTDM_EINVAL; @@ -1422,8 +1445,9 @@ static __inline__ int request_voice_channel(ftdm_channel_t *check, ftdm_channel_ * sometimes with the group or span lock held and were * blocking anyone hunting for channels available and * I believe teh channel_request() function may take - * a bit of time - * */ + * a bit of time. However channel_request is a callback + * used by boost and may be only a few other old sig mods + * and it should be deprecated */ ftdm_mutex_unlock(check->mutex); ftdm_set_caller_data(check->span, caller_data); status = check->span->channel_request(check->span, check->chan_id, @@ -1436,7 +1460,9 @@ static __inline__ int request_voice_channel(ftdm_channel_t *check, ftdm_channel_ if (status == FTDM_SUCCESS) { *ftdmchan = check; ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND); +#if 0 ftdm_mutex_unlock(check->mutex); +#endif return 1; } } @@ -1488,9 +1514,9 @@ static ftdm_status_t __inline__ get_best_rated(ftdm_channel_t **fchan, ftdm_chan } *fchan = best_rated; ftdm_set_flag(best_rated, FTDM_CHANNEL_OUTBOUND); - +#if 0 ftdm_mutex_unlock(best_rated->mutex); - +#endif return FTDM_SUCCESS; } @@ -1520,7 +1546,7 @@ FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan) return availability; } -FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) +static ftdm_status_t _ftdm_channel_open_by_group(uint32_t group_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) { ftdm_status_t status = FTDM_FAIL; ftdm_channel_t *check = NULL; @@ -1601,6 +1627,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir return status; } +FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) +{ + ftdm_status_t status; + status = _ftdm_channel_open_by_group(group_id, direction, caller_data, ftdmchan); + if (status == FTDM_SUCCESS) { + ftdm_channel_t *fchan = *ftdmchan; + ftdm_channel_unlock(fchan); + } + return status; +} FT_DECLARE(ftdm_status_t) ftdm_span_channel_use_count(ftdm_span_t *span, uint32_t *count) { @@ -1623,7 +1659,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_channel_use_count(ftdm_span_t *span, uint32_ return FTDM_SUCCESS; } -FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) +/* Hunt a channel by span, if successful the channel is returned locked */ +static ftdm_status_t _ftdm_channel_open_by_span(uint32_t span_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) { ftdm_status_t status = FTDM_FAIL; ftdm_channel_t *check = NULL; @@ -1721,6 +1758,17 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc return status; } +FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direction_t direction, ftdm_caller_data_t *caller_data, ftdm_channel_t **ftdmchan) +{ + ftdm_status_t status; + status = _ftdm_channel_open_by_span(span_id, direction, caller_data, ftdmchan); + if (status == FTDM_SUCCESS) { + ftdm_channel_t *fchan = *ftdmchan; + ftdm_channel_unlock(fchan); + } + return status; +} + FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan) { ftdm_status_t status = FTDM_FAIL; @@ -1771,7 +1819,7 @@ done: return status; } -FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) +static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) { ftdm_channel_t *check = NULL; ftdm_span_t *span = NULL; @@ -1852,6 +1900,10 @@ openchan: ftdm_set_flag(check, FTDM_CHANNEL_INUSE); ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND); *ftdmchan = check; +#if 1 + /* we've got the channel, do not unlock it */ + goto done; +#endif unlockchan: ftdm_mutex_unlock(check->mutex); @@ -1865,6 +1917,17 @@ done: return status; } +FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan) +{ + ftdm_status_t status; + status = _ftdm_channel_open(span_id, chan_id, ftdmchan); + if (status == FTDM_SUCCESS) { + ftdm_channel_t *fchan = *ftdmchan; + ftdm_channel_unlock(fchan); + } + return status; +} + FT_DECLARE(uint32_t) ftdm_channel_get_id(const ftdm_channel_t *ftdmchan) { return ftdmchan->chan_id; @@ -2029,6 +2092,11 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *fchan, ftdm_channel_indication_t indication, ftdm_status_t status) { ftdm_sigmsg_t msg; + + if (!ftdm_test_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING)) { + return; + } + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Acknowledging indication %s in state %s (rc = %d)\n", ftdm_channel_indication2str(indication), ftdm_channel_state2str(fchan->state), status); ftdm_clear_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING); @@ -2040,25 +2108,11 @@ FT_DECLARE(void) ftdm_ack_indication(ftdm_channel_t *fchan, ftdm_channel_indicat ftdm_span_send_signal(fchan->span, &msg); } -/*! \brief Answer call without locking the channel. The caller must have locked first - * \note This function was added because ftdm_channel_call_indicate needs to answer the call - * when its already locking the channel, ftdm_channel_set_state cannot be called with the same - * lock locked once or more (recursive lock) and wait for the result */ +/*! Answer call without locking the channel. The caller must have locked first */ static ftdm_status_t _ftdm_channel_call_answer_nl(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { ftdm_status_t status = FTDM_SUCCESS; - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - status = FTDM_EINVAL; - goto done; - } - - if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call is already TERMINATING\n"); - status = FTDM_ECANCELED; - goto done; - } - if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) { /* We will fail RFC's if we not skip states, but some modules apart from ftmod_sangoma_isdn * expect the call to always to go PROGRESS and PROGRESS MEDIA state before going to UP, so @@ -2108,23 +2162,20 @@ done: FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { - ftdm_status_t status = FTDM_SUCCESS; + ftdm_status_t status; - ftdm_channel_lock(ftdmchan); + /* we leave the locking up to ftdm_channel_call_indicate, DO NOT lock here since ftdm_channel_call_indicate expects + * the lock recursivity to be 1 */ + status = _ftdm_channel_call_indicate(file, func, line, ftdmchan, FTDM_CHANNEL_INDICATE_ANSWER); - status = _ftdm_channel_call_answer_nl(file, func, line, ftdmchan); - - ftdm_channel_unlock(ftdmchan); return status; } /* lock must be acquired by the caller! */ -static ftdm_status_t _ftdm_channel_call_hangup_nl(ftdm_channel_t *chan, const char *file, const char *func, int line) +static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *func, int line, ftdm_channel_t *chan) { ftdm_status_t status = FTDM_SUCCESS; - ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP); - ftdm_set_echocancel_call_end(chan); if (chan->state != FTDM_CHANNEL_STATE_DOWN) { @@ -2135,6 +2186,11 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(ftdm_channel_t *chan, const ch if (chan->hangup_timer) { ftdm_sched_cancel_timer(globals.timingsched, chan->hangup_timer); } + ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP); + /* if a state change requested by the user was pending, a hangup certainly cancels that request */ + if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_channel_cancel_state(file, func, line, chan); + } status = ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1); } else { /* the signaling stack did not touch the state, @@ -2158,7 +2214,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, ftdmchan->caller_data.hangup_cause = cause; - status = _ftdm_channel_call_hangup_nl(ftdmchan, file, func, line); + status = _ftdm_channel_call_hangup_nl(file, func, line, ftdmchan); ftdm_channel_unlock(ftdmchan); return status; @@ -2172,7 +2228,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING; - status = _ftdm_channel_call_hangup_nl(ftdmchan, file, func, line); + status = _ftdm_channel_call_hangup_nl(file, func, line, ftdmchan); ftdm_channel_unlock(ftdmchan); return status; @@ -2238,13 +2294,13 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch ftdm_assert_return(ftdmchan, FTDM_FAIL, "Null channel\n"); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Indicating %s in state %s\n", + ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Indicating %s in state %s\n", ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); ftdm_channel_lock(ftdmchan); if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n", + ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n", ftdm_channel_indication2str(indication), ftdm_channel_indication2str(ftdmchan->indication), ftdm_channel_state2str(ftdmchan->state)); @@ -2253,17 +2309,19 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch } ftdmchan->indication = indication; - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) { + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING); + } if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot indicate %s in outgoing channel in state %s\n", + ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in outgoing channel in state %s\n", ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); status = FTDM_EINVAL; goto done; } if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring indication %s because the call is in %s state\n", + ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Ignoring indication %s because the call is in %s state\n", ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state)); status = FTDM_ECANCELED; goto done; @@ -2279,7 +2337,8 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1); break; case FTDM_CHANNEL_INDICATE_PROCEED: - if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE)) { + if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_PROCEED_STATE) || + ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) { ftdm_ack_indication(ftdmchan, indication, status); goto done; } @@ -2299,14 +2358,13 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch /* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */ if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring progress media because the call is terminating\n"); + ftdm_log_chan_ex_msg(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Ignoring progress media because the call is terminating\n"); goto done; } } status = ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1); break; case FTDM_CHANNEL_INDICATE_ANSWER: - /* _ftdm_channel_call_answer takes care of the indication ack */ status = _ftdm_channel_call_answer_nl(file, func, line, ftdmchan); break; default: @@ -2352,61 +2410,151 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func return FTDM_SUCCESS; } -FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) +static ftdm_status_t _ftdm_channel_call_place_nl(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) { - status = ftdmchan->span->outgoing_call(ftdmchan); - } else { - status = FTDM_NOTIMPL; - ftdm_log(FTDM_LOG_ERROR, "outgoing_call method not implemented in this span!\n"); + if (!ftdmchan->span->outgoing_call) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "outgoing_call method not implemented in this span!\n"); + status = FTDM_ENOSYS; + goto done; } - if (status == FTDM_SUCCESS) { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED); - ftdm_call_set_call_id(ftdmchan, &ftdmchan->caller_data); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot place call in channel that is not open!\n"); + goto done; + } + + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot place call in non outbound channel in state %s!\n", ftdm_channel_state2str(ftdmchan->state)); + goto done; + } + + if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) { + ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot place call in channel in state %s!\n", ftdm_channel_state2str(ftdmchan->state)); + goto done; + } + + status = ftdmchan->span->outgoing_call(ftdmchan); + if (status == FTDM_BREAK) { + /* the signaling module detected glare on time */ + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Glare detected, you should hunt in another channel!\n"); + goto done; + } + + if (status != FTDM_SUCCESS) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to place call!\n"); + goto done; + } + + /* in case of success, *before* unlocking the channel, we must set the call started flag and the call id + * that is a guarantee that signaling modules expect from us */ + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED); + ftdm_call_set_call_id(ftdmchan, &ftdmchan->caller_data); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NONBLOCK)) { + /* be aware this waiting unlocks the channel and locks it back when done */ ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100); } - ftdm_channel_unlock(ftdmchan); - +done: #ifdef __WINDOWS__ UNREFERENCED_PARAMETER(file); UNREFERENCED_PARAMETER(func); UNREFERENCED_PARAMETER(line); #endif + return status; +} + +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_channel_lock(ftdmchan); + + status = _ftdm_channel_call_place_nl(file, func, line, ftdmchan); + + ftdm_channel_unlock(ftdmchan); + return status; +} + +FT_DECLARE(ftdm_status_t) _ftdm_call_place(const char *file, const char *func, int line, + ftdm_caller_data_t *caller_data, ftdm_hunting_scheme_t *hunting) +{ + ftdm_status_t status = FTDM_SUCCESS; + ftdm_channel_t *fchan = NULL; + + ftdm_assert_return(caller_data, FTDM_EINVAL, "Invalid caller data\n"); + ftdm_assert_return(hunting, FTDM_EINVAL, "Invalid hunting scheme\n"); + + if (hunting->mode == FTDM_HUNT_SPAN) { + status = _ftdm_channel_open_by_span(hunting->mode_data.span.span_id, + hunting->mode_data.span.direction, caller_data, &fchan); + } else if (hunting->mode == FTDM_HUNT_GROUP) { + status = _ftdm_channel_open_by_group(hunting->mode_data.group.group_id, + hunting->mode_data.group.direction, caller_data, &fchan); + } else if (hunting->mode == FTDM_HUNT_CHAN) { + status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan); + } else { + ftdm_log(FTDM_LOG_ERROR, "Cannot make outbound call with invalid hunting mode %d\n", hunting->mode); + return FTDM_EINVAL; + } + + if (status != FTDM_SUCCESS) { + return FTDM_EBUSY; + } + + /* we have a locked channel and are not afraid of using it! */ + status = hunting->result_cb(fchan, caller_data); + if (status != FTDM_SUCCESS) { + status = FTDM_ECANCELED; + goto done; + } + + ftdm_channel_set_caller_data(fchan, caller_data); + + status = _ftdm_channel_call_place_nl(file, func, line, fchan); + if (status != FTDM_SUCCESS) { + _ftdm_channel_call_hangup_nl(file, func, line, fchan); + goto done; + } + + caller_data->fchan = fchan; +done: + ftdm_channel_unlock(fchan); return status; } -FT_DECLARE(ftdm_status_t) ftdm_channel_set_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t sigstatus) +FT_DECLARE(ftdm_status_t) ftdm_channel_set_sig_status(ftdm_channel_t *fchan, ftdm_signaling_status_t sigstatus) { - ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel\n"); - ftdm_assert_return(ftdmchan->span != NULL, FTDM_FAIL, "Null span\n"); + ftdm_status_t res; + + ftdm_assert_return(fchan != NULL, FTDM_FAIL, "Null channel\n"); + ftdm_assert_return(fchan->span != NULL, FTDM_FAIL, "Null span\n"); + ftdm_assert_return(fchan->span->set_channel_sig_status != NULL, FTDM_ENOSYS, "Not implemented\n"); + + ftdm_channel_lock(fchan); + + if (ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) { + ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "You can not set the signaling status of an alarmed channel\n"); + res = FTDM_EINVAL; + goto done; + } if (sigstatus == FTDM_SIG_STATE_DOWN) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "The user is not allowed to set the signaling status to DOWN, valid states are UP or SUSPENDED\n"); - return FTDM_FAIL; + ftdm_log_chan_msg(fchan, FTDM_LOG_WARNING, "You can not set the signaling status to DOWN, valid states are UP or SUSPENDED\n"); + res = FTDM_EINVAL; + goto done; } - if (ftdmchan->span->set_channel_sig_status) { - ftdm_status_t res; - ftdm_channel_lock(ftdmchan); - res = ftdmchan->span->set_channel_sig_status(ftdmchan, sigstatus); - ftdm_channel_unlock(ftdmchan); - return res; - } else { - ftdm_log(FTDM_LOG_ERROR, "set_channel_sig_status method not implemented!\n"); - return FTDM_FAIL; - } + res = fchan->span->set_channel_sig_status(fchan, sigstatus); +done: + + ftdm_channel_unlock(fchan); + + return res; } FT_DECLARE(ftdm_status_t) ftdm_channel_get_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t *sigstatus) @@ -2576,10 +2724,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan) ftdm_log_chan_msg(check, FTDM_LOG_WARNING, "Channel not opened, proceeding anyway\n"); } status = check->fio->close(check); - if (status == FTDM_SUCCESS) { - ftdm_channel_done(check); - *ftdmchan = NULL; - } + ftdm_assert(status == FTDM_SUCCESS, "Failed to close channel!\n"); + ftdm_channel_done(check); + *ftdmchan = NULL; check->ring_count = 0; ftdm_mutex_unlock(check->mutex); } @@ -2921,23 +3068,27 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co case FTDM_COMMAND_ENABLE_DTMF_DETECT: { /* if they don't have thier own, use ours */ - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) { - teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled software DTMF detector\n"); - GOTO_STATUS(done, FTDM_SUCCESS); + if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { + if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) { + teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Enabled software DTMF detector\n"); + GOTO_STATUS(done, FTDM_SUCCESS); + } } } break; case FTDM_COMMAND_DISABLE_DTMF_DETECT: { - if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) { - teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); - ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n"); - GOTO_STATUS(done, FTDM_SUCCESS); + if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) { + if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) { + teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT); + ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n"); + GOTO_STATUS(done, FTDM_SUCCESS); + } } } break; @@ -5094,6 +5245,16 @@ FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span) goto done; } + /* check the alarms again before starting the signaling module + this works-around some I/O modules (netborder I/O module) that cannot + check the alarm status before during configuration because the spans are + not really started yet at the I/O level */ + if (ftdm_set_channels_alarms(span, 0) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "Failed to set channel alarms in span %s\n", span->name); + status = FTDM_FAIL; + goto done; + } + status = span->start(span); if (status == FTDM_SUCCESS) { ftdm_set_flag_locked(span, FTDM_SPAN_STARTED); @@ -5327,7 +5488,7 @@ static void execute_safety_hangup(void *data) fchan->hangup_timer = 0; if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) { ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER); - _ftdm_channel_call_hangup_nl(fchan, __FILE__, __FUNCTION__, __LINE__); + _ftdm_channel_call_hangup_nl(__FILE__, __FUNCTION__, __LINE__, fchan); } else { ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state)); } @@ -5337,7 +5498,10 @@ static void execute_safety_hangup(void *data) FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg) { if (sigmsg->channel) { - ftdm_mutex_lock(sigmsg->channel->mutex); + ftdm_mutex_lock(sigmsg->channel->mutex); + sigmsg->chan_id = sigmsg->channel->chan_id; + sigmsg->span_id = sigmsg->channel->span_id; + sigmsg->call_id = sigmsg->channel->caller_data.call_id; } /* some core things to do on special events */ @@ -5347,14 +5511,26 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t { if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_UP) { ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); + ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED); } else { ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP); + if (sigmsg->ev_data.sigstatus.status == FTDM_SIG_STATE_SUSPENDED) { + ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED); + } else { + ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SUSPENDED); + } } } break; case FTDM_SIGEVENT_START: { + ftdm_assert(!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED), "Started call twice!"); + + if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_OUTBOUND)) { + ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_WARNING, "Inbound call taking over outbound channel\n"); + ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_OUTBOUND); + } ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED); ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data); ftdm_set_echocancel_call_begin(sigmsg->channel); @@ -5370,20 +5546,46 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t } break; + case FTDM_SIGEVENT_PROGRESS_MEDIA: + { + /* test signaling module compliance */ + if (sigmsg->channel->state != FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { + ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_PROGRESS_MEDIA sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state)); + } + } + break; + + case FTDM_SIGEVENT_UP: + { + /* test signaling module compliance */ + if (sigmsg->channel->state != FTDM_CHANNEL_STATE_UP) { + ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_UP sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state)); + } + } + break; + case FTDM_SIGEVENT_STOP: - if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) { - /* this happens for FXS devices which blindly send SIGEVENT_STOP, we should fix it there ... */ - ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n"); - goto done; - } - if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) { - 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); + { + /* TODO: we could test for compliance here and check the state is FTDM_CHANNEL_STATE_TERMINATING + * but several modules need to be updated first */ + + /* if the call was never started, do not send SIGEVENT_STOP + this happens for FXS devices in ftmod_analog which blindly send SIGEVENT_STOP, we should fix it there ... */ + if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) { + ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n"); + goto done; + } + + if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) { + 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; @@ -5392,9 +5594,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t } - if (sigmsg->channel) { - sigmsg->call_id = sigmsg->channel->caller_data.call_id; - } /* if the signaling module uses a queue for signaling notifications, then enqueue it */ if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) { ftdm_span_queue_signal(span, sigmsg); diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index f6c2c2320c..de62c0f0e7 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -70,22 +70,25 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c if (state == FTDM_CHANNEL_STATE_PROGRESS) { ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); - } else if (state == FTDM_CHANNEL_STATE_UP) { - ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); - ftdm_set_flag(fchan, FTDM_CHANNEL_MEDIA); - ftdm_set_flag(fchan, FTDM_CHANNEL_ANSWERED); } else if (state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); - ftdm_set_flag(fchan, FTDM_CHANNEL_MEDIA); + ftdm_test_and_set_media(fchan); + } else if (state == FTDM_CHANNEL_STATE_UP) { + ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS); + ftdm_set_flag(fchan, FTDM_CHANNEL_ANSWERED); + ftdm_test_and_set_media(fchan); + } else if (state == FTDM_CHANNEL_STATE_DIALING) { + ftdm_sigmsg_t msg; + memset(&msg, 0, sizeof(msg)); + msg.channel = fchan; + msg.event_id = FTDM_SIGEVENT_DIALING; + ftdm_span_send_signal(fchan->span, &msg); } - /* if there is a pending ack for an indication - * MAINTENANCE WARNING: we're assuming an indication performed - * via state change will involve a single state change - */ - if (ftdm_test_flag(fchan, FTDM_CHANNEL_IND_ACK_PENDING)) { - ftdm_ack_indication(fchan, fchan->indication, FTDM_SUCCESS); - } + /* MAINTENANCE WARNING + * we're assuming an indication performed + * via state change will involve a single state change */ + ftdm_ack_indication(fchan, fchan->indication, FTDM_SUCCESS); hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1); @@ -167,6 +170,59 @@ static int ftdm_parse_state_map(ftdm_channel_t *ftdmchan, ftdm_channel_state_t s return ok; } +FT_DECLARE(ftdm_status_t) ftdm_channel_cancel_state(const char *file, const char *func, int line, ftdm_channel_t *fchan) +{ + ftdm_time_t diff; + ftdm_channel_state_t state; + ftdm_channel_state_t last_state; + uint8_t hindex = 0; + + if (!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE)) { + ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Cannot cancel state change from %s to %s, it was already processed\n", + ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(fchan->state)); + return FTDM_FAIL; + } + + if (fchan->state_status != FTDM_STATE_STATUS_NEW) { + ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Failed to cancel state change from %s to %s, state is not new anymore\n", + ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(fchan->state)); + return FTDM_FAIL; + } + + /* compute the last history index */ + hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1); + diff = fchan->history[hindex].end_time - fchan->history[hindex].time; + + /* go back in time and revert the state to the previous state */ + state = fchan->state; + last_state = fchan->last_state; + + fchan->state = fchan->last_state; + fchan->state_status = FTDM_STATE_STATUS_COMPLETED; + fchan->last_state = fchan->history[hindex].last_state; + fchan->hindex = hindex; + + /* clear the state change flag */ + ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE); + + /* ack any pending indications as cancelled */ + ftdm_ack_indication(fchan, fchan->indication, FTDM_ECANCELED); + + /* wake up anyone sleeping waiting for the state change to complete, it won't ever be completed */ + if (ftdm_test_flag(fchan, FTDM_CHANNEL_BLOCKING)) { + ftdm_clear_flag(fchan, FTDM_CHANNEL_BLOCKING); + ftdm_interrupt_signal(fchan->state_completed_interrupt); + } + + /* NOTE + * we could potentially also take out the channel from the pendingchans queue, but I believe is easier just leave it, + * the only side effect will be a call to ftdm_channel_advance_states() for a channel that has nothing to advance */ + ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Cancelled state change from %s to %s in %llums\n", + ftdm_channel_state2str(last_state), ftdm_channel_state2str(state), diff); + + return FTDM_SUCCESS; +} + /* this function MUST be called with the channel lock held. If waitrq == 1, the channel will be unlocked/locked (never call it with waitrq == 1 with an lock recursivity > 1) */ #define DEFAULT_WAIT_TIME 1000 FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int waitrq) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 8be6d579e1..2f9c70a48d 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -406,25 +406,36 @@ static ftdm_state_map_t isdn_state_map = { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_DIALING, FTDM_END}, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END} + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, + FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, + FTDM_CHANNEL_STATE_UP, FTDM_END} }, { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END} + {FTDM_CHANNEL_STATE_PROCEED, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, + FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, }, { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END} + {FTDM_CHANNEL_STATE_RINGING, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, + FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, }, { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, + {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, + FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END} + }, + { + ZSD_OUTBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, + {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END} }, { ZSD_OUTBOUND, @@ -432,6 +443,24 @@ static ftdm_state_map_t isdn_state_map = { {FTDM_CHANNEL_STATE_UP, FTDM_END}, {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END} }, + { + ZSD_OUTBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, + {FTDM_CHANNEL_STATE_HANGUP, FTDM_END} + }, + { + ZSD_OUTBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_HANGUP, FTDM_END}, + {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, + }, + { + ZSD_OUTBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, + {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, + }, /****************************************/ { @@ -462,26 +491,33 @@ static ftdm_state_map_t isdn_state_map = { ZSD_INBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_RING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END} + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_END} }, { ZSD_INBOUND, ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}, + {FTDM_CHANNEL_STATE_PROCEED, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, + FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END} }, { ZSD_INBOUND, ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, + {FTDM_CHANNEL_STATE_RINGING, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, + FTDM_CHANNEL_STATE_UP, FTDM_END} }, { ZSD_INBOUND, ZSM_UNACCEPTABLE, - {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, - {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, - FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END}, + {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END} + }, + { + ZSD_INBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_UP, FTDM_END} }, { ZSD_INBOUND, @@ -489,6 +525,24 @@ static ftdm_state_map_t isdn_state_map = { {FTDM_CHANNEL_STATE_UP, FTDM_END}, {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, }, + { + ZSD_INBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}, + {FTDM_CHANNEL_STATE_HANGUP, FTDM_END}, + }, + { + ZSD_INBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_HANGUP, FTDM_END}, + {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, + }, + { + ZSD_INBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, + {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, + }, } }; @@ -533,8 +587,6 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) break; case FTDM_CHANNEL_STATE_PROGRESS: - /* RINGING is an alias for PROGRESS state in inbound calls ATM */ - case FTDM_CHANNEL_STATE_RINGING: { if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { sig.event_id = FTDM_SIGEVENT_PROGRESS; @@ -542,7 +594,23 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); } } else if (call) { - pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); + pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); + } else { + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); + } + } + break; + + case FTDM_CHANNEL_STATE_RINGING: + { + if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { + sig.event_id = FTDM_SIGEVENT_RINGING; + if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) { + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); + } + } else if (call) { +// pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); + pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); } else { ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); } @@ -561,7 +629,26 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { ftdm_channel_open_chan(chan); } - pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); + pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1); + } else { + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); + } + } + break; + + case FTDM_CHANNEL_STATE_PROCEED: + { + if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { + /* PROCEED from other end, notify user */ + sig.event_id = FTDM_SIGEVENT_PROCEED; + if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) { + ftdm_log(FTDM_LOG_ERROR, "Failed to send PROCEED sigevent on Channel %d:%d\n", + ftdm_channel_get_span_id(chan), + ftdm_channel_get_id(chan)); + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); + } + } else if (call) { + pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); } else { ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART); } @@ -572,11 +659,12 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) { /* * This needs more auditing for BRI PTMP: - * does pri_acknowledge() steal the call from other devices? + * does pri_acknowledge() steal the call from other devices? (yes, it does) */ if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) { if (call) { - pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); + pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); +// pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0); sig.event_id = FTDM_SIGEVENT_START; if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) { ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP); @@ -690,15 +778,22 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan); pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause); - pri_destroycall(isdn_data->spri.pri, call); +// pri_destroycall(isdn_data->spri.pri, call); chan->call_data = NULL; } - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); } break; case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: + { + if (call) { + pri_destroycall(isdn_data->spri.pri, call); + chan->call_data = NULL; + } + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); + } break; case FTDM_CHANNEL_STATE_TERMINATING: @@ -869,7 +964,7 @@ static int on_proceeding(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ } } ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROCEED); } else { ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d but it's not in the span?\n", ftdm_span_get_id(span), pevent->proceeding.channel); @@ -909,9 +1004,12 @@ static int on_progress(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING); goto out; } + ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d with media\n", ftdm_span_get_id(span), pevent->proceeding.channel); + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } else { + ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel); + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS); } - ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel); - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else { ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d but it's not in the span?\n", ftdm_span_get_id(span), pevent->proceeding.channel); @@ -936,10 +1034,10 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d\n", ftdm_span_get_id(span), pevent->ringing.channel); /* we may get on_ringing even when we're already in FTDM_CHANNEL_STATE_PROGRESS_MEDIA */ - if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { - /* dont try to move to STATE_PROGRESS to avoid annoying veto warning */ - return 0; - } +// if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) { +// /* dont try to move to STATE_PROGRESS to avoid annoying veto warning */ +// return 0; +// } /* Open channel if inband information is available */ if ((pevent->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) && !ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { @@ -959,7 +1057,8 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve goto out; } } - ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS); +// ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS); + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RINGING); } else { ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d but it's not in the span?\n", ftdm_span_get_id(span), pevent->ringing.channel); @@ -1913,6 +2012,9 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span) span->get_channel_sig_status = isdn_get_channel_sig_status; span->get_span_sig_status = isdn_get_span_sig_status; + /* move calls to PROCEED state when they hit dialplan (ROUTING state in FreeSWITCH) */ + ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE); + if ((isdn_data->opts & FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL)) { span->channel_request = isdn_channel_request; ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID); diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 79850a3c1f..0217a5172a 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -50,8 +50,6 @@ #include "freetdm.h" #include "private/ftdm_core.h" -typedef int openr2_call_status_t; - /* when the user stops a span, we clear FTDM_R2_SPAN_STARTED, so that the signaling thread * knows it must stop, and we wait for FTDM_R2_RUNNING to be clear, which tells us the * signaling thread is done. */ @@ -71,8 +69,8 @@ typedef struct ftdm_r2_call_t { int accepted:1; int answer_pending:1; int disconnect_rcvd:1; - int ftdm_call_started:1; int protocol_error:1; + int localsuspend_on_alarm:1; ftdm_size_t dnis_index; ftdm_size_t ani_index; char logname[255]; @@ -293,8 +291,11 @@ static ftdm_call_cause_t ftdm_r2_cause_to_ftdm_cause(ftdm_channel_t *fchan, open case OR2_CAUSE_FORCED_RELEASE: return FTDM_CAUSE_NORMAL_CLEARING; + + case OR2_CAUSE_GLARE: + return FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL; } - ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Mapping openr2 cause %d to unspecified\n", cause); + ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "Mapping openr2 cause %d to unspecified\n", cause); return FTDM_CAUSE_NORMAL_UNSPECIFIED; } @@ -329,6 +330,9 @@ static openr2_call_disconnect_cause_t ftdm_r2_ftdm_cause_to_openr2_cause(ftdm_ch case FTDM_CAUSE_NORMAL_UNSPECIFIED: return OR2_CAUSE_UNSPECIFIED; + case FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL: + return OR2_CAUSE_GLARE; + } ftdm_log_chan(fchan, FTDM_LOG_WARNING, "freetdm hangup cause %d mapped to openr2 cause %s\n", fchan->caller_data.hangup_cause, openr2_proto_get_disconnect_string(OR2_CAUSE_UNSPECIFIED)); @@ -345,7 +349,6 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call) call->accepted = 0; call->answer_pending = 0; call->disconnect_rcvd = 0; - call->ftdm_call_started = 0; call->protocol_error = 0; call->dnis_index = 0; call->ani_index = 0; @@ -437,19 +440,12 @@ static __inline openr2_calling_party_category_t ftdm_r2_ftdm_cpc_to_openr2_cpc(f /* this function must be called with the chan mutex held! */ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) { - openr2_call_status_t callstatus; + int ret; ftdm_r2_data_t *r2data; openr2_calling_party_category_t category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; r2data = ftdmchan->span->signal_data; - if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) { - /* collision, an incoming seized the channel between our take and use timing */ - ftdm_log_chan(ftdmchan, - FTDM_LOG_CRIT, "R2 cannot dial out in channel in state %s, try another channel!.\n", ftdm_channel_state2str(ftdmchan->state)); - return FTDM_FAIL; - } - ft_r2_clean_call(ftdmchan->call_data); if (ftdmchan->caller_data.cpc == FTDM_CPC_INVALID || ftdmchan->caller_data.cpc == FTDM_CPC_UNKNOWN) { @@ -464,18 +460,17 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_OUTPUT_DUMP, &r2data->mf_dump_size); } - callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, + ret = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, ftdmchan->caller_data.cid_num.digits, ftdmchan->caller_data.dnis.digits, category, ftdmchan->caller_data.pres == FTDM_PRES_ALLOWED ? 0 : 1); - if (callstatus) { + if (ret) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n"); return FTDM_FAIL; } - R2CALL(ftdmchan)->ftdm_call_started = 1; ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING); ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS); @@ -505,8 +500,16 @@ static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span) static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_channel_sig_status) { + openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan; + openr2_cas_signal_t rxcas, txcas; + + /* get the current rx and tx cas bits */ + openr2_chan_get_cas(r2chan, &rxcas, &txcas); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { *status = FTDM_SIG_STATE_UP; + } else if (rxcas == OR2_CAS_BLOCK || txcas == OR2_CAS_BLOCK) { + *status = FTDM_SIG_STATE_SUSPENDED; } else { *status = FTDM_SIG_STATE_DOWN; } @@ -567,6 +570,11 @@ static FIO_SPAN_GET_SIG_STATUS_FUNCTION(ftdm_r2_get_span_sig_status) for (citer = chaniter; citer; citer = ftdm_iterator_next(citer)) { ftdm_channel_t *fchan = ftdm_iterator_current(citer); ftdm_channel_lock(fchan); + if (ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM)) { + *status = FTDM_SIG_STATE_DOWN; + ftdm_channel_unlock(fchan); + break; + } if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) { *status = FTDM_SIG_STATE_UP; ftdm_channel_unlock(fchan); @@ -639,9 +647,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan) return; } - /* mark the channel in use (so no outgoing calls can be placed here) */ - ftdm_channel_use(ftdmchan); - memset(ftdmchan->caller_data.dnis.digits, 0, sizeof(ftdmchan->caller_data.collected)); memset(ftdmchan->caller_data.ani.digits, 0, sizeof(ftdmchan->caller_data.collected)); @@ -826,8 +831,17 @@ static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm) { - ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Alarm notification: %d\n", alarm); + ftdm_channel_t *fchan = openr2_chan_get_client_data(r2chan); + + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Alarm notification %d when in state %s (sigstatus = %d)\n", + alarm, ftdm_channel_state2str(fchan->state), ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP) ? 1 : 0); + + if (alarm) { + R2CALL(fchan)->localsuspend_on_alarm = ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED) ? 1 : 0; + if (ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP) || ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) { + ftdm_r2_set_chan_sig_status(fchan, FTDM_SIG_STATE_DOWN); + } + } } static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode) @@ -881,14 +895,31 @@ static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan) { ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end blocked in state %s\n", ftdm_channel_state2str(ftdmchan->state)); - ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP) + || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { + ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED); + } } static void ftdm_r2_on_line_idle(openr2_chan_t *r2chan) { + openr2_cas_signal_t rxcas, txcas; ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan); + + /* get the current rx and tx cas bits */ + openr2_chan_get_cas(r2chan, &rxcas, &txcas); ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end unblocked in state %s\n", ftdm_channel_state2str(ftdmchan->state)); - ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP) + && txcas == OR2_CAS_IDLE) { + /* if txcas is not idle, it means we're still blocked as far as the user is concerned, do not send SIGEVENT UP, + * it will be done when the user set the line to IDLE (if the remote is still also IDLE) */ + ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP); + } else if (txcas == OR2_CAS_BLOCK && R2CALL(ftdmchan)->localsuspend_on_alarm) { + /* the user requested to block, we do not notify about state up until the user set the bits to IDLE, however + * if we're just getting back from alarmed condition, we notify about suspended again */ + ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED); + } + R2CALL(ftdmchan)->localsuspend_on_alarm = 0; } static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const char *function, int line, const char *message) @@ -920,7 +951,7 @@ static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const static void ftdm_r2_on_context_log(openr2_context_t *r2context, const char *file, const char *function, unsigned int line, openr2_log_level_t level, const char *fmt, va_list ap) { -#define CONTEXT_TAG "Context -" +#define CONTEXT_TAG "Context - " char logmsg[256]; char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1]; vsnprintf(logmsg, sizeof(logmsg), fmt, ap); @@ -1007,8 +1038,19 @@ static void ftdm_r2_on_call_log_created(openr2_chan_t *r2chan, const char *logna snprintf(r2call->logname, sizeof(r2call->logname), "%s", logname); } +static void ftdm_r2_on_call_proceed(openr2_chan_t *r2chan) +{ + ftdm_sigmsg_t sigev; + ftdm_channel_t *fchan = openr2_chan_get_client_data(r2chan); + memset(&sigev, 0, sizeof(sigev)); + sigev.event_id = FTDM_SIGEVENT_PROCEED; + sigev.channel = fchan; + ftdm_span_send_signal(fchan->span, &sigev); +} + static openr2_event_interface_t ftdm_r2_event_iface = { /* .on_call_init */ ftdm_r2_on_call_init, + /* .on_call_proceed */ ftdm_r2_on_call_proceed, /* .on_call_offered */ ftdm_r2_on_call_offered, /* .on_call_accepted */ ftdm_r2_on_call_accepted, /* .on_call_answered */ ftdm_r2_on_call_answered, @@ -1186,6 +1228,14 @@ static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *e return 0; } +static int ftdm_r2_io_get_alarm_state(openr2_chan_t *r2chan, int *alarm) +{ + ftdm_channel_t *fchan = openr2_chan_get_fd(r2chan); + ftdm_assert_return(alarm, -1, "Alarm pointer is null\n"); + *alarm = ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM) ? 1 : 0; + return 0; +} + static openr2_io_interface_t ftdm_r2_io_iface = { /* .open */ ftdm_r2_io_open, /* never called */ /* .close */ ftdm_r2_io_close, /* never called */ @@ -1196,7 +1246,8 @@ static openr2_io_interface_t ftdm_r2_io_iface = { /* .read */ ftdm_r2_io_read, /* .setup */ ftdm_r2_io_setup, /* never called */ /* .wait */ ftdm_r2_io_wait, - /* .get_oob_event */ ftdm_r2_io_get_oob_event /* never called */ + /* .get_oob_event */ ftdm_r2_io_get_oob_event, + /* .get_alarm_state */ ftdm_r2_io_get_alarm_state }; /* resolve a loglevel string, such as "debug,notice,warning", to an openr2 log level integer */ @@ -1691,8 +1742,7 @@ static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) uint32_t interval = 0; ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval); ftdm_assert(interval != 0, "Invalid interval!"); - ftdm_log_chan(ftdmchan, - FTDM_LOG_DEBUG, "Starting processing of outgoing call in channel with interval %d\n", interval); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Starting outgoing call with interval %d\n", interval); openr2_chan_enable_read(r2chan); } break; @@ -1702,10 +1752,7 @@ static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) /* notify the user about the new call */ sigev.event_id = FTDM_SIGEVENT_START; - ftdm_span_send_signal(ftdmchan->span, &sigev); - r2call->ftdm_call_started = 1; - break; /* the call is making progress */ @@ -1719,9 +1766,6 @@ static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) } } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Notifying progress\n"); - sigev.event_id = FTDM_SIGEVENT_PROCEED; - ftdm_span_send_signal(ftdmchan->span, &sigev); - sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA; ftdm_span_send_signal(ftdmchan->span, &sigev); } @@ -1772,7 +1816,7 @@ static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan) case FTDM_CHANNEL_STATE_TERMINATING: { /* if the call has not been started yet we must go to HANGUP right here */ - if (!r2call->ftdm_call_started) { + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP); } else { openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan); @@ -2001,9 +2045,6 @@ static void __inline__ block_channel(ftdm_channel_t *fchan, ftdm_stream_handle_t if (fchan->state != FTDM_CHANNEL_STATE_DOWN) { stream->write_function(stream, "cannot block channel %d:%d because has a call in progress\n", fchan->span_id, fchan->chan_id); - } else if (ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) { - stream->write_function(stream, "cannot block channel %d:%d because is already blocked\n", - fchan->span_id, fchan->chan_id); } else { if (!openr2_chan_set_blocked(r2chan)) { ftdm_set_flag(fchan, FTDM_CHANNEL_SUSPENDED); @@ -2021,17 +2062,12 @@ static void __inline__ unblock_channel(ftdm_channel_t *fchan, ftdm_stream_handle { openr2_chan_t *r2chan = R2CALL(fchan)->r2chan; ftdm_mutex_lock(fchan->mutex); - if (ftdm_test_flag(fchan, FTDM_CHANNEL_SUSPENDED)) { - if (!openr2_chan_set_idle(r2chan)) { - ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED); - stream->write_function(stream, "unblocked channel %d:%d\n", - fchan->span_id, fchan->chan_id); - } else { - stream->write_function(stream, "failed to unblock channel %d:%d\n", - fchan->span_id, fchan->chan_id); - } + if (!openr2_chan_set_idle(r2chan)) { + ftdm_clear_flag(fchan, FTDM_CHANNEL_SUSPENDED); + stream->write_function(stream, "unblocked channel %d:%d\n", + fchan->span_id, fchan->chan_id); } else { - stream->write_function(stream, "cannot unblock channel %d:%d because is not blocked\n", + stream->write_function(stream, "failed to unblock channel %d:%d\n", fchan->span_id, fchan->chan_id); } ftdm_mutex_unlock(fchan->mutex); 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 259bf18b81..f2afd1cf9c 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 @@ -120,7 +120,7 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_INBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_RING, FTDM_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END} + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END} }, { ZSD_INBOUND, @@ -139,7 +139,7 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_INBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, }, { ZSD_INBOUND, @@ -234,7 +234,7 @@ ftdm_state_map_t sangoma_isdn_state_map = { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_RINGING, FTDM_END}, - {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, + {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}, }, { ZSD_OUTBOUND, @@ -788,21 +788,21 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm /* set the flag to indicate this hangup is started from the local side */ sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_REL); - /* If we never sent ack to incoming call, we need to send release instead of disconnect */ - 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)) { - sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN); - } - } else { - sngisdn_snd_disconnect(ftdmchan); + switch(ftdmchan->last_state) { + case FTDM_CHANNEL_STATE_RING: + /* If we never sent PROCEED/ALERT/PROGRESS/CONNECT on an incoming call, we need to send release instead of disconnect */ + sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT); + sngisdn_snd_release(ftdmchan, 0); + break; + case FTDM_CHANNEL_STATE_DIALING: + /* If we never received a PROCEED/ALERT/PROGRESS/CONNECT on an outgoing call, we need to send release instead of disconnect */ + sngisdn_snd_release(ftdmchan, 0); + break; + default: + sngisdn_snd_disconnect(ftdmchan); + break; } } - /* now go to the HANGUP complete state */ ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); } @@ -884,6 +884,7 @@ static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg) switch (sigmsg->event_id) { case FTDM_SIGEVENT_FACILITY: sngisdn_snd_fac_req(ftdmchan); + status = FTDM_SUCCESS; break; default: ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unsupported signalling msg requested\n"); @@ -931,7 +932,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_isdn_outgoing_call) ftdm_channel_unlock(ftdmchan); return status; } - static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_get_chan_sig_status) { if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) { @@ -1094,6 +1094,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) ftdm_set_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE); ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE); ftdm_set_flag(span, FTDM_SPAN_USE_SKIP_STATES); + ftdm_set_flag(span, FTDM_SPAN_NON_STOPPABLE); if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || span->trunk_type == FTDM_TRUNK_BRI) { 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 6a440e4f66..58fcc07040 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 @@ -47,11 +47,12 @@ #include #include "private/ftdm_core.h" +#include "ftmod_sangoma_isdn_user.h" #include /* Theoretical limit for MAX_SPANS_PER_NFAS_LINK is 31, - but set to 8 for now to save some memor */ + but set to 8 for now to save some memory */ #define MAX_SPANS_PER_NFAS_LINK 8 #define NUM_E1_CHANNELS_PER_SPAN 32 @@ -64,33 +65,6 @@ /* TODO: rename all *_cc_* to *_an_* */ -#define SNGISDN_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL }; -#define SNGISDN_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) _TYPE _FUNC1 (const char *name); const char * _FUNC2 (_TYPE type); -#define SNGISDN_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \ - _TYPE _FUNC1 (const char *name) \ -{ \ - int i; \ - _TYPE t = _MAX ; \ - \ - for (i = 0; i < _MAX ; i++) { \ - if (!strcasecmp(name, _STRINGS[i])) { \ - t = (_TYPE) i; \ - break; \ -} \ -} \ - \ - return t; \ -} \ - const char * _FUNC2 (_TYPE type) \ -{ \ - if (type > _MAX) { \ - type = _MAX; \ -} \ - return _STRINGS[(int)type]; \ -} \ - - - typedef enum { FLAG_RESET_RX = (1 << 0), FLAG_RESET_TX = (1 << 1), @@ -165,46 +139,6 @@ typedef enum { SNGISDN_EVENT_RST_IND, } ftdm_sngisdn_event_id_t; -typedef enum { - /* Call is not end-to-end ISDN */ - SNGISDN_PROGIND_DESCR_NETE_ISDN, - /* Destination address is non-ISDN */ - SNGISDN_PROGIND_DESCR_DEST_NISDN, - /* Origination address is non-ISDN */ - SNGISDN_PROGIND_DESCR_ORIG_NISDN, - /* Call has returned to the ISDN */ - SNGISDN_PROGIND_DESCR_RET_ISDN, - /* Interworking as occured and has resulted in a telecommunication service change */ - SNGISDN_PROGIND_DESCR_SERV_CHANGE, - /* In-band information or an appropriate pattern is now available */ - SNGISDN_PROGIND_DESCR_IB_AVAIL, - /* Invalid */ - SNGISDN_PROGIND_DESCR_INVALID, -} ftdm_sngisdn_progind_descr_t; -#define SNGISDN_PROGIND_DESCR_STRINGS "not-end-to-end-isdn", "destination-is-non-isdn", "origination-is-non-isdn", "call-returned-to-isdn", "service-change", "inband-info-available", "invalid" -SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t); - -typedef enum { - /* User */ - SNGISDN_PROGIND_LOC_USER, - /* Private network serving the local user */ - SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR, - /* Public network serving the local user */ - SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR, - /* Transit network */ - SNGISDN_PROGIND_LOC_TRANSIT_NET, - /* Public network serving remote user */ - SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR, - /* Private network serving remote user */ - SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR, - /* Network beyond the interworking point */ - SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW, - /* Invalid */ - SNGISDN_PROGIND_LOC_INVALID, -} ftdm_sngisdn_progind_loc_t; -#define SNGISDN_PROGIND_LOC_STRINGS "user", "private-net-local-user", "public-net-local-user", "transit-network", "public-net-remote-user", "private-net-remote-user", "beyond-interworking", "invalid" -SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t); - typedef struct ftdm_sngisdn_prog_ind { ftdm_sngisdn_progind_loc_t loc; /* location */ ftdm_sngisdn_progind_descr_t descr; /* description */ @@ -233,6 +167,7 @@ typedef struct sngisdn_chan_data { uint32_t flags; uint8_t ces; /* used only for BRI, otherwise always 0 */ uint8_t dchan_id; + uint16_t call_ref; /* Q.931 call reference, only valid for ETSI/INSNET/QSIG */ uint32_t suInstId; /* instance ID generated locally */ uint32_t spInstId; /* instance ID generated by stack */ @@ -446,6 +381,9 @@ void sngisdn_rcv_cc_ind(CcMngmt *status); void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...); void sngisdn_rcv_sng_assert(char *message); +#ifdef NETBORDER_CALL_REF +ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef); +#endif ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb); ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb); @@ -470,11 +408,10 @@ ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd); ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr); ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len); - -uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability); -uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot); -ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability); -ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot); +uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability); +uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_prot); +ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability); +ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_stack(uint8_t layer1_prot); static __inline__ uint32_t sngisdn_test_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag) { @@ -515,3 +452,15 @@ void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span); #endif /* __FTMOD_SNG_ISDN_H__ */ +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ + +/******************************************************************************/ 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 c979000223..aad68e15d1 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 @@ -38,6 +38,7 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span); static ftdm_status_t add_local_number(const char* val, ftdm_span_t *span); static ftdm_status_t parse_yesno(const char* var, const char* val, uint8_t *target); +static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span); extern ftdm_sngisdn_data_t g_sngisdn_data; @@ -149,7 +150,7 @@ static ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span 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); + ftdm_log(FTDM_LOG_DEBUG, "%s: cc_id:%d dchan_id:%d span_id:%d link_id:%d\n", span->name, signal_data->cc_id, signal_data->dchan_id, signal_data->span_id, signal_data->link_id); chaniter = ftdm_span_get_chan_iterator(span, NULL); @@ -191,6 +192,63 @@ static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) return FTDM_SUCCESS; } +static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + switch(signal_data->switchtype) { + case SNGISDN_SWITCH_NI2: + case SNGISDN_SWITCH_5ESS: + case SNGISDN_SWITCH_4ESS: + case SNGISDN_SWITCH_DMS100: + if (span->default_caller_data.dnis.plan >= FTDM_NPI_INVALID) { + ftdm_set_npi("isdn", &span->default_caller_data.dnis.plan); + } + if (span->default_caller_data.dnis.type >= FTDM_TON_INVALID) { + ftdm_set_ton("national", &span->default_caller_data.dnis.type); + } + if (span->default_caller_data.cid_num.plan >= FTDM_NPI_INVALID) { + ftdm_set_npi("isdn", &span->default_caller_data.cid_num.plan); + } + if (span->default_caller_data.cid_num.type >= FTDM_TON_INVALID) { + ftdm_set_ton("national", &span->default_caller_data.cid_num.type); + } + if (span->default_caller_data.rdnis.plan >= FTDM_NPI_INVALID) { + ftdm_set_npi("isdn", &span->default_caller_data.rdnis.plan); + } + if (span->default_caller_data.rdnis.type >= FTDM_TON_INVALID) { + ftdm_set_ton("national", &span->default_caller_data.rdnis.type); + } + break; + case SNGISDN_SWITCH_EUROISDN: + case SNGISDN_SWITCH_QSIG: + case SNGISDN_SWITCH_INSNET: + if (span->default_caller_data.dnis.plan >= FTDM_NPI_INVALID) { + ftdm_set_npi("unknown", &span->default_caller_data.dnis.plan); + } + if (span->default_caller_data.dnis.type >= FTDM_TON_INVALID) { + ftdm_set_ton("unknown", &span->default_caller_data.dnis.type); + } + if (span->default_caller_data.cid_num.plan >= FTDM_NPI_INVALID) { + ftdm_set_npi("unknown", &span->default_caller_data.cid_num.plan); + } + if (span->default_caller_data.cid_num.type >= FTDM_TON_INVALID) { + ftdm_set_ton("unknown", &span->default_caller_data.cid_num.type); + } + if (span->default_caller_data.rdnis.plan >= FTDM_NPI_INVALID) { + ftdm_set_npi("unknown", &span->default_caller_data.rdnis.plan); + } + if (span->default_caller_data.rdnis.type >= FTDM_TON_INVALID) { + ftdm_set_ton("unknown", &span->default_caller_data.rdnis.type); + } + break; + case SNGISDN_SWITCH_INVALID: + default: + ftdm_log(FTDM_LOG_ERROR, "Unsupported switchtype[%d]\n", signal_data->switchtype); + return FTDM_FAIL; + } + return FTDM_SUCCESS; +} + ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) { unsigned paramindex; @@ -205,31 +263,19 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ signal_data->ignore_cause_value = SNGISDN_OPT_DEFAULT; signal_data->timer_t3 = 8; signal_data->restart_opt = SNGISDN_OPT_DEFAULT; - signal_data->link_id = span->span_id; - span->default_caller_data.bearer_capability = IN_ITC_SPEECH; + + span->default_caller_data.dnis.plan = FTDM_NPI_INVALID; + span->default_caller_data.dnis.type = FTDM_TON_INVALID; + span->default_caller_data.cid_num.plan = FTDM_NPI_INVALID; + span->default_caller_data.cid_num.type = FTDM_TON_INVALID; + span->default_caller_data.rdnis.plan = FTDM_NPI_INVALID; + span->default_caller_data.rdnis.type = FTDM_TON_INVALID; + span->default_caller_data.bearer_capability = IN_ITC_SPEECH; /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */ span->default_caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM; - if (span->trunk_type == FTDM_TRUNK_BRI || - span->trunk_type == FTDM_TRUNK_BRI_PTMP) { - - ftdm_set_npi("unknown", &span->default_caller_data.dnis.plan); - ftdm_set_ton("unknown", &span->default_caller_data.dnis.type); - ftdm_set_npi("unknown", &span->default_caller_data.cid_num.plan); - ftdm_set_ton("unknown", &span->default_caller_data.cid_num.type); - ftdm_set_npi("unknown", &span->default_caller_data.rdnis.plan); - ftdm_set_ton("unknown", &span->default_caller_data.rdnis.type); - } else { - ftdm_set_npi("isdn", &span->default_caller_data.dnis.plan); - ftdm_set_ton("national", &span->default_caller_data.dnis.type); - ftdm_set_npi("isdn", &span->default_caller_data.cid_num.plan); - ftdm_set_ton("national", &span->default_caller_data.cid_num.type); - ftdm_set_npi("isdn", &span->default_caller_data.rdnis.plan); - ftdm_set_ton("national", &span->default_caller_data.rdnis.type); - } - for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) { ftdm_log(FTDM_LOG_DEBUG, "Sangoma ISDN key=value, %s=%s\n", ftdm_parameters[paramindex].var, ftdm_parameters[paramindex].val); var = ftdm_parameters[paramindex].var; @@ -239,6 +285,9 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ if (parse_switchtype(val, span) != FTDM_SUCCESS) { return FTDM_FAIL; } + if (set_switchtype_defaults(span) != FTDM_SUCCESS) { + return FTDM_FAIL; + } } else if (!strcasecmp(var, "signalling") || !strcasecmp(var, "interface")) { if (parse_signalling(val, span) != FTDM_SUCCESS) { @@ -277,9 +326,11 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ftdm_set_ton(val, &span->default_caller_data.rdnis.type); } else if (!strcasecmp(var, "outbound-rdnis-npi")) { ftdm_set_npi(val, &span->default_caller_data.rdnis.plan); - } else if (!strcasecmp(var, "outbound-bearer_cap")) { + } else if (!strcasecmp(var, "outbound-bearer_cap") || + !strcasecmp(var, "outbound-bc-transfer-cap")) { ftdm_set_bearer_capability(val, (uint8_t*)&span->default_caller_data.bearer_capability); - } else if (!strcasecmp(var, "outbound-bearer_layer1")) { + } else if (!strcasecmp(var, "outbound-bearer_layer1") || + !strcasecmp(var, "outbound-bc-user-layer1")) { ftdm_set_bearer_layer1(val, (uint8_t*)&span->default_caller_data.bearer_layer1); } else if (!strcasecmp(var, "channel-restart-on-link-up")) { parse_yesno(var, val, &signal_data->restart_opt); 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 de10a9fac0..a52a624dd0 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 @@ -216,7 +216,7 @@ ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STPSAP; - cfg.hdr.elmId.elmntInst1 = signal_data->link_id; + cfg.hdr.elmId.elmntInst1 = signal_data->dchan_id; if (!signal_data->dchan) { ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name); @@ -241,7 +241,8 @@ ftdm_status_t sngisdn_stack_cfg_phy_psap(ftdm_span_t *span) ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type); return FTDM_FAIL; } - cfg.t.cfg.s.l1PSAP.spId = signal_data->link_id; + + cfg.t.cfg.s.l1PSAP.spId = signal_data->dchan_id; if (sng_isdn_phy_config(&pst, &cfg)) { return FTDM_FAIL; @@ -315,7 +316,7 @@ ftdm_status_t sngisdn_stack_cfg_q921_msap(ftdm_span_t *span) cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STMSAP; - cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id; + cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->dchan_id; cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */ cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */ @@ -408,7 +409,7 @@ ftdm_status_t sngisdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t management cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STDLSAP; - cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id; + cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->dchan_id; cfg.t.cfg.s.bdDLSAP.n201 = 1028; /* n201 */ if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || @@ -613,9 +614,9 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span) cfg.hdr.response.selector=0; + cfg.t.cfg.s.inDLSAP.sapId = signal_data->dchan_id; + cfg.t.cfg.s.inDLSAP.spId = signal_data->dchan_id; - 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); cfg.t.cfg.s.inDLSAP.n201 = 1024; @@ -876,8 +877,7 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span) cfg.hdr.response.selector=0; - cfg.t.cfg.s.inLCe.sapId = signal_data->link_id; - + cfg.t.cfg.s.inLCe.sapId = signal_data->dchan_id; cfg.t.cfg.s.inLCe.lnkUpDwnInd = TRUE; cfg.t.cfg.s.inLCe.tCon.enb = TRUE; 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 225244f57e..2023f4c54c 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 @@ -146,7 +146,8 @@ ftdm_status_t sngisdn_deactivate_phy(ftdm_span_t *span) cntrl.t.cntrl.action = AUBND_DIS; cntrl.t.cntrl.subAction = SAELMNT; - cntrl.t.cntrl.sapId = signal_data->link_id; + + cntrl.t.cntrl.sapId = signal_data->dchan_id; if (sng_isdn_phy_cntrl(&pst, &cntrl)) { return FTDM_FAIL; @@ -180,7 +181,8 @@ ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span) cntrl.t.cntrl.action = AENA; cntrl.t.cntrl.subAction = SAELMNT; - cntrl.t.cntrl.sapId = signal_data->link_id; + + cntrl.t.cntrl.sapId = signal_data->dchan_id; if (sng_isdn_phy_cntrl(&pst, &cntrl)) { return FTDM_FAIL; @@ -298,7 +300,8 @@ ftdm_status_t sngisdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t suba if (action == AENA && subaction == SATRC) { cntrl.t.cntrl.trcLen = -1; /* Trace the entire message buffer */ } - cntrl.t.cntrl.sapId = signal_data->link_id; + + cntrl.t.cntrl.sapId = signal_data->dchan_id; cntrl.t.cntrl.ces = 0; if(sng_isdn_q931_cntrl(&pst, &cntrl)) { @@ -339,11 +342,11 @@ ftdm_status_t sngisdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t suba cntrl.t.cntrl.subAction = subaction; #if (SMBD_LMINT3 || BD_LMINT3) - cntrl.t.cntrl.lnkNmb = signal_data->link_id; + cntrl.t.cntrl.lnkNmb = signal_data->dchan_id; cntrl.t.cntrl.sapi = NOTUSED; cntrl.t.cntrl.tei = NOTUSED; #else /* _LMINT3 */ - cntrl.hdr.elmId.elmntInst1 = signal_data->link_id; + cntrl.hdr.elmId.elmntInst1 = signal_data->dchan_id; cntrl.hdr.elmId.elmntInst2 = NOTUSED; cntrl.hdr.elmId.elmntInst3 = NOTUSED; #endif /* _LMINT3 */ 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 7e9e360c6d..7b7c748c7a 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 @@ -71,13 +71,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */ sngisdn_info->glare.spInstId = spInstId; sngisdn_info->glare.dChan = dChan; - sngisdn_info->glare.ces = ces; + sngisdn_info->glare.ces = ces; break; } sngisdn_info->suInstId = get_unique_suInstId(suId); sngisdn_info->spInstId = spInstId; - if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) { uint8_t local_number_matched = 0; @@ -125,30 +124,39 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) } /* Fill in call information */ +#ifdef NETBORDER_CALL_REF + get_callref(ftdmchan, &conEvnt->callRef); +#endif get_calling_num(ftdmchan, &conEvnt->cgPtyNmb); get_calling_num2(ftdmchan, &conEvnt->cgPtyNmb2); get_called_num(ftdmchan, &conEvnt->cdPtyNmb); get_redir_num(ftdmchan, &conEvnt->redirNmb); get_calling_subaddr(ftdmchan, &conEvnt->cgPtySad); get_prog_ind_ie(ftdmchan, &conEvnt->progInd); - get_facility_ie(ftdmchan, &conEvnt->facilityStr); + get_facility_ie(ftdmchan, &conEvnt->facilityStr); if (get_calling_name_from_display(ftdmchan, &conEvnt->display) != FTDM_SUCCESS) { get_calling_name_from_usr_usr(ftdmchan, &conEvnt->usrUsr); } - ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits); if (conEvnt->bearCap[0].eh.pres) { - ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val); + ftdmchan->caller_data.bearer_layer1 = sngisdn_get_usrInfoLyr1Prot_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val); ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val); } - if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) { if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) { - snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]); + uint8_t encoding = (conEvnt->ni2OctStr.str.val[2] >> 5); + if (encoding == 0 || encoding == 1) { + /* BCD even or BCD odd */ + uint8_t value = (conEvnt->ni2OctStr.str.val[3] & 0x0F)*10 + ((conEvnt->ni2OctStr.str.val[3] >> 4) & 0x0F); + snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", value); + } else if (encoding == 2) { + /* IA 5 */ + snprintf(ftdmchan->caller_data.aniII, 5, "%c", conEvnt->ni2OctStr.str.val[3]); + } } } @@ -282,6 +290,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS_MEDIA: case FTDM_CHANNEL_STATE_DIALING: +#ifdef NETBORDER_CALL_REF + get_callref(ftdmchan, &cnStEvnt->callRef); +#endif get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd); get_facility_ie(ftdmchan, &cnStEvnt->facilityStr); ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP); @@ -354,6 +365,9 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case MI_CALLPROC: case MI_PROGRESS: case MI_ALERTING: +#ifdef NETBORDER_CALL_REF + get_callref(ftdmchan, &cnStEvnt->callRef); +#endif get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd); get_facility_ie(ftdmchan, &cnStEvnt->facilityStr); @@ -372,7 +386,10 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_RINGING: if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n"); sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media not available\n"); } switch (evntType) { case MI_CALLPROC: @@ -387,10 +404,8 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) break; case MI_PROGRESS: if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS); } break; @@ -590,7 +605,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event) ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause); } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "RELEASE COMPLETE did not have a cause code\n"); - ftdmchan->caller_data.hangup_cause = 0; + ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL; } sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT); 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 bb04f887ab..4b27f21e1c 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 @@ -39,7 +39,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan) ConEvnt conEvnt; sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; - ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN}; + ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID}; ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n"); @@ -261,7 +261,7 @@ void sngisdn_snd_fac_req(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) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending FACILITY, but no call data, ignoring (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId); return; } @@ -491,8 +491,8 @@ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len) /* Should we trigger congestion here? */ l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL; } - - sng_isdn_data_ind(signal_data->link_id, &l1_frame); + + sng_isdn_data_ind(signal_data->dchan_id, &l1_frame); } void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event) @@ -506,11 +506,11 @@ void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event) switch(event) { case FTDM_OOB_ALARM_CLEAR: l1_event.type = SNG_L1EVENT_ALARM_OFF; - sng_isdn_event_ind(signal_data->link_id, &l1_event); + sng_isdn_event_ind(signal_data->dchan_id, &l1_event); break; case FTDM_OOB_ALARM_TRAP: l1_event.type = SNG_L1EVENT_ALARM_ON; - sng_isdn_event_ind(signal_data->link_id, &l1_event); + sng_isdn_event_ind(signal_data->dchan_id, &l1_event); break; default: /* We do not care about the other OOB events for now */ 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 3afdaa599e..791b65f0f6 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 @@ -662,7 +662,9 @@ void sngisdn_rcv_phy_ind(SuId suId, Reason reason) void sngisdn_rcv_q921_ind(BdMngmt *status) { ftdm_span_t *ftdmspan; - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.lnkNmb]; + + sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[status->t.usta.lnkNmb].spans[1]; + if (!signal_data) { ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); return; @@ -715,7 +717,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status) case LCM_EVENT_DOWN: { ftdm_span_t *ftdmspan; - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.suId]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[status->t.usta.suId].spans[1]; if (!signal_data) { ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId); return; @@ -784,15 +786,16 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf) uint8_t data; ftdm_trace_dir_t dir; uint8_t tdata[1000]; - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.suId]; + + sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[trc->t.trc.suId].spans[1]; ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer"); mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len; if (trc->t.trc.evnt == TL3PKTTX) { - dir = FTDM_TRACE_OUTGOING; + dir = FTDM_TRACE_DIR_OUTGOING; } else { - dir = FTDM_TRACE_INCOMING; + dir = FTDM_TRACE_DIR_INCOMING; } if (mlen) { @@ -830,16 +833,17 @@ void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf) uint8_t data; ftdm_trace_dir_t dir; uint8_t tdata[1000]; - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[trc->t.trc.lnkNmb]; + + sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[trc->t.trc.lnkNmb].spans[1]; if (trc->t.trc.evnt == TL2TMR) { return; } if (trc->t.trc.evnt == TL2FRMTX) { - dir = FTDM_TRACE_OUTGOING; + dir = FTDM_TRACE_DIR_OUTGOING; } else { - dir = FTDM_TRACE_INCOMING; + dir = FTDM_TRACE_DIR_INCOMING; } ftdm_assert(mBuf != NULLP, "Received a Q921 trace with no buffer"); @@ -879,7 +883,7 @@ int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame) { ftdm_status_t status; ftdm_wait_flag_t flags = FTDM_WRITE; - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; + sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[spId].spans[1]; ftdm_size_t length = l1_frame->len; ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); @@ -912,8 +916,8 @@ int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame) } int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd) -{ - sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; +{ + sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[spId].spans[1]; ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); switch(l1_cmd->type) { 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 28768a1f09..9c1b7baf79 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 @@ -161,6 +161,32 @@ ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t ava return FTDM_SUCCESS; } +#ifdef NETBORDER_CALL_REF +ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; + + if (signal_data->raw_trace_q931) { + if (callRef->eh.pres != PRSNT_NODEF || callRef->reference.pres != PRSNT_NODEF) { + /* Netborder only supports BRI, so we only care for BRI for now */ + if (FTDM_SPAN_IS_BRI(ftdmchan->span) && !sngisdn_info->call_ref) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to obtain call reference\n"); + } + return FTDM_FAIL; + } + if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { + sngisdn_info->call_ref = 0x7F & callRef->reference.val; + } else { + sngisdn_info->call_ref = 0x7FFF & callRef->reference.val; + } + + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call reference:%04x\n", sngisdn_info->call_ref); + } + return FTDM_SUCCESS; +} +#endif + ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) { ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; @@ -697,7 +723,6 @@ ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8 { int len; ftdm_caller_data_t *caller_data = &ftdmchan->caller_data; - if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) { len = caller_data->raw_data[1]; memcpy(data, &caller_data->raw_data[2], len); @@ -789,7 +814,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s break; default: ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind location:%d\n", loc); - progInd->location.val = IN_PD_NOTETEISDN; + progInd->location.val = IN_LOC_USER; } return FTDM_SUCCESS; } @@ -1033,7 +1058,7 @@ void get_memory_info(void) return; } -uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability) +uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability) { switch(bearer_capability) { case FTDM_BEARER_CAP_SPEECH: @@ -1049,7 +1074,7 @@ uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability) return FTDM_BEARER_CAP_SPEECH; } -uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot) +uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_prot) { switch(layer1_prot) { case FTDM_USER_LAYER1_PROT_V110: @@ -1065,25 +1090,22 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_pr return IN_UIL1_G711ULAW; } -ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability) +ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability) { switch(bearer_capability) { case IN_ITC_SPEECH: - return FTDM_BEARER_CAP_SPEECH; - + return FTDM_BEARER_CAP_SPEECH; case IN_ITC_UNRDIG: - return FTDM_BEARER_CAP_64K_UNRESTRICTED; - + return FTDM_BEARER_CAP_64K_UNRESTRICTED; case IN_ITC_A31KHZ: return FTDM_BEARER_CAP_3_1KHZ_AUDIO; - default: return FTDM_BEARER_CAP_SPEECH; } return FTDM_BEARER_CAP_SPEECH; } -ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot) +ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_stack(uint8_t layer1_prot) { switch(layer1_prot) { case IN_UIL1_CCITTV110: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c index 8c421b0691..9feb5c8c43 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c @@ -38,14 +38,26 @@ #define OCTET(x) (ieData[x-1] & 0xFF) #define MAX_DECODE_STR_LEN 2000 +typedef struct sngisdn_trace_info +{ + uint8_t call_ref_flag; + uint16_t call_ref; + uint8_t msgtype; + uint8_t bchan_no; + ftdm_trace_dir_t dir; +} sngisdn_frame_info_t; + void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end); uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset, uint8_t *data, uint16_t index_start); +static ftdm_status_t sngisdn_map_call(sngisdn_span_data_t *signal_data, sngisdn_frame_info_t frame_info, ftdm_channel_t **found); +static ftdm_status_t sngisdn_get_frame_info(uint8_t *data, uint32_t data_len, ftdm_trace_dir_t dir, sngisdn_frame_info_t *frame_info); uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi); char* get_code_2_str(int code, struct code2str *pCodeTable); void sngisdn_decode_q921(char* str, uint8_t* data, uint32_t data_len); void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len); + char* get_code_2_str(int code, struct code2str *pCodeTable) { struct code2str* pCode2txt; @@ -118,11 +130,8 @@ void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d sigev.channel = signal_data->dchan; sigev.event_id = FTDM_SIGEVENT_TRACE_RAW; - sigev.ev_data.logevent.dir = dir; - sigev.ev_data.logevent.level = 2; - - /* TODO: Map trace to call ID here */ - sigev.call_id = 0; + sigev.ev_data.trace.dir = dir; + sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q921; raw_data = ftdm_malloc(data_len); ftdm_assert(raw_data, "Failed to malloc"); @@ -219,27 +228,34 @@ void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t d { uint8_t *raw_data; ftdm_sigmsg_t sigev; + ftdm_channel_t *ftdmchan = NULL; + sngisdn_frame_info_t frame_info; memset(&sigev, 0, sizeof(sigev)); - sigev.span_id = signal_data->ftdm_span->span_id; - sigev.chan_id = signal_data->dchan->chan_id; - sigev.channel = signal_data->dchan; - sigev.event_id = FTDM_SIGEVENT_TRACE_RAW; + /* Note: Mapped raw trace assume only exclusive b-channel selection is used. i.e the b-channel selected on outgoing SETUP is always used for the call */ + + if (sngisdn_get_frame_info(data, data_len, dir, &frame_info) == FTDM_SUCCESS) { + if (sngisdn_map_call(signal_data, frame_info, &ftdmchan) == FTDM_SUCCESS) { + sigev.call_id = ftdmchan->caller_data.call_id; + sigev.span_id = ftdmchan->physical_span_id; + sigev.chan_id = ftdmchan->physical_chan_id; + sigev.channel = ftdmchan; + } + sigev.event_id = FTDM_SIGEVENT_TRACE_RAW; - sigev.ev_data.logevent.dir = dir; - sigev.ev_data.logevent.level = 3; - - /* TODO: Map trace to call ID here */ - - raw_data = ftdm_malloc(data_len); - ftdm_assert(raw_data, "Failed to malloc"); - - memcpy(raw_data, data, data_len); - sigev.raw.data = raw_data; - sigev.raw.len = data_len; - sigev.raw.autofree = 1; - ftdm_span_send_signal(signal_data->ftdm_span, &sigev); + sigev.ev_data.trace.dir = dir; + sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q931; + + raw_data = ftdm_malloc(data_len); + ftdm_assert(raw_data, "Failed to malloc"); + + memcpy(raw_data, data, data_len); + sigev.raw.data = raw_data; + sigev.raw.len = data_len; + sigev.raw.autofree = 1; + ftdm_span_send_signal(signal_data->ftdm_span, &sigev); + } } void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len) @@ -255,9 +271,6 @@ void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len) prot_disc = (uint8_t)data[0]; str_len += sprintf(&str[str_len], " Prot Disc:%s (0x%02x)\n", get_code_2_str(prot_disc, dcodQ931ProtDiscTable), prot_disc); - - - /* Decode Call Reference */ lenCallRef = (uint8_t) (data[1] & 0x0F); @@ -749,4 +762,203 @@ void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_ return; } +static ftdm_status_t sngisdn_get_frame_info(uint8_t *data, uint32_t data_len, ftdm_trace_dir_t dir, sngisdn_frame_info_t *target) +{ + uint8_t pos = 0; + uint8_t flag; + uint16_t ref = 0; + uint8_t ref_len = 0; + uint8_t bchan_no = 0; + uint8_t msgtype; + + /* First octet is protocol discriminator */ + pos++; + /* Second octet contains length of call reference */ + ref_len = data[pos++] & 0x0F; + + /* third octet is call reference */ + flag = (data[pos] & 0x80) >> 7; + if (ref_len == 2) { + ref = (data[pos++] & 0x7F) << 8; + ref |= (data[pos++] & 0xFF) ; + } else { + ref = (data[pos++] & 0x7F); + } + + /* Next octet is the message type */ + msgtype = data[pos++] & 0x7F; + + /* + ftdm_log(FTDM_LOG_DEBUG, "Raw frame:call_ref:0x%04x flag:%d msgtype:%d\n", ref, flag, msgtype); + */ + if (!ref) { + /* This is not a call specific message (RESTART for example and we do not care about it) */ + return FTDM_FAIL; + } + + /* Look for the b-channel */ + if (msgtype == PROT_Q931_MSGTYPE_SETUP) { + /* Try to find the b-channel no*/ + + for(; pos < data_len; pos++) { + uint8_t ie_id = data[pos]; + uint8_t ie_len = data[pos+1]; + + switch(ie_id) { + case PROT_Q931_IE_SENDING_COMPLETE: + /* Single octet ie's do not have a length */ + ie_len = 0; + break; + case PROT_Q931_IE_CHANNEL_ID: + { + /* Try to obtain the b-channel */ + uint8_t ie_pos = pos+2; + //ifaceIdPresent = get_bits(OCTET(3),7,7); + if (data[ie_pos] & 0x20) { + /* Interface type is Primary Rate */ + ie_pos+=2; + bchan_no = data[ie_pos] & 0x7F; + } else { + /* Interface type is Basic Interface */ + /* Get the channel number from info channel selection */ + bchan_no = data[ie_pos] & 0x03; + } + ftdm_log(FTDM_LOG_DEBUG, "Found b-channel:%d\n", bchan_no); + goto parse_ies_done; + } + break; + default: + pos = pos+ie_len+1; + } + //ftdm_log(FTDM_LOG_DEBUG, "Decoded IE:%s\n", get_code_2_str(ie_id, dcodQ931IEIDTable)); + } + if (!bchan_no) { + char tmp[1000]; + print_hex_dump(tmp, 0, data, 0, data_len); + ftdm_log(FTDM_LOG_WARNING, "Failed to determine b-channel on SETUP message\n%s\n", tmp); + } + } + +parse_ies_done: + + target->call_ref = ref; + target->call_ref_flag = flag; + target->msgtype = msgtype; + target->bchan_no = bchan_no; + target->dir = dir; + + return FTDM_SUCCESS; +} + +static ftdm_status_t sngisdn_map_call(sngisdn_span_data_t *signal_data, sngisdn_frame_info_t frame_info, ftdm_channel_t **found) +{ + sngisdn_chan_data_t *sngisdn_info; + ftdm_channel_t *ftdmchan = NULL; + ftdm_iterator_t *chaniter = NULL; + ftdm_iterator_t *curr = NULL; + ftdm_status_t status = FTDM_FAIL; + uint8_t outbound_call = 0; + + if ((!frame_info.call_ref_flag && frame_info.dir == FTDM_TRACE_DIR_OUTGOING) || + (frame_info.call_ref_flag && frame_info.dir == FTDM_TRACE_DIR_INCOMING)) { + + /* If this is an outgoing frame and this frame was sent by the originating side + of the call (frame_info.call_ref_flag == 0), then this is an outbound call */ + outbound_call = 1; + } else { + outbound_call = 0; + } + + switch (frame_info.msgtype) { + case PROT_Q931_MSGTYPE_SETUP: + /* We initiated this outgoing call try to match the call reference with our internal call-id*/ + if (!frame_info.bchan_no) { + /* We were not able to determine the bchannel on this call, so we will not be able to match it anyway */ + status = FTDM_FAIL; + } + + chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdmchan = (ftdm_channel_t*)(ftdm_iterator_current(curr)); + ftdm_channel_lock(ftdmchan); + + if (outbound_call) { + sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; + if (sngisdn_info && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + if (ftdmchan->caller_data.call_id && ftdmchan->physical_chan_id == frame_info.bchan_no) { + + sngisdn_info->call_ref = frame_info.call_ref; + *found = ftdmchan; + status = FTDM_SUCCESS; + } + } + } else { + if (ftdmchan->physical_chan_id == frame_info.bchan_no) { + *found = ftdmchan; + status = FTDM_SUCCESS; + } + } + ftdm_channel_unlock(ftdmchan); + } + ftdm_iterator_free(chaniter); + break; + case PROT_Q931_MSGTYPE_ALERTING: + case PROT_Q931_MSGTYPE_PROCEEDING: + case PROT_Q931_MSGTYPE_PROGRESS: + case PROT_Q931_MSGTYPE_CONNECT: + case PROT_Q931_MSGTYPE_SETUP_ACK: + case PROT_Q931_MSGTYPE_CONNECT_ACK: + case PROT_Q931_MSGTYPE_USER_INFO: + case PROT_Q931_MSGTYPE_DISCONNECT: + case PROT_Q931_MSGTYPE_RELEASE: + case PROT_Q931_MSGTYPE_RELEASE_ACK: + case PROT_Q931_MSGTYPE_RELEASE_COMPLETE: + case PROT_Q931_MSGTYPE_FACILITY: + case PROT_Q931_MSGTYPE_NOTIFY: + case PROT_Q931_MSGTYPE_STATUS_ENQUIRY: + case PROT_Q931_MSGTYPE_INFORMATION: + case PROT_Q931_MSGTYPE_STATUS: + /* Look for an outbound call on that span and and try to match the call-id */ + chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL); + for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { + ftdmchan = (ftdm_channel_t*)(ftdm_iterator_current(curr)); + ftdm_channel_lock(ftdmchan); + sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data; + if (outbound_call) { + if (sngisdn_info && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + if (sngisdn_info->call_ref == frame_info.call_ref) { + + *found = ftdmchan; + status = FTDM_SUCCESS; + } + } + } else { + if (sngisdn_info && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { + if (sngisdn_info->call_ref && sngisdn_info->call_ref == frame_info.call_ref) { + + *found = ftdmchan; + status = FTDM_SUCCESS; + } + } + } + ftdm_channel_unlock(ftdmchan); + } + ftdm_iterator_free(chaniter); + break; + default: + /* This frame is not call specific, ignore */ + break; + } + if (status == FTDM_SUCCESS) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Mapped %s with Call Ref:%04x to call-id:%d\n", get_code_2_str(frame_info.msgtype, dcodQ931MsgTypeTable), frame_info.call_ref, (*found)->caller_data.call_id); + } else { + /* We could not map this frame to a call-id */ + ftdm_log(FTDM_LOG_DEBUG, "Failed to map %s with Call Ref:%04x to local call\n", + get_code_2_str(frame_info.msgtype, dcodQ931MsgTypeTable), frame_info.call_ref); + } + + return status; +} + + diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h index f054de9377..db33cf8083 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.h @@ -191,37 +191,65 @@ struct code2str dcodQ931CallRefLoTable[] = { {13, "D"}, {14, "E"}, {15, "F"}, - {-1,"?"}, + {-1, "?"}, }; +#define PROT_Q931_MSGTYPE_ALERTING 1 +#define PROT_Q931_MSGTYPE_PROCEEDING 2 +#define PROT_Q931_MSGTYPE_PROGRESS 3 +#define PROT_Q931_MSGTYPE_SETUP 5 +#define PROT_Q931_MSGTYPE_CONNECT 7 +#define PROT_Q931_MSGTYPE_SETUP_ACK 13 +#define PROT_Q931_MSGTYPE_CONNECT_ACK 15 +#define PROT_Q931_MSGTYPE_USER_INFO 32 +#define PROT_Q931_MSGTYPE_SUSPEND_REJ 33 +#define PROT_Q931_MSGTYPE_RESUME_REJ 34 +#define PROT_Q931_MSGTYPE_SUSPEND 37 +#define PROT_Q931_MSGTYPE_RESUME 38 +#define PROT_Q931_MSGTYPE_SUSPEND_ACK 45 +#define PROT_Q931_MSGTYPE_RESUME_ACK 46 +#define PROT_Q931_MSGTYPE_DISCONNECT 69 +#define PROT_Q931_MSGTYPE_RESTART 70 +#define PROT_Q931_MSGTYPE_RELEASE 77 +#define PROT_Q931_MSGTYPE_RELEASE_ACK 78 +#define PROT_Q931_MSGTYPE_RELEASE_COMPLETE 90 +#define PROT_Q931_MSGTYPE_SEGMENT 96 +#define PROT_Q931_MSGTYPE_FACILITY 98 +#define PROT_Q931_MSGTYPE_NOTIFY 110 +#define PROT_Q931_MSGTYPE_STATUS_ENQUIRY 117 +#define PROT_Q931_MSGTYPE_CONGESTION_CNTRL 121 +#define PROT_Q931_MSGTYPE_INFORMATION 123 +#define PROT_Q931_MSGTYPE_STATUS 125 + + struct code2str dcodQ931MsgTypeTable[] = { - {1, "Alerting"}, - {2, "Call Proceeding"}, - {3, "Progress"}, - {5, "Setup"}, - {7, "Connect"}, - {13, "Setup Ack"}, - {15, "Connect Ack"}, - {32, "User Info"}, - {33, "Suspend Rej"}, - {34, "Resume Rej"}, - {37, "Suspend"}, - {38, "Resume"}, - {45, "Suspend Ack"}, - {46, "Resume Ack"}, - {69, "Disconnect"}, - {70, "Restart"}, - {77, "Release"}, - {78, "Release Ack"}, - {90, "Release Compl"}, - {96, "Segment"}, - {98, "Facility"}, - {110, "Notify"}, - {117, "Status Enquiry"}, - {121, "Congest Cntrl"}, - {123, "Information"}, - {125, "Status"}, - {-1, "Unknown"}, + {PROT_Q931_MSGTYPE_ALERTING, "ALERT"}, + {PROT_Q931_MSGTYPE_PROCEEDING, "PROCEED"}, + {PROT_Q931_MSGTYPE_PROGRESS, "PROGRESS"}, + {PROT_Q931_MSGTYPE_SETUP, "SETUP"}, + {PROT_Q931_MSGTYPE_CONNECT, "CONNECT"}, + {PROT_Q931_MSGTYPE_SETUP_ACK, "SETUP ACK"}, + {PROT_Q931_MSGTYPE_CONNECT_ACK, "CONNECT ACK"}, + {PROT_Q931_MSGTYPE_USER_INFO, "USER INFO"}, + {PROT_Q931_MSGTYPE_SUSPEND_REJ, "SUSPEND REJ"}, + {PROT_Q931_MSGTYPE_RESUME_REJ, "RESUME REJ"}, + {PROT_Q931_MSGTYPE_SUSPEND, "SUSPEND"}, + {PROT_Q931_MSGTYPE_RESUME, "RESUME"}, + {PROT_Q931_MSGTYPE_SUSPEND_ACK, "SUSPEND ACK"}, + {PROT_Q931_MSGTYPE_RESUME_ACK, "RESUME ACK"}, + {PROT_Q931_MSGTYPE_DISCONNECT, "DISCONNECT"}, + {PROT_Q931_MSGTYPE_RESTART, "RESTART"}, + {PROT_Q931_MSGTYPE_RELEASE, "RELEASE"}, + {PROT_Q931_MSGTYPE_RELEASE_ACK, "RELEASR ACK"}, + {PROT_Q931_MSGTYPE_RELEASE_COMPLETE, "RELEASE COMPLETE"}, + {PROT_Q931_MSGTYPE_SEGMENT, "SEGMENT"}, + {PROT_Q931_MSGTYPE_FACILITY, "FACILITY"}, + {PROT_Q931_MSGTYPE_NOTIFY, "NOTIFY"}, + {PROT_Q931_MSGTYPE_STATUS_ENQUIRY, "STATUS ENQ"}, + {PROT_Q931_MSGTYPE_CONGESTION_CNTRL, "CONGESTION CTRL"}, + {PROT_Q931_MSGTYPE_INFORMATION, "INFO"}, + {PROT_Q931_MSGTYPE_STATUS, "STATUS"}, + {-1, "UNKNOWN"}, }; struct code2str dcodQ931CauseCodeTable[] = { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_user.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_user.h new file mode 100644 index 0000000000..5d94e6c620 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_user.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2010, Sangoma Technologies + * David Yat Sin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __FTMOD_SANGOMA_ISDN_USER_H__ +#define __FTMOD_SANGOMA_ISDN_USER_H__ + + +#define SNGISDN_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL }; +#define SNGISDN_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) _TYPE _FUNC1 (const char *name); const char * _FUNC2 (_TYPE type); +#define SNGISDN_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \ + _TYPE _FUNC1 (const char *name) \ + { \ + int i; \ + _TYPE t = _MAX ; \ + \ + for (i = 0; i < _MAX ; i++) { \ + if (!strcasecmp(name, _STRINGS[i])) { \ + t = (_TYPE) i; \ + break; \ + } \ + } \ + return t; \ + } \ + const char * _FUNC2 (_TYPE type) \ + { \ + if (type > _MAX) { \ + type = _MAX; \ + } \ + return _STRINGS[(int)type]; \ + } \ + + +typedef enum { + /* Call is not end-to-end ISDN */ + SNGISDN_PROGIND_DESCR_NETE_ISDN, + /* Destination address is non-ISDN */ + SNGISDN_PROGIND_DESCR_DEST_NISDN, + /* Origination address is non-ISDN */ + SNGISDN_PROGIND_DESCR_ORIG_NISDN, + /* Call has returned to the ISDN */ + SNGISDN_PROGIND_DESCR_RET_ISDN, + /* Interworking as occured and has resulted in a telecommunication service change */ + SNGISDN_PROGIND_DESCR_SERV_CHANGE, + /* In-band information or an appropriate pattern is now available */ + SNGISDN_PROGIND_DESCR_IB_AVAIL, + /* Invalid */ + SNGISDN_PROGIND_DESCR_INVALID, +} ftdm_sngisdn_progind_descr_t; +#define SNGISDN_PROGIND_DESCR_STRINGS "not-end-to-end-isdn", "destination-is-non-isdn", "origination-is-non-isdn", "call-returned-to-isdn", "service-change", "inband-info-available", "invalid" +SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t); + + +typedef enum { + /* User */ + SNGISDN_PROGIND_LOC_USER, + /* Private network serving the local user */ + SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR, + /* Public network serving the local user */ + SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR, + /* Transit network */ + SNGISDN_PROGIND_LOC_TRANSIT_NET, + /* Public network serving remote user */ + SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR, + /* Private network serving remote user */ + SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR, + /* Network beyond the interworking point */ + SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW, + /* Invalid */ + SNGISDN_PROGIND_LOC_INVALID, +} ftdm_sngisdn_progind_loc_t; +#define SNGISDN_PROGIND_LOC_STRINGS "user", "private-net-local-user", "public-net-local-user", "transit-network", "public-net-remote-user", "private-net-remote-user", "beyond-interworking", "invalid" +SNGISDN_STR2ENUM_P(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t); + + +#endif /* __FTMOD_SANGOMA_ISDN_USER_H__*/ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ + +/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 2a203faf8d..e2b08255ac 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -230,6 +230,8 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start ftdm_channel_t *chan; ftdm_socket_t sockfd = FTDM_INVALID_SOCKET; const char *dtmf = "none"; + const char *hwec_str = "none"; + const char *hwec_idle = "none"; if (!strncasecmp(span->name, "smg_prid_nfas", 8) && span->trunk_type == FTDM_TRUNK_T1 && x == 24) { #ifdef LIBSANGOMA_VERSION sockfd = __tdmv_api_open_span_chan(spanno, x); @@ -271,6 +273,8 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start || type == FTDM_CHAN_TYPE_B) { int err; + hwec_str = "unavailable"; + hwec_idle = "enabled"; dtmf = "software"; err = sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api); @@ -289,6 +293,7 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start err = sangoma_tdm_get_hw_ec(chan->sockfd, &tdm_api); if (err > 0) { + hwec_str = "available"; ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC); } @@ -296,6 +301,7 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start 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); + hwec_idle = "disabled"; } #else if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) { @@ -365,8 +371,8 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start ftdm_copy_string(chan->chan_number, number, sizeof(chan->chan_number)); } configured++; - ftdm_log_chan(chan, FTDM_LOG_INFO, "configured wanpipe device s%dc%d as FreeTDM channel %d:%d fd:%d DTMF: %s\n", - spanno, x, chan->span_id, chan->chan_id, sockfd, dtmf); + ftdm_log_chan(chan, FTDM_LOG_INFO, "Configured wanpipe device FD: %d, DTMF: %s, HWEC: %s, HWEC_IDLE: %s\n", + sockfd, dtmf, hwec_str, hwec_idle); } else { ftdm_log(FTDM_LOG_ERROR, "ftdm_span_add_channel failed for wanpipe span %d channel %d\n", spanno, x); @@ -1180,7 +1186,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) unsigned int alarms = 0; int err; - memset(&tdm_api,0,sizeof(tdm_api)); + memset(&tdm_api, 0, sizeof(tdm_api)); #ifdef LIBSANGOMA_VERSION if ((err = sangoma_tdm_get_fe_alarms(ftdmchan->sockfd, &tdm_api, &alarms))) { @@ -1226,9 +1232,19 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) alarms &= ~WAN_TE_BIT_ALARM_RAI; } + if (!ftdmchan->alarm_flags) { + if (FTDM_IS_DIGITAL_CHANNEL(ftdmchan)) { + ftdm_channel_hw_link_status_t sangoma_status = 0; + /* there is a bug in wanpipe where alarms were not properly set when they should be + * on at application startup, until that is fixed we check the link status here too */ + ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status); + ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? 1 : 0; + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Link status is %d\n", sangoma_status); + } + } + if (alarms) { - /* FIXME: investigate what else does the driver report */ - ftdm_log(FTDM_LOG_DEBUG, "Unmapped wanpipe alarms: %d\n", alarms); + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Unmapped wanpipe alarms: %d\n", alarms); } return FTDM_SUCCESS; @@ -1243,30 +1259,38 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) */ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fchan, ftdm_oob_event_t *event_id, wanpipe_tdm_api_t *tdm_api) { + ftdm_status_t status = FTDM_SUCCESS; + switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type) { case WP_API_EVENT_LINK_STATUS: { switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) { case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: - *event_id = FTDM_OOB_ALARM_CLEAR; + /* *event_id = FTDM_OOB_ALARM_CLEAR; */ + ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link connected event\n"); break; default: - *event_id = FTDM_OOB_ALARM_TRAP; + /* *event_id = FTDM_OOB_ALARM_TRAP; */ + ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link disconnected event\n"); break; }; + /* The WP_API_EVENT_ALARM event should be used to clear alarms */ + *event_id = FTDM_OOB_NOOP; } break; case WP_API_EVENT_RXHOOK: { if (fchan->type == FTDM_CHAN_TYPE_FXS) { - *event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK; + *event_id = tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_hook_state + & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK; + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got wanpipe %s\n", ftdm_oob_event2str(*event_id)); if (*event_id == FTDM_OOB_OFFHOOK) { if (ftdm_test_flag(fchan, FTDM_CHANNEL_FLASH)) { ftdm_clear_flag(fchan, FTDM_CHANNEL_FLASH); ftdm_clear_flag(fchan, FTDM_CHANNEL_WINK); *event_id = FTDM_OOB_FLASH; - goto event; + goto done; } else { ftdm_set_flag(fchan, FTDM_CHANNEL_WINK); } @@ -1275,12 +1299,14 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc ftdm_clear_flag(fchan, FTDM_CHANNEL_WINK); ftdm_clear_flag(fchan, FTDM_CHANNEL_FLASH); *event_id = FTDM_OOB_WINK; - goto event; + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Wink flag is set, delivering %s\n", + ftdm_oob_event2str(*event_id)); + goto done; } else { ftdm_set_flag(fchan, FTDM_CHANNEL_FLASH); } } - break; + status = FTDM_BREAK; } else { ftdm_status_t status; wanpipe_tdm_api_t onhook_tdm_api; @@ -1338,8 +1364,13 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc break; case WP_API_EVENT_ALARM: { - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api->wp_tdm_cmd.event.wp_api_event_alarm); - *event_id = FTDM_OOB_ALARM_TRAP; + if (tdm_api->wp_tdm_cmd.event.wp_api_event_alarm) { + ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Got Wanpipe alarms %d\n", tdm_api->wp_tdm_cmd.event.wp_api_event_alarm); + *event_id = FTDM_OOB_ALARM_TRAP; + } else { + ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Wanpipe alarms cleared\n"); + *event_id = FTDM_OOB_ALARM_CLEAR; + } } break; case WP_API_EVENT_POLARITY_REVERSE: @@ -1355,8 +1386,8 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc } break; } -event: - return FTDM_SUCCESS; +done: + return status; } /** @@ -1385,12 +1416,16 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event) } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); - if ((wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api)) != FTDM_SUCCESS) { + status = wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api); + if (status == FTDM_BREAK) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Ignoring event for now\n"); + } else if (status != FTDM_SUCCESS) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process event from channel\n"); return FTDM_FAIL; + } else { + ftdmchan->last_event_time = 0; } - ftdmchan->last_event_time = 0; span->event_header.e_type = FTDM_EVENT_OOB; span->event_header.enum_id = event_id; span->event_header.channel = ftdmchan; @@ -1409,8 +1444,10 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) uint32_t i,err; ftdm_oob_event_t event_id; for(i = 1; i <= span->chan_count; i++) { + /* as a hack for wink/flash detection, wanpipe_poll_event overrides the timeout parameter + * to force the user to call this function each 5ms or so to detect the timeout of our wink/flash */ if (span->channels[i]->last_event_time && !ftdm_test_flag(span->channels[i], FTDM_CHANNEL_EVENT)) { - uint32_t diff = (uint32_t)(ftdm_current_time_in_ms() - span->channels[i]->last_event_time); + ftdm_time_t diff = ftdm_current_time_in_ms() - span->channels[i]->last_event_time; /* XX printf("%u %u %u\n", diff, (unsigned)ftdm_current_time_in_ms(), (unsigned)span->channels[i]->last_event_time); */ if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_WINK)) { if (diff > wp_globals.wink_ms) { @@ -1418,6 +1455,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) ftdm_clear_flag_locked(span->channels[i], FTDM_CHANNEL_FLASH); ftdm_set_flag_locked(span->channels[i], FTDM_CHANNEL_OFFHOOK); event_id = FTDM_OOB_OFFHOOK; + ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %llums, delivering %s now\n", diff, ftdm_oob_event2str(event_id)); goto event; } } @@ -1436,11 +1474,13 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) sangoma_tdm_txsig_onhook(ftdmchan->sockfd,&tdm_api); } + ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "Diff since last event = %llums, delivering %s now\n", diff, ftdm_oob_event2str(event_id)); goto event; } } } if (ftdm_test_flag(span->channels[i], FTDM_CHANNEL_EVENT)) { + ftdm_status_t status; wanpipe_tdm_api_t tdm_api; ftdm_channel_t *ftdmchan = span->channels[i]; memset(&tdm_api, 0, sizeof(tdm_api)); @@ -1448,18 +1488,22 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) err = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api); if (err != FTDM_SUCCESS) { - snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); + ftdm_log_chan(span->channels[i], FTDM_LOG_ERROR, "read wanpipe event got error: %s\n", strerror(errno)); return FTDM_FAIL; } ftdm_log_chan(span->channels[i], FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type); ftdm_channel_lock(ftdmchan); - if ((wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api)) != FTDM_SUCCESS) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process events from channel\n"); - ftdm_channel_unlock(ftdmchan); + status = wanpipe_channel_process_event(ftdmchan, &event_id, &tdm_api); + ftdm_channel_unlock(ftdmchan); + + if (status == FTDM_BREAK) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring event for now\n"); + continue; + } else if (status != FTDM_SUCCESS) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to process event from channel\n"); return FTDM_FAIL; } - ftdm_channel_unlock(ftdmchan); event: @@ -1471,7 +1515,7 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event) return FTDM_SUCCESS; } } - return FTDM_FAIL; + return FTDM_BREAK; } /** diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 5b507bd0b9..1b55b739fc 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -1064,6 +1064,12 @@ static __inline__ ftdm_status_t zt_channel_process_event(ftdm_channel_t *fchan, fchan->rx_cas_bits = bits; } break; + case ZT_EVENT_NONE: + { + ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "No event\n"); + *event_id = FTDM_OOB_NOOP; + } + break; default: { ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Unhandled event %d\n", zt_event_id); @@ -1125,26 +1131,26 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) ftdm_channel_t *fchan = span->channels[i]; if (ftdm_test_flag(fchan, FTDM_CHANNEL_EVENT)) { ftdm_clear_flag(fchan, FTDM_CHANNEL_EVENT); - } - if (ioctl(fchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { - snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); - return FTDM_FAIL; - } + if (ioctl(fchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { + snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); + return FTDM_FAIL; + } - ftdm_channel_lock(fchan); - if ((zt_channel_process_event(fchan, &event_id, zt_event_id)) != FTDM_SUCCESS) { - ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Failed to process event from channel\n"); + ftdm_channel_lock(fchan); + if ((zt_channel_process_event(fchan, &event_id, zt_event_id)) != FTDM_SUCCESS) { + ftdm_log_chan_msg(fchan, FTDM_LOG_ERROR, "Failed to process event from channel\n"); + ftdm_channel_unlock(fchan); + return FTDM_FAIL; + } ftdm_channel_unlock(fchan); - return FTDM_FAIL; - } - ftdm_channel_unlock(fchan); - fchan->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = fchan; - *event = &span->event_header; - return FTDM_SUCCESS; + fchan->last_event_time = 0; + span->event_header.e_type = FTDM_EVENT_OOB; + span->event_header.enum_id = event_id; + span->event_header.channel = fchan; + *event = &span->event_header; + return FTDM_SUCCESS; + } } return FTDM_FAIL; diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 38bc61188b..8d67df3edc 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -82,8 +82,12 @@ typedef enum { FTDM_CAUSE_UNALLOCATED = 1, FTDM_CAUSE_NO_ROUTE_TRANSIT_NET = 2, FTDM_CAUSE_NO_ROUTE_DESTINATION = 3, + FTDM_CAUSE_SEND_SPECIAL_INFO_TONE = 4, + FTDM_CAUSE_MISDIALED_TRUNK_PREFIX = 5, FTDM_CAUSE_CHANNEL_UNACCEPTABLE = 6, FTDM_CAUSE_CALL_AWARDED_DELIVERED = 7, + FTDM_CAUSE_PREEMPTION = 8, + FTDM_CAUSE_PREEMPTION_CIRCUIT_RESERVED = 9, FTDM_CAUSE_NORMAL_CLEARING = 16, FTDM_CAUSE_USER_BUSY = 17, FTDM_CAUSE_NO_USER_RESPONSE = 18, @@ -100,23 +104,38 @@ typedef enum { FTDM_CAUSE_NORMAL_UNSPECIFIED = 31, FTDM_CAUSE_NORMAL_CIRCUIT_CONGESTION = 34, FTDM_CAUSE_NETWORK_OUT_OF_ORDER = 38, + FTDM_CAUSE_PERMANENT_FRAME_MODE_CONNECTION_OOS = 39, + FTDM_CAUSE_PERMANENT_FRAME_MODE_OPERATIONAL = 40, FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE = 41, FTDM_CAUSE_SWITCH_CONGESTION = 42, FTDM_CAUSE_ACCESS_INFO_DISCARDED = 43, FTDM_CAUSE_REQUESTED_CHAN_UNAVAIL = 44, FTDM_CAUSE_PRE_EMPTED = 45, + FTDM_CAUSE_PRECEDENCE_CALL_BLOCKED = 46, + FTDM_CAUSE_RESOURCE_UNAVAILABLE_UNSPECIFIED = 47, + FTDM_CAUSE_QOS_NOT_AVAILABLE = 49, FTDM_CAUSE_FACILITY_NOT_SUBSCRIBED = 50, - FTDM_CAUSE_OUTGOING_CALL_BARRED = 52, - FTDM_CAUSE_INCOMING_CALL_BARRED = 54, + FTDM_CAUSE_OUTGOING_CALL_BARRED = 53, + FTDM_CAUSE_INCOMING_CALL_BARRED = 55, FTDM_CAUSE_BEARERCAPABILITY_NOTAUTH = 57, FTDM_CAUSE_BEARERCAPABILITY_NOTAVAIL = 58, + FTDM_CAUSE_INCONSISTENCY_IN_INFO = 62, FTDM_CAUSE_SERVICE_UNAVAILABLE = 63, FTDM_CAUSE_BEARERCAPABILITY_NOTIMPL = 65, FTDM_CAUSE_CHAN_NOT_IMPLEMENTED = 66, FTDM_CAUSE_FACILITY_NOT_IMPLEMENTED = 69, + FTDM_CAUSE_ONLY_DIGITAL_INFO_BC_AVAIL = 70, FTDM_CAUSE_SERVICE_NOT_IMPLEMENTED = 79, FTDM_CAUSE_INVALID_CALL_REFERENCE = 81, + FTDM_CAUSE_IDENTIFIED_CHAN_NOT_EXIST = 82, + FTDM_CAUSE_SUSPENDED_CALL_EXISTS_BUT_CALL_ID_DOES_NOT = 83, + FTDM_CAUSE_CALL_ID_IN_USE = 84, + FTDM_CAUSE_NO_CALL_SUSPENDED = 85, + FTDM_CAUSE_CALL_WITH_CALL_ID_CLEARED = 86, + FTDM_CAUSE_USER_NOT_CUG = 87, FTDM_CAUSE_INCOMPATIBLE_DESTINATION = 88, + FTDM_CAUSE_NON_EXISTENT_CUG = 90, + FTDM_CAUSE_INVALID_TRANSIT_NETWORK_SELECTION = 91, FTDM_CAUSE_INVALID_MSG_UNSPECIFIED = 95, FTDM_CAUSE_MANDATORY_IE_MISSING = 96, FTDM_CAUSE_MESSAGE_TYPE_NONEXIST = 97, @@ -126,6 +145,7 @@ typedef enum { FTDM_CAUSE_WRONG_CALL_STATE = 101, FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE = 102, FTDM_CAUSE_MANDATORY_IE_LENGTH_ERROR = 103, + FTDM_CAUSE_MSG_WITH_UNRECOGNIZED_PARAM_DISCARDED = 110, FTDM_CAUSE_PROTOCOL_ERROR = 111, FTDM_CAUSE_INTERWORKING = 127, FTDM_CAUSE_SUCCESS = 142, @@ -168,10 +188,17 @@ typedef enum { FTDM_STR2ENUM_P(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t) /*! \brief Test if a channel is a voice channel */ -#define FTDM_IS_VOICE_CHANNEL(ftdm_chan) ((ftdm_chan)->type != FTDM_CHAN_TYPE_DQ921 && (ftdm_chan)->type != FTDM_CHAN_TYPE_DQ931) +#define FTDM_IS_VOICE_CHANNEL(fchan) ((fchan)->type != FTDM_CHAN_TYPE_DQ921 && (fchan)->type != FTDM_CHAN_TYPE_DQ931) /*! \brief Test if a channel is a D-channel */ -#define FTDM_IS_DCHAN(ftdm_chan) ((ftdm_chan)->type == FTDM_CHAN_TYPE_DQ921 || (ftdm_chan)->type == FTDM_CHAN_TYPE_DQ931) +#define FTDM_IS_DCHAN(fchan) ((fchan)->type == FTDM_CHAN_TYPE_DQ921 || (fchan)->type == FTDM_CHAN_TYPE_DQ931) + +/*! \brief Test if a channel is digital channel */ +#define FTDM_IS_DIGITAL_CHANNEL(fchan) ((fchan)->span->trunk_type == FTDM_TRUNK_E1 || \ + (fchan)->span->trunk_type == FTDM_TRUNK_T1 || \ + (fchan)->span->trunk_type == FTDM_TRUNK_J1 || \ + (fchan)->span->trunk_type == FTDM_TRUNK_BRI || \ + (fchan)->span->trunk_type == FTDM_TRUNK_BRI_PTMP) /*! \brief Logging function prototype to be used for all FreeTDM logs * you should use ftdm_global_set_logger to set your own logger @@ -321,8 +348,57 @@ typedef struct ftdm_caller_data { * should use the call_id from sigmsg otherwise */ uint32_t call_id; /*!< Unique call ID for this call */ ftdm_channel_t *fchan; /*!< FreeTDM channel associated (can be NULL) */ + void *priv; /*!< Private data for the FreeTDM user */ } ftdm_caller_data_t; +/*! \brief Hunting mode */ +typedef enum { + FTDM_HUNT_SPAN, /*!< Hunt channels in a given span */ + FTDM_HUNT_GROUP, /*!< Hunt channels in a given group */ + FTDM_HUNT_CHAN, /*!< Hunt for a specific channel */ +} ftdm_hunt_mode_t; + +/*! \brief Structure used for FTDM_HUNT_SPAN mode */ +typedef struct { + uint32_t span_id; + ftdm_direction_t direction; +} ftdm_span_hunt_t; + +/*! \brief Structure used for FTDM_HUNT_GROUP mode */ +typedef struct { + uint32_t group_id; + ftdm_direction_t direction; +} ftdm_group_hunt_t; + +/*! \brief Structure used for FTDM_HUNT_CHAN mode */ +typedef struct { + uint32_t span_id; + uint32_t chan_id; +} ftdm_chan_hunt_t; + +/*! \brief Function called before placing the call in the hunted channel + * The user can have a last saying in whether to proceed or abort + * the call attempt. Be aware that this callback will be called with + * the channel lock and you must not do any blocking operations during + * its execution. + * \param fchan The channel that will be used to place the call + * \param caller_data The caller data provided to ftdm_call_place + * \return FTDM_SUCCESS to proceed or FTDM_BREAK to abort the hunting + */ +typedef ftdm_status_t (*ftdm_hunt_result_cb_t)(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data); + +/*! \brief Channel Hunting provided to ftdm_call_place() */ +typedef struct { + ftdm_hunt_mode_t mode; + union { + ftdm_span_hunt_t span; + ftdm_group_hunt_t group; + ftdm_chan_hunt_t chan; + } mode_data; + ftdm_hunt_result_cb_t result_cb; +} ftdm_hunting_scheme_t; + + /*! \brief Tone type */ typedef enum { FTDM_TONE_DTMF = (1 << 0) @@ -335,7 +411,7 @@ typedef enum { FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */ FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */ FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */ - FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */ + FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got an initial positive response from the other end */ FTDM_SIGEVENT_RINGING, /*!< Remote side is in ringing state */ FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */ FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */ @@ -345,17 +421,17 @@ typedef enum { FTDM_SIGEVENT_ADD_CALL, /*!< New call should be added to the channel */ FTDM_SIGEVENT_RESTART, /*!< Restart has been requested. Typically you hangup your call resources here */ FTDM_SIGEVENT_SIGSTATUS_CHANGED, /*!< Signaling protocol status changed (ie: D-chan up), see new status in raw_data ftdm_sigmsg_t member */ - FTDM_SIGEVENT_COLLISION, /*!< Outgoing call was dropped because an incoming call arrived at the same time */ FTDM_SIGEVENT_FACILITY, /*!< In call facility event */ FTDM_SIGEVENT_TRACE, /*!span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) + +#define ftdm_log_chan_ex_msg(fchan, file, func, line, level, msg) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id) + #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_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) @@ -673,6 +680,14 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); #define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex) #define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex) +#define ftdm_test_and_set_media(fchan) \ + do { \ + if (!ftdm_test_flag((fchan), FTDM_CHANNEL_MEDIA)) { \ + ftdm_set_flag((fchan), FTDM_CHANNEL_MEDIA); \ + ftdm_set_echocancel_call_begin((fchan)); \ + } \ + } while (0); + 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_state.h b/libs/freetdm/src/include/private/ftdm_state.h index 7de015b72b..5672839d15 100644 --- a/libs/freetdm/src/include/private/ftdm_state.h +++ b/libs/freetdm/src/include/private/ftdm_state.h @@ -177,6 +177,12 @@ struct ftdm_state_map { }; typedef struct ftdm_state_map ftdm_state_map_t; +/*!\brief Cancel the state processing for a channel (the channel must be locked when calling this function) + * \note Only the core should use this function + */ +FT_DECLARE(ftdm_status_t) ftdm_channel_cancel_state(const char *file, const char *func, int line, + ftdm_channel_t *ftdmchan); + /*!\brief Set the state for a channel (the channel must be locked when calling this function) * \note Signaling modules should use ftdm_set_state macro instead * \note If this function is called with the wait parameter set to a non-zero value, the recursivity diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h index d79835733b..9e8df1f5f2 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -186,6 +186,9 @@ typedef enum { /* If this flag is set, the signalling module supports jumping directly to state up, without going through PROGRESS/PROGRESS_MEDIA */ FTDM_SPAN_USE_SKIP_STATES = (1 << 12), + /* If this flag is set, then this span cannot be stopped individually, it can only be stopped + on freetdm unload */ + FTDM_SPAN_NON_STOPPABLE = (1 << 13), } ftdm_span_flag_t; /*! \brief Channel supported features */ @@ -224,16 +227,11 @@ typedef enum { #define FTDM_CHANNEL_OUTBOUND (1ULL << 18) #define FTDM_CHANNEL_SUSPENDED (1ULL << 19) #define FTDM_CHANNEL_3WAY (1ULL << 20) - -/* this 3 flags are really nonsense used by boost module only, as soon - * as we deprecate/delete boost module we can get rid of them - * ================== - * */ #define FTDM_CHANNEL_PROGRESS (1ULL << 21) +/*!< There is media on the channel already */ #define FTDM_CHANNEL_MEDIA (1ULL << 22) +/*!< The channel was answered */ #define FTDM_CHANNEL_ANSWERED (1ULL << 23) -/* ================== */ - #define FTDM_CHANNEL_MUTE (1ULL << 24) #define FTDM_CHANNEL_USE_RX_GAIN (1ULL << 25) #define FTDM_CHANNEL_USE_TX_GAIN (1ULL << 26) diff --git a/libs/freetdm/src/include/private/libteletone.h b/libs/freetdm/src/include/private/libteletone.h index 7453be51d8..dc98c8cb6c 100644 --- a/libs/freetdm/src/include/private/libteletone.h +++ b/libs/freetdm/src/include/private/libteletone.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is libteletone * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * libteletone.h -- Tone Generator/Detector diff --git a/libs/freetdm/src/include/private/libteletone_detect.h b/libs/freetdm/src/include/private/libteletone_detect.h index b2d43d15f5..71bf067514 100644 --- a/libs/freetdm/src/include/private/libteletone_detect.h +++ b/libs/freetdm/src/include/private/libteletone_detect.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * libteletone_detect.c Tone Detection Code * diff --git a/libs/freetdm/src/include/private/libteletone_generate.h b/libs/freetdm/src/include/private/libteletone_generate.h index 2d47abdc7d..6d71694761 100644 --- a/libs/freetdm/src/include/private/libteletone_generate.h +++ b/libs/freetdm/src/include/private/libteletone_generate.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Copyright (c) 2007, Anthony Minessale II * All rights reserved. diff --git a/libs/freetdm/src/include/private/sangoma_tdm_api.h b/libs/freetdm/src/include/private/sangoma_tdm_api.h index 062d4e219d..6438c99fbb 100644 --- a/libs/freetdm/src/include/private/sangoma_tdm_api.h +++ b/libs/freetdm/src/include/private/sangoma_tdm_api.h @@ -1,7 +1,7 @@ /***************************************************************************** * sangoma_tdm_api.h Sangoma TDM API Portability functions * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * Michael Jerris * David Rokhvarg diff --git a/libs/freetdm/src/libteletone_detect.c b/libs/freetdm/src/libteletone_detect.c index 61fef90149..0436c25953 100644 --- a/libs/freetdm/src/libteletone_detect.c +++ b/libs/freetdm/src/libteletone_detect.c @@ -1,12 +1,12 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Much less efficient expansion interface was added to allow for the detection of * a single arbitrary tone combination which may also exceed 2 simultaneous tones. * (controlled by compile time constant TELETONE_MAX_TONES) * - * Copyright (C) 2006 Anthony Minessale II + * Copyright (C) 2006 Anthony Minessale II * * libteletone_detect.c Tone Detection Code * diff --git a/libs/freetdm/src/priserver.c b/libs/freetdm/src/priserver.c index b67fa04483..4e5ec8706d 100644 --- a/libs/freetdm/src/priserver.c +++ b/libs/freetdm/src/priserver.c @@ -1,7 +1,7 @@ /***************************************************************************** * priserver.c Refactoring of pritest.c * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * * Copyright: (c) 2005 Anthony Minessale II diff --git a/libs/freetdm/src/sangoma_pri.c b/libs/freetdm/src/sangoma_pri.c index 402611e518..4adcf017cf 100644 --- a/libs/freetdm/src/sangoma_pri.c +++ b/libs/freetdm/src/sangoma_pri.c @@ -1,7 +1,7 @@ /***************************************************************************** * sangoma_pri.c libpri Sangoma integration * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * * Copyright: (c) 2005 Anthony Minessale II diff --git a/libs/freetdm/src/sangoma_pri.h b/libs/freetdm/src/sangoma_pri.h index 2a1b2a2cef..d37622a6da 100644 --- a/libs/freetdm/src/sangoma_pri.h +++ b/libs/freetdm/src/sangoma_pri.h @@ -1,7 +1,7 @@ /***************************************************************************** * libsangoma.c AFT T1/E1: HDLC API Code Library * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * * Copyright: (c) 2005 Anthony Minessale II diff --git a/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s b/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s index 743eff56fe..650aa2ad80 100644 --- a/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s +++ b/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s @@ -1,42 +1,42 @@ -/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -/ -/ 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 the Netscape Portable Runtime (NSPR). -/ -/ The Initial Developer of the Original Code is Netscape -/ Communications Corporation. Portions created by Netscape are -/ Copyright (C) 2000 Netscape Communications Corporation. All -/ Rights Reserved. -/ -/ Contributor(s): -/ -/ Alternatively, the contents of this file may be used under the -/ terms of the GNU General Public License Version 2 or later (the -/ "GPL"), in which case the provisions of the GPL are applicable -/ instead of those above. If you wish to allow use of your -/ version of this file only under the terms of the GPL and not to -/ allow others to use your version of this file under the MPL, -/ indicate your decision by deleting the provisions above and -/ replace them with the notice and other provisions required by -/ the GPL. If you do not delete the provisions above, a recipient -/ may use your version of this file under either the MPL or the -/ GPL. -/ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// 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 the Netscape Portable Runtime (NSPR). +// +// The Initial Developer of the Original Code is Netscape +// Communications Corporation. Portions created by Netscape are +// Copyright (C) 2000 Netscape Communications Corporation. All +// Rights Reserved. +// +// Contributor(s): +// +// Alternatively, the contents of this file may be used under the +// terms of the GNU General Public License Version 2 or later (the +// "GPL"), in which case the provisions of the GPL are applicable +// instead of those above. If you wish to allow use of your +// version of this file only under the terms of the GPL and not to +// allow others to use your version of this file under the MPL, +// indicate your decision by deleting the provisions above and +// replace them with the notice and other provisions required by +// the GPL. If you do not delete the provisions above, a recipient +// may use your version of this file under either the MPL or the +// GPL. +// -/ PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val) -/ -/ Atomically increment the integer pointed to by 'val' and return -/ the result of the increment. -/ +// PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// .text .globl _PR_x86_AtomicIncrement .align 4 @@ -48,11 +48,11 @@ _PR_x86_AtomicIncrement: incl %eax ret -/ PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val) -/ -/ Atomically decrement the integer pointed to by 'val' and return -/ the result of the decrement. -/ +// PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// .text .globl _PR_x86_AtomicDecrement .align 4 @@ -64,25 +64,25 @@ _PR_x86_AtomicDecrement: decl %eax ret -/ PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval) -/ -/ Atomically set the integer pointed to by 'val' to the new -/ value 'newval' and return the old value. -/ -/ An alternative implementation: -/ .text -/ .globl _PR_x86_AtomicSet -/ .align 4 -/_PR_x86_AtomicSet: -/ movl 4(%esp), %ecx -/ movl 8(%esp), %edx -/ movl (%ecx), %eax -/retry: -/ lock -/ cmpxchgl %edx, (%ecx) -/ jne retry -/ ret -/ +// PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// +// An alternative implementation: +// .text +// .globl _PR_x86_AtomicSet +// .align 4 +//_PR_x86_AtomicSet: +// movl 4(%esp), %ecx +// movl 8(%esp), %edx +// movl (%ecx), %eax +//retry: +// lock +// cmpxchgl %edx, (%ecx) +// jne retry +// ret +// .text .globl _PR_x86_AtomicSet .align 4 @@ -92,11 +92,11 @@ _PR_x86_AtomicSet: xchgl %eax, (%ecx) ret -/ PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val) -/ -/ Atomically add 'val' to the integer pointed to by 'ptr' -/ and return the result of the addition. -/ +// PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// .text .globl _PR_x86_AtomicAdd .align 4 @@ -109,5 +109,5 @@ _PR_x86_AtomicAdd: addl %edx, %eax ret -/ Magic indicating no need for an executable stack +// Magic indicating no need for an executable stack .section .note.GNU-stack, "", @progbits ; .previous diff --git a/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s b/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s index c62437b23a..230dd82887 100644 --- a/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s +++ b/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s @@ -1,42 +1,42 @@ -/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -/ -/ 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 the Netscape Portable Runtime (NSPR). -/ -/ The Initial Developer of the Original Code is Netscape -/ Communications Corporation. Portions created by Netscape are -/ Copyright (C) 2004 Netscape Communications Corporation. All -/ Rights Reserved. -/ -/ Contributor(s): -/ -/ Alternatively, the contents of this file may be used under the -/ terms of the GNU General Public License Version 2 or later (the -/ "GPL"), in which case the provisions of the GPL are applicable -/ instead of those above. If you wish to allow use of your -/ version of this file only under the terms of the GPL and not to -/ allow others to use your version of this file under the MPL, -/ indicate your decision by deleting the provisions above and -/ replace them with the notice and other provisions required by -/ the GPL. If you do not delete the provisions above, a recipient -/ may use your version of this file under either the MPL or the -/ GPL. -/ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// 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 the Netscape Portable Runtime (NSPR). +// +// The Initial Developer of the Original Code is Netscape +// Communications Corporation. Portions created by Netscape are +// Copyright (C) 2004 Netscape Communications Corporation. All +// Rights Reserved. +// +// Contributor(s): +// +// Alternatively, the contents of this file may be used under the +// terms of the GNU General Public License Version 2 or later (the +// "GPL"), in which case the provisions of the GPL are applicable +// instead of those above. If you wish to allow use of your +// version of this file only under the terms of the GPL and not to +// allow others to use your version of this file under the MPL, +// indicate your decision by deleting the provisions above and +// replace them with the notice and other provisions required by +// the GPL. If you do not delete the provisions above, a recipient +// may use your version of this file under either the MPL or the +// GPL. +// -/ PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val) -/ -/ Atomically increment the integer pointed to by 'val' and return -/ the result of the increment. -/ +// PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// .text .globl _PR_x86_64_AtomicIncrement .align 4 @@ -47,11 +47,11 @@ _PR_x86_64_AtomicIncrement: incl %eax ret -/ PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val) -/ -/ Atomically decrement the integer pointed to by 'val' and return -/ the result of the decrement. -/ +// PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// .text .globl _PR_x86_64_AtomicDecrement .align 4 @@ -62,11 +62,11 @@ _PR_x86_64_AtomicDecrement: decl %eax ret -/ PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval) -/ -/ Atomically set the integer pointed to by 'val' to the new -/ value 'newval' and return the old value. -/ +// PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// .text .globl _PR_x86_64_AtomicSet .align 4 @@ -75,11 +75,11 @@ _PR_x86_64_AtomicSet: xchgl %eax, (%rdi) ret -/ PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val) -/ -/ Atomically add 'val' to the integer pointed to by 'ptr' -/ and return the result of the addition. -/ +// PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// .text .globl _PR_x86_64_AtomicAdd .align 4 @@ -90,5 +90,5 @@ _PR_x86_64_AtomicAdd: addl %esi, %eax ret -/ Magic indicating no need for an executable stack -/.section .note.GNU-stack, "", @progbits ; .previous +// Magic indicating no need for an executable stack +//.section .note.GNU-stack, "", @progbits ; .previous diff --git a/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s b/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s index a46c20fe1e..6e94a732da 100644 --- a/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s +++ b/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s @@ -1,36 +1,36 @@ -/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -/ -/ 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 the Netscape Portable Runtime (NSPR). -/ -/ The Initial Developer of the Original Code is Netscape -/ Communications Corporation. Portions created by Netscape are -/ Copyright (C) 1998-2000 Netscape Communications Corporation. All -/ Rights Reserved. -/ -/ Contributor(s): -/ -/ Alternatively, the contents of this file may be used under the -/ terms of the GNU General Public License Version 2 or later (the -/ "GPL"), in which case the provisions of the GPL are applicable -/ instead of those above. If you wish to allow use of your -/ version of this file only under the terms of the GPL and not to -/ allow others to use your version of this file under the MPL, -/ indicate your decision by deleting the provisions above and -/ replace them with the notice and other provisions required by -/ the GPL. If you do not delete the provisions above, a recipient -/ may use your version of this file under either the MPL or the -/ GPL. -/ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// 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 the Netscape Portable Runtime (NSPR). +// +// The Initial Developer of the Original Code is Netscape +// Communications Corporation. Portions created by Netscape are +// Copyright (C) 1998-2000 Netscape Communications Corporation. All +// Rights Reserved. +// +// Contributor(s): +// +// Alternatively, the contents of this file may be used under the +// terms of the GNU General Public License Version 2 or later (the +// "GPL"), in which case the provisions of the GPL are applicable +// instead of those above. If you wish to allow use of your +// version of this file only under the terms of the GPL and not to +// allow others to use your version of this file under the MPL, +// indicate your decision by deleting the provisions above and +// replace them with the notice and other provisions required by +// the GPL. If you do not delete the provisions above, a recipient +// may use your version of this file under either the MPL or the +// GPL. +// .text @@ -56,31 +56,31 @@ _MD_FlushRegisterWindows: ret -/ -/ sol_getsp() -/ -/ Return the current sp (for debugging) -/ +// +// sol_getsp() +// +// Return the current sp (for debugging) +// .globl sol_getsp sol_getsp: movl %esp, %eax ret -/ -/ sol_curthread() -/ -/ Return a unique identifier for the currently active thread. -/ +// +// sol_curthread() +// +// Return a unique identifier for the currently active thread. +// .globl sol_curthread sol_curthread: movl %ecx, %eax ret -/ PRInt32 _MD_AtomicIncrement(PRInt32 *val) -/ -/ Atomically increment the integer pointed to by 'val' and return -/ the result of the increment. -/ +// PRInt32 _MD_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// .text .globl _MD_AtomicIncrement .align 4 @@ -92,11 +92,11 @@ _MD_AtomicIncrement: incl %eax ret -/ PRInt32 _MD_AtomicDecrement(PRInt32 *val) -/ -/ Atomically decrement the integer pointed to by 'val' and return -/ the result of the decrement. -/ +// PRInt32 _MD_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// .text .globl _MD_AtomicDecrement .align 4 @@ -108,25 +108,25 @@ _MD_AtomicDecrement: decl %eax ret -/ PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) -/ -/ Atomically set the integer pointed to by 'val' to the new -/ value 'newval' and return the old value. -/ -/ An alternative implementation: -/ .text -/ .globl _MD_AtomicSet -/ .align 4 -/_MD_AtomicSet: -/ movl 4(%esp), %ecx -/ movl 8(%esp), %edx -/ movl (%ecx), %eax -/retry: -/ lock -/ cmpxchgl %edx, (%ecx) -/ jne retry -/ ret -/ +// PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// +// An alternative implementation: +// .text +// .globl _MD_AtomicSet +// .align 4 +//_MD_AtomicSet: +// movl 4(%esp), %ecx +// movl 8(%esp), %edx +// movl (%ecx), %eax +//retry: +// lock +// cmpxchgl %edx, (%ecx) +// jne retry +// ret +// .text .globl _MD_AtomicSet .align 4 @@ -136,11 +136,11 @@ _MD_AtomicSet: xchgl %eax, (%ecx) ret -/ PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) -/ -/ Atomically add 'val' to the integer pointed to by 'ptr' -/ and return the result of the addition. -/ +// PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// .text .globl _MD_AtomicAdd .align 4 diff --git a/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s b/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s index d4446a5f6b..6d30bc505e 100644 --- a/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s +++ b/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s @@ -1,42 +1,42 @@ -/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -/ -/ 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 the Netscape Portable Runtime (NSPR). -/ -/ The Initial Developer of the Original Code is Netscape -/ Communications Corporation. Portions created by Netscape are -/ Copyright (C) 2004 Netscape Communications Corporation. All -/ Rights Reserved. -/ -/ Contributor(s): -/ -/ Alternatively, the contents of this file may be used under the -/ terms of the GNU General Public License Version 2 or later (the -/ "GPL"), in which case the provisions of the GPL are applicable -/ instead of those above. If you wish to allow use of your -/ version of this file only under the terms of the GPL and not to -/ allow others to use your version of this file under the MPL, -/ indicate your decision by deleting the provisions above and -/ replace them with the notice and other provisions required by -/ the GPL. If you do not delete the provisions above, a recipient -/ may use your version of this file under either the MPL or the -/ GPL. -/ +// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// +// 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 the Netscape Portable Runtime (NSPR). +// +// The Initial Developer of the Original Code is Netscape +// Communications Corporation. Portions created by Netscape are +// Copyright (C) 2004 Netscape Communications Corporation. All +// Rights Reserved. +// +// Contributor(s): +// +// Alternatively, the contents of this file may be used under the +// terms of the GNU General Public License Version 2 or later (the +// "GPL"), in which case the provisions of the GPL are applicable +// instead of those above. If you wish to allow use of your +// version of this file only under the terms of the GPL and not to +// allow others to use your version of this file under the MPL, +// indicate your decision by deleting the provisions above and +// replace them with the notice and other provisions required by +// the GPL. If you do not delete the provisions above, a recipient +// may use your version of this file under either the MPL or the +// GPL. +// -/ PRInt32 _MD_AtomicIncrement(PRInt32 *val) -/ -/ Atomically increment the integer pointed to by 'val' and return -/ the result of the increment. -/ +// PRInt32 _MD_AtomicIncrement(PRInt32 *val) +// +// Atomically increment the integer pointed to by 'val' and return +// the result of the increment. +// .text .globl _MD_AtomicIncrement .align 4 @@ -47,11 +47,11 @@ _MD_AtomicIncrement: incl %eax ret -/ PRInt32 _MD_AtomicDecrement(PRInt32 *val) -/ -/ Atomically decrement the integer pointed to by 'val' and return -/ the result of the decrement. -/ +// PRInt32 _MD_AtomicDecrement(PRInt32 *val) +// +// Atomically decrement the integer pointed to by 'val' and return +// the result of the decrement. +// .text .globl _MD_AtomicDecrement .align 4 @@ -62,11 +62,11 @@ _MD_AtomicDecrement: decl %eax ret -/ PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) -/ -/ Atomically set the integer pointed to by 'val' to the new -/ value 'newval' and return the old value. -/ +// PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval) +// +// Atomically set the integer pointed to by 'val' to the new +// value 'newval' and return the old value. +// .text .globl _MD_AtomicSet .align 4 @@ -75,11 +75,11 @@ _MD_AtomicSet: xchgl %eax, (%rdi) ret -/ PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) -/ -/ Atomically add 'val' to the integer pointed to by 'ptr' -/ and return the result of the addition. -/ +// PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val) +// +// Atomically add 'val' to the integer pointed to by 'ptr' +// and return the result of the addition. +// .text .globl _MD_AtomicAdd .align 4 diff --git a/libs/libdingaling/src/ldl_compat.h b/libs/libdingaling/src/ldl_compat.h index b19137e083..26ae586632 100644 --- a/libs/libdingaling/src/ldl_compat.h +++ b/libs/libdingaling/src/ldl_compat.h @@ -1,6 +1,6 @@ /* * libDingaLing XMPP Jingle Library - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 11a9a8a5b8..44c4589429 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -1,6 +1,6 @@ /* * libDingaLing XMPP Jingle Library - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/libs/libdingaling/src/libdingaling.h b/libs/libdingaling/src/libdingaling.h index c32b9363d9..f103327339 100644 --- a/libs/libdingaling/src/libdingaling.h +++ b/libs/libdingaling/src/libdingaling.h @@ -1,6 +1,6 @@ /* * libDingaLing XMPP Jingle Library - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/libs/libteletone/src/libteletone.h b/libs/libteletone/src/libteletone.h index 6e806cec4f..b54098c8ee 100644 --- a/libs/libteletone/src/libteletone.h +++ b/libs/libteletone/src/libteletone.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is libteletone * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * libteletone.h -- Tone Generator/Detector diff --git a/libs/libteletone/src/libteletone_detect.c b/libs/libteletone/src/libteletone_detect.c index 3738e4c993..ae959535b5 100644 --- a/libs/libteletone/src/libteletone_detect.c +++ b/libs/libteletone/src/libteletone_detect.c @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -32,7 +32,7 @@ * a single arbitrary tone combination which may also exceed 2 simultaneous tones. * (controlled by compile time constant TELETONE_MAX_TONES) * - * Copyright (C) 2006 Anthony Minessale II + * Copyright (C) 2006 Anthony Minessale II * * * libteletone_detect.c Tone Detection Code diff --git a/libs/libteletone/src/libteletone_detect.h b/libs/libteletone/src/libteletone_detect.h index a9fee6cfbd..e2a8c20b33 100644 --- a/libs/libteletone/src/libteletone_detect.h +++ b/libs/libteletone/src/libteletone_detect.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -32,7 +32,7 @@ * a single arbitrary tone combination which may also exceed 2 simultaneous tones. * (controlled by compile time constant TELETONE_MAX_TONES) * - * Copyright (C) 2006 Anthony Minessale II + * Copyright (C) 2006 Anthony Minessale II * * * libteletone_detect.c Tone Detection Code diff --git a/libs/libteletone/src/libteletone_generate.c b/libs/libteletone/src/libteletone_generate.c index 3977ca521d..ebf62822a4 100644 --- a/libs/libteletone/src/libteletone_generate.c +++ b/libs/libteletone/src/libteletone_generate.c @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is libteletone * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * libteletone.c -- Tone Generator diff --git a/libs/libteletone/src/libteletone_generate.h b/libs/libteletone/src/libteletone_generate.h index a6addc4eb8..5e6444b0c4 100644 --- a/libs/libteletone/src/libteletone_generate.h +++ b/libs/libteletone/src/libteletone_generate.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is libteletone * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * libteletone.h -- Tone Generator diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 6a75dc85ff..3e5227ea90 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * Moises Silva * * diff --git a/libs/openzap/src/include/libteletone.h b/libs/openzap/src/include/libteletone.h index 6e806cec4f..b54098c8ee 100644 --- a/libs/openzap/src/include/libteletone.h +++ b/libs/openzap/src/include/libteletone.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is libteletone * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * libteletone.h -- Tone Generator/Detector diff --git a/libs/openzap/src/include/libteletone_detect.h b/libs/openzap/src/include/libteletone_detect.h index 3d0a5130ec..c8c667d282 100644 --- a/libs/openzap/src/include/libteletone_detect.h +++ b/libs/openzap/src/include/libteletone_detect.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * libteletone_detect.c Tone Detection Code * diff --git a/libs/openzap/src/include/libteletone_generate.h b/libs/openzap/src/include/libteletone_generate.h index fce19e7255..1b774206ff 100644 --- a/libs/openzap/src/include/libteletone_generate.h +++ b/libs/openzap/src/include/libteletone_generate.h @@ -1,6 +1,6 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Copyright (c) 2007, Anthony Minessale II * All rights reserved. diff --git a/libs/openzap/src/include/sangoma_tdm_api.h b/libs/openzap/src/include/sangoma_tdm_api.h index 062d4e219d..6438c99fbb 100644 --- a/libs/openzap/src/include/sangoma_tdm_api.h +++ b/libs/openzap/src/include/sangoma_tdm_api.h @@ -1,7 +1,7 @@ /***************************************************************************** * sangoma_tdm_api.h Sangoma TDM API Portability functions * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * Michael Jerris * David Rokhvarg diff --git a/libs/openzap/src/libteletone_detect.c b/libs/openzap/src/libteletone_detect.c index 61fef90149..0436c25953 100644 --- a/libs/openzap/src/libteletone_detect.c +++ b/libs/openzap/src/libteletone_detect.c @@ -1,12 +1,12 @@ /* * libteletone - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Much less efficient expansion interface was added to allow for the detection of * a single arbitrary tone combination which may also exceed 2 simultaneous tones. * (controlled by compile time constant TELETONE_MAX_TONES) * - * Copyright (C) 2006 Anthony Minessale II + * Copyright (C) 2006 Anthony Minessale II * * libteletone_detect.c Tone Detection Code * diff --git a/libs/openzap/src/priserver.c b/libs/openzap/src/priserver.c index 7a37357083..080e5d4cef 100644 --- a/libs/openzap/src/priserver.c +++ b/libs/openzap/src/priserver.c @@ -1,7 +1,7 @@ /***************************************************************************** * priserver.c Refactoring of pritest.c * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * * Copyright: (c) 2005 Anthony Minessale II diff --git a/libs/openzap/src/sangoma_pri.c b/libs/openzap/src/sangoma_pri.c index 5cf6a5cd10..c160eedd28 100644 --- a/libs/openzap/src/sangoma_pri.c +++ b/libs/openzap/src/sangoma_pri.c @@ -1,7 +1,7 @@ /***************************************************************************** * sangoma_pri.c libpri Sangoma integration * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * * Copyright: (c) 2005 Anthony Minessale II diff --git a/libs/openzap/src/sangoma_pri.h b/libs/openzap/src/sangoma_pri.h index 5ea21eb7b5..880fc85cea 100644 --- a/libs/openzap/src/sangoma_pri.h +++ b/libs/openzap/src/sangoma_pri.h @@ -1,7 +1,7 @@ /***************************************************************************** * libsangoma.c AFT T1/E1: HDLC API Code Library * - * Author(s): Anthony Minessale II + * Author(s): Anthony Minessale II * Nenad Corbic * * Copyright: (c) 2005 Anthony Minessale II diff --git a/libs/win32/Download CELT.vcproj b/libs/win32/Download CELT.vcproj index e32ebd42a6..cac10794c8 100644 --- a/libs/win32/Download CELT.vcproj +++ b/libs/win32/Download CELT.vcproj @@ -76,7 +76,7 @@ @@ -86,7 +86,7 @@ diff --git a/libs/win32/Download CELT.vcxproj b/libs/win32/Download CELT.vcxproj index af8c9aa543..527ff5a5f5 100644 --- a/libs/win32/Download CELT.vcxproj +++ b/libs/win32/Download CELT.vcxproj @@ -65,15 +65,15 @@ Document Downloading CELT. - if not exist "$(ProjectDir)..\celt-0.7.1" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/celt-0.7.1.tar.gz "$(ProjectDir).." -xcopy "$(ProjectDir)\celt\config.h" "$(ProjectDir)..\celt-0.7.1\libcelt" /C /D /Y /S /I -xcopy "$(ProjectDir)\celt\float_cast.h" "$(ProjectDir)..\celt-0.7.1\libcelt" /C /D /Y /S /I + if not exist "$(ProjectDir)..\celt-0.10.0" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz "$(ProjectDir).." +xcopy "$(ProjectDir)\celt\config.h" "$(ProjectDir)..\celt-0.10.0\libcelt" /C /D /Y /S /I +xcopy "$(ProjectDir)\celt\float_cast.h" "$(ProjectDir)..\celt-0.10.0\libcelt" /C /D /Y /S /I $(ProjectDir)..\CELT;%(Outputs) Downloading CELT. - if not exist "$(ProjectDir)..\celt-0.7.1" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/celt-0.7.1.tar.gz "$(ProjectDir).." -xcopy "$(ProjectDir)\celt\config.h" "$(ProjectDir)..\celt-0.7.1\libcelt" /C /D /Y /S /I -xcopy "$(ProjectDir)\celt\float_cast.h" "$(ProjectDir)..\celt-0.7.1\libcelt" /C /D /Y /S /I + if not exist "$(ProjectDir)..\celt-0.10.0" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz "$(ProjectDir).." +xcopy "$(ProjectDir)\celt\config.h" "$(ProjectDir)..\celt-0.10.0\libcelt" /C /D /Y /S /I +xcopy "$(ProjectDir)\celt\float_cast.h" "$(ProjectDir)..\celt-0.10.0\libcelt" /C /D /Y /S /I $(ProjectDir)..\CELT;%(Outputs) diff --git a/libs/win32/celt/libcelt.vcproj b/libs/win32/celt/libcelt.vcproj index 0533096a76..9a19d9e5fd 100644 --- a/libs/win32/celt/libcelt.vcproj +++ b/libs/win32/celt/libcelt.vcproj @@ -44,7 +44,7 @@ + + + + diff --git a/libs/win32/celt/libcelt.vcxproj b/libs/win32/celt/libcelt.vcxproj index 6abd09915b..b774320090 100644 --- a/libs/win32/celt/libcelt.vcxproj +++ b/libs/win32/celt/libcelt.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\..\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions) true EnableFastChecks @@ -82,7 +82,7 @@ Disabled - ..\..\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;_AMD64_;_WIN64;%(PreprocessorDefinitions) true EnableFastChecks @@ -94,7 +94,7 @@ MaxSpeed true - ..\..\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -108,7 +108,7 @@ MaxSpeed true - ..\..\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;_AMD64_;_WIN64;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -116,23 +116,25 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/libs/win32/celt/libcelt.vcxproj.filters b/libs/win32/celt/libcelt.vcxproj.filters index f3cb02a769..22236564f3 100644 --- a/libs/win32/celt/libcelt.vcxproj.filters +++ b/libs/win32/celt/libcelt.vcxproj.filters @@ -15,55 +15,61 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + + Source Files + + + Source Files + + Source Files diff --git a/libs/xmlrpc-c/lib/abyss/src/socket_win.c b/libs/xmlrpc-c/lib/abyss/src/socket_win.c index 92b2b99cfb..d3f683a439 100644 --- a/libs/xmlrpc-c/lib/abyss/src/socket_win.c +++ b/libs/xmlrpc-c/lib/abyss/src/socket_win.c @@ -9,8 +9,7 @@ #include #include #include -#include -#include +#include #include "xmlrpc_config.h" #include "xmlrpc-c/util_int.h" @@ -249,6 +248,7 @@ struct socketWin { SOCKET winsock; bool userSuppliedWinsock; /* 'socket' was supplied by the user; it belongs to him */ + HANDLE interruptEvent; }; static @@ -322,6 +322,8 @@ channelDestroy(TChannel * const channelP) { if (!socketWinP->userSuppliedWinsock) closesocket(socketWinP->winsock); + CloseHandle(socketWinP->interruptEvent); + free(socketWinP); } @@ -430,9 +432,9 @@ channelWait(TChannel * const channelP, timedOut = TRUE; break; case -1: /* socket error */ - if (errno != EINTR) + if (WSAGetLastError() != WSAEINTR) failed = TRUE; - break; + break; default: if (FD_ISSET(socketWinP->winsock, &rfds)) readRdy = TRUE; @@ -460,7 +462,9 @@ channelInterrupt(TChannel * const channelP) { now or in the future. Actually, this is just a no-op because we don't yet know how to - accomplish that. + accomplish that. (But we could probably do it the same way + chanSwitchInterrupt() works -- no one has needed it enough yet to do that + work). -----------------------------------------------------------------------------*/ } @@ -484,7 +488,7 @@ ChannelWinGetPeerName(TChannel * const channelP, if (rc != 0) { int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "getpeername() failed. WSAERROR = %d (%s)", + xmlrpc_asprintf(errorP, "getpeername() failed. WSA error = %d (%s)", lastError, getWSAError(lastError)); } else { if (addrlen != sizeof(sockAddr)) @@ -581,7 +585,8 @@ makeChannelFromWinsock(SOCKET const winsock, socketWinP->winsock = winsock; socketWinP->userSuppliedWinsock = TRUE; - + socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + ChannelCreate(&channelVtbl, socketWinP, &channelP); if (channelP == NULL) @@ -591,8 +596,10 @@ makeChannelFromWinsock(SOCKET const winsock, *channelPP = channelP; *errorP = NULL; } - if (*errorP) + if (*errorP) { + CloseHandle(socketWinP->interruptEvent); free(socketWinP); + } } } @@ -632,7 +639,7 @@ ChannelWinCreateWinsock(SOCKET const fd, socklen_t peerAddrLen; int rc; - peerAddrLen = sizeof(peerAddrLen); + peerAddrLen = sizeof(peerAddr); rc = getpeername(fd, &peerAddr, &peerAddrLen); @@ -676,6 +683,8 @@ chanSwitchDestroy(TChanSwitch * const chanSwitchP) { if (!socketWinP->userSuppliedWinsock) closesocket(socketWinP->winsock); + CloseHandle(socketWinP->interruptEvent); + free(socketWinP); } @@ -711,6 +720,49 @@ chanSwitchListen(TChanSwitch * const chanSwitchP, +static void +createChannelForAccept(int const acceptedWinsock, + struct sockaddr const peerAddr, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { + + struct abyss_win_chaninfo * channelInfoP; + makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP); + if (!*errorP) { + struct socketWin * acceptedSocketP; + + MALLOCVAR(acceptedSocketP); + + if (!acceptedSocketP) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + TChannel * channelP; + + acceptedSocketP->winsock = acceptedWinsock; + acceptedSocketP->userSuppliedWinsock = FALSE; + acceptedSocketP->interruptEvent = + CreateEvent(NULL, FALSE, FALSE, NULL); + + ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); + if (!channelP) + xmlrpc_asprintf(errorP, + "Failed to create TChannel object."); + else { + *errorP = NULL; + *channelPP = channelP; + *channelInfoPP = channelInfoP; + } + if (*errorP) { + CloseHandle(acceptedSocketP->interruptEvent); + free(acceptedSocketP); + } + } + } +} + + + static SwitchAcceptImpl chanSwitchAccept; static void @@ -728,7 +780,7 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP, *channelPP == NULL. -----------------------------------------------------------------------------*/ struct socketWin * const listenSocketP = chanSwitchP->implP; - + HANDLE acceptEvent = WSACreateEvent(); bool interrupted; TChannel * channelP; @@ -736,46 +788,44 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP, channelP = NULL; /* No connection yet */ *errorP = NULL; /* No error yet */ + WSAEventSelect(listenSocketP->winsock, acceptEvent, + FD_ACCEPT | FD_CLOSE | FD_READ); + while (!channelP && !*errorP && !interrupted) { + HANDLE interrupts[2] = {acceptEvent, listenSocketP->interruptEvent}; + int rc; struct sockaddr peerAddr; socklen_t size = sizeof(peerAddr); - int rc; + + rc = WaitForMultipleObjects(2, interrupts, FALSE, INFINITE); + if (WAIT_OBJECT_0 + 1 == rc) { + interrupted = TRUE; + continue; + }; rc = accept(listenSocketP->winsock, &peerAddr, &size); if (rc >= 0) { int const acceptedWinsock = rc; - struct socketWin * acceptedSocketP; - MALLOCVAR(acceptedSocketP); + createChannelForAccept(acceptedWinsock, peerAddr, + &channelP, channelInfoPP, errorP); - if (!acceptedSocketP) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - acceptedSocketP->winsock = acceptedWinsock; - acceptedSocketP->userSuppliedWinsock = FALSE; - - *channelInfoPP = NULL; - - ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); - if (!channelP) - xmlrpc_asprintf(errorP, - "Failed to create TChannel object."); - else - *errorP = NULL; - - if (*errorP) - free(acceptedSocketP); - } if (*errorP) closesocket(acceptedWinsock); - } else if (errno == EINTR) - interrupted = TRUE; - else - xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)", - errno, strerror(errno)); + } else { + int const lastError = WSAGetLastError(); + + if (lastError == WSAEINTR) + interrupted = TRUE; + else + xmlrpc_asprintf(errorP, + "accept() failed, WSA error = %d (%s)", + lastError, getWSAError(lastError)); + } } *channelPP = channelP; + CloseHandle(acceptEvent); } @@ -787,15 +837,10 @@ chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { /*---------------------------------------------------------------------------- Interrupt any waiting that a thread might be doing in chanSwitchAccept() now or in the future. - - Actually, this is just a no-op because we don't yet know how to - accomplish that. -----------------------------------------------------------------------------*/ - struct socketWin * const socketWinP = chanSwitchP->implP; - - if (!socketWinP->userSuppliedWinsock) - closesocket(socketWinP->winsock); + struct socketWin * const listenSocketP = chanSwitchP->implP; + SetEvent(listenSocketP->interruptEvent); } @@ -889,6 +934,7 @@ ChanSwitchWinCreate(uint16_t const portNumber, } else { socketWinP->winsock = winsock; socketWinP->userSuppliedWinsock = FALSE; + socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); setSocketOptions(socketWinP->winsock, errorP); if (!*errorP) { @@ -899,8 +945,10 @@ ChanSwitchWinCreate(uint16_t const portNumber, chanSwitchPP); } - if (*errorP) + if (*errorP) { + CloseHandle(socketWinP->interruptEvent); closesocket(winsock); + } } if (*errorP) free(socketWinP); @@ -929,7 +977,8 @@ ChanSwitchWinCreateWinsock(SOCKET const winsock, socketWinP->winsock = winsock; socketWinP->userSuppliedWinsock = TRUE; - + socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + ChanSwitchCreate(&chanSwitchVtbl, socketWinP, &chanSwitchP); if (chanSwitchP == NULL) @@ -939,8 +988,10 @@ ChanSwitchWinCreateWinsock(SOCKET const winsock, *chanSwitchPP = chanSwitchP; *errorP = NULL; } - if (*errorP) + if (*errorP) { + CloseHandle(socketWinP->interruptEvent); free(socketWinP); + } } } } diff --git a/scripts/c/socket2me/socket2me.c b/scripts/c/socket2me/socket2me.c index 5d6fceb701..1b3aa0c6f2 100644 --- a/scripts/c/socket2me/socket2me.c +++ b/scripts/c/socket2me/socket2me.c @@ -29,7 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * - * Copyright (C) 2007, Anthony Minessale II + * Copyright (C) 2007, Anthony Minessale II */ #include diff --git a/scripts/javascript/api.js b/scripts/javascript/api.js index 41b632ef6b..47c5770353 100644 --- a/scripts/javascript/api.js +++ b/scripts/javascript/api.js @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * api.js Demo javascript FSAPI Interface diff --git a/scripts/javascript/js_modules/SpeechTools.jm b/scripts/javascript/js_modules/SpeechTools.jm index 6f9fb25089..4e9628b2f5 100644 --- a/scripts/javascript/js_modules/SpeechTools.jm +++ b/scripts/javascript/js_modules/SpeechTools.jm @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005/2006, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * SpeechTools.jm Speech Detection Interface diff --git a/scripts/javascript/pizza.js b/scripts/javascript/pizza.js index b665ca6620..9807f5bc8d 100644 --- a/scripts/javascript/pizza.js +++ b/scripts/javascript/pizza.js @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * pizza.js ASR Demonstration Application diff --git a/scripts/javascript/ps_pizza.js b/scripts/javascript/ps_pizza.js index 50d3167718..7fd405e009 100644 --- a/scripts/javascript/ps_pizza.js +++ b/scripts/javascript/ps_pizza.js @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * * * pizza.js ASR Demonstration Application diff --git a/scripts/perl/sendmail b/scripts/perl/sendmail index 1cf6f71d69..a89dce6cef 100644 --- a/scripts/perl/sendmail +++ b/scripts/perl/sendmail @@ -5,7 +5,7 @@ # voicemail gateway with no mail server> # # (c) 2005 Anthony Minessale II -# Anthony Minessale +# Anthony Minessale # ################################################################################ use Net::SMTP; diff --git a/scripts/python/freepy/__init__.py b/scripts/python/freepy/__init__.py index e23fc6fc70..cebe48a0ab 100644 --- a/scripts/python/freepy/__init__.py +++ b/scripts/python/freepy/__init__.py @@ -1,6 +1,6 @@ """ FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -Copyright (C) 2005/2006, Anthony Minessale II +Copyright (C) 2005-2011, Anthony Minessale II Version: MPL 1.1 @@ -17,7 +17,7 @@ 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 +Anthony Minessale II Portions created by the Initial Developer are Copyright (C) the Initial Developer. All Rights Reserved. diff --git a/scripts/python/freepy/fseventlistener.py b/scripts/python/freepy/fseventlistener.py index 8e1f118528..6e3455f62f 100644 --- a/scripts/python/freepy/fseventlistener.py +++ b/scripts/python/freepy/fseventlistener.py @@ -1,6 +1,6 @@ """ FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -Copyright (C) 2005/2006, Anthony Minessale II +Copyright (C) 2005-2011, Anthony Minessale II Version: MPL 1.1 @@ -17,7 +17,7 @@ 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 +Anthony Minessale II Portions created by the Initial Developer are Copyright (C) the Initial Developer. All Rights Reserved. diff --git a/scripts/python/freepy/fshelper.py b/scripts/python/freepy/fshelper.py index a06ed40985..090abce9d6 100644 --- a/scripts/python/freepy/fshelper.py +++ b/scripts/python/freepy/fshelper.py @@ -2,7 +2,7 @@ """ FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -Copyright (C) 2005/2006, Anthony Minessale II +Copyright (C) 2005-2011, Anthony Minessale II Version: MPL 1.1 @@ -19,7 +19,7 @@ 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 +Anthony Minessale II Portions created by the Initial Developer are Copyright (C) the Initial Developer. All Rights Reserved. diff --git a/scripts/python/freepy/models.py b/scripts/python/freepy/models.py index 2b9de74510..3dfb105424 100644 --- a/scripts/python/freepy/models.py +++ b/scripts/python/freepy/models.py @@ -1,6 +1,6 @@ """ FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -Copyright (C) 2005/2006, Anthony Minessale II +Copyright (C) 2005-2011, Anthony Minessale II Version: MPL 1.1 @@ -17,7 +17,7 @@ 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 +Anthony Minessale II Portions created by the Initial Developer are Copyright (C) the Initial Developer. All Rights Reserved. diff --git a/scripts/python/freepy/request.py b/scripts/python/freepy/request.py index f2c6e389b0..d76fe2942c 100644 --- a/scripts/python/freepy/request.py +++ b/scripts/python/freepy/request.py @@ -1,6 +1,6 @@ """ FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -Copyright (C) 2005/2006, Anthony Minessale II +Copyright (C) 2005-2011, Anthony Minessale II Version: MPL 1.1 @@ -17,7 +17,7 @@ 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 +Anthony Minessale II Portions created by the Initial Developer are Copyright (C) the Initial Developer. All Rights Reserved. diff --git a/scripts/rss/rss2ivr.pl b/scripts/rss/rss2ivr.pl index f74a51c5f3..ed5aabd3a3 100755 --- a/scripts/rss/rss2ivr.pl +++ b/scripts/rss/rss2ivr.pl @@ -4,7 +4,7 @@ # # Copyright (C) 2006, Anthony Minessale # -# Anthony Minessale +# Anthony Minessale # # This program is free software, distributed under the terms of # Perl itself diff --git a/scripts/trace/sipgrep b/scripts/trace/sipgrep index e161675a34..7bd5daed4d 100755 --- a/scripts/trace/sipgrep +++ b/scripts/trace/sipgrep @@ -1,6 +1,6 @@ #!/usr/bin/perl # sipgrep version 0.2. Skin for ngrep. (C) 2005-2006 Alexandr Dubovikov -# Modified 2007 Anthony Minessale +# Modified 2007 Anthony Minessale use Term::ANSIColor; use Getopt::Std; diff --git a/src/fs_encode.c b/src/fs_encode.c index 9517802600..bdaf1ec759 100644 --- a/src/fs_encode.c +++ b/src/fs_encode.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 422d5f2930..30690b1848 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch.h b/src/include/switch.h index 81684c59b0..ce2ba7867f 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index 7a19bd165e..a2ef3e5052 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_bitpack.h b/src/include/switch_bitpack.h index f534ea6bcf..3209cbc282 100644 --- a/src/include/switch_bitpack.h +++ b/src/include/switch_bitpack.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_buffer.h b/src/include/switch_buffer.h index 40c4c5a278..75b5929b9b 100644 --- a/src/include/switch_buffer.h +++ b/src/include/switch_buffer.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_caller.h b/src/include/switch_caller.h index f77f1b016d..bd53a04f68 100644 --- a/src/include/switch_caller.h +++ b/src/include/switch_caller.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index e726554d81..c0bef4be59 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -256,6 +256,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_partner_var_check(sw const char *varname, const char *value, switch_bool_t var_check); SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_t *channel, const char *varname); +SWITCH_DECLARE(const char *) switch_channel_get_hold_music(switch_channel_t *channel); +SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channel_t *channel); #define switch_channel_set_variable(_channel, _var, _val) switch_channel_set_variable_var_check(_channel, _var, _val, SWITCH_TRUE) #define switch_channel_set_variable_partner(_channel, _var, _val) switch_channel_set_variable_partner_var_check(_channel, _var, _val, SWITCH_TRUE) @@ -344,6 +346,7 @@ SWITCH_DECLARE(void) switch_channel_set_cap_value(switch_channel_t *channel, swi SWITCH_DECLARE(void) switch_channel_clear_cap(switch_channel_t *channel, switch_channel_cap_t cap); SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, switch_channel_cap_t cap); +SWITCH_DECLARE(uint32_t) switch_channel_test_cap_partner(switch_channel_t *channel, switch_channel_cap_t cap); /*! \brief Set given flag(s) on a given channel's bridge partner diff --git a/src/include/switch_config.h b/src/include/switch_config.h index 4115564f56..b0ef805b52 100644 --- a/src/include/switch_config.h +++ b/src/include/switch_config.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_console.h b/src/include/switch_console.h index 31d5ebf8e4..5585a041c1 100644 --- a/src/include/switch_console.h +++ b/src/include/switch_console.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_core.h b/src/include/switch_core.h index bcd3c0aee2..29e8b43526 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -116,7 +116,6 @@ struct switch_core_session; struct switch_core_runtime; struct switch_core_port_allocator; - /*! \defgroup core1 Core Library \ingroup FREESWITCH @@ -713,6 +712,7 @@ SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *sessio SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine); SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data); /*! \brief Retrieve the unique identifier from the core @@ -2162,6 +2162,13 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_hand SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, const char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err); +/*! + \brief Get the affected rows of the last performed query + \param [in] dbh The handle + \param [out] the number of affected rows +*/ +SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh); + /*! \brief Provides some feedback as to the status of the db connection pool \param [in] stream stream for status diff --git a/src/include/switch_core_db.h b/src/include/switch_core_db.h index 6be6e8eeda..6ea9b4a3fb 100644 --- a/src/include/switch_core_db.h +++ b/src/include/switch_core_db.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_core_event_hook.h b/src/include/switch_core_event_hook.h index 575786f5ce..ff836b3978 100644 --- a/src/include/switch_core_event_hook.h +++ b/src/include/switch_core_event_hook.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_event.h b/src/include/switch_event.h index 41bc75cada..56acbd3a4b 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_frame.h b/src/include/switch_frame.h index 20103a16cb..edc4f8be6c 100644 --- a/src/include/switch_frame.h +++ b/src/include/switch_frame.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index da366c5b8d..46c9c91670 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_limit.h b/src/include/switch_limit.h index e798f9c8af..4488b8caf0 100644 --- a/src/include/switch_limit.h +++ b/src/include/switch_limit.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index 37c752bd3e..7e4d617256 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_log.h b/src/include/switch_log.h index 98d9448bac..170425a2a4 100644 --- a/src/include/switch_log.h +++ b/src/include/switch_log.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index ae0ce900a9..114e594c0c 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -711,6 +711,14 @@ struct switch_api_interface { #define PROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); #define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); +#include "switch_frame.h" + +struct switch_slin_data { + switch_core_session_t *session; + switch_frame_t write_frame; + switch_codec_t codec; + char frame_data[SWITCH_RECOMMENDED_BUFFER_SIZE]; +}; SWITCH_END_EXTERN_C #endif diff --git a/src/include/switch_nat.h b/src/include/switch_nat.h index 09118c10eb..bdbd51b592 100644 --- a/src/include/switch_nat.h +++ b/src/include/switch_nat.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_odbc.h b/src/include/switch_odbc.h index b8d4bc2f17..103fe0f0d7 100644 --- a/src/include/switch_odbc.h +++ b/src/include/switch_odbc.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -34,6 +34,8 @@ #include +#define DEFAULT_ODBC_RETRIES 120 + SWITCH_BEGIN_EXTERN_C struct switch_odbc_handle; typedef void *switch_odbc_statement_handle_t; @@ -50,6 +52,7 @@ typedef enum { } switch_odbc_status_t; SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, const char *username, const char *password); +SWITCH_DECLARE(void) switch_odbc_set_num_retries(switch_odbc_handle_t *handle, int num_retries); SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle); SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_handle_t *handle); SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep); @@ -92,6 +95,9 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c SWITCH_DECLARE(char *) switch_odbc_handle_get_error(switch_odbc_handle_t *handle, switch_odbc_statement_handle_t stmt); + +SWITCH_DECLARE(int) switch_odbc_handle_affected_rows(switch_odbc_handle_t *handle); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index c1ad51f92e..15b3277404 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_regex.h b/src/include/switch_regex.h index 4ee1fd582a..96d623043c 100644 --- a/src/include/switch_regex.h +++ b/src/include/switch_regex.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_resample.h b/src/include/switch_resample.h index 55f1740bff..b38e094dd6 100644 --- a/src/include/switch_resample.h +++ b/src/include/switch_resample.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index c48a40e6d1..27dacc7c18 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -237,6 +237,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name); SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session); +SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause); /*! \brief Set an RTP Flag diff --git a/src/include/switch_scheduler.h b/src/include/switch_scheduler.h index d9fa5655d7..8db9696f4a 100644 --- a/src/include/switch_scheduler.h +++ b/src/include/switch_scheduler.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_stun.h b/src/include/switch_stun.h index d5df57e4fe..426eb49628 100644 --- a/src/include/switch_stun.h +++ b/src/include/switch_stun.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_types.h b/src/include/switch_types.h index bb5f59865f..3972404290 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -156,6 +156,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_PROXY_MEDIA_VARIABLE "proxy_media" #define SWITCH_ENDPOINT_DISPOSITION_VARIABLE "endpoint_disposition" #define SWITCH_HOLD_MUSIC_VARIABLE "hold_music" +#define SWITCH_TEMP_HOLD_MUSIC_VARIABLE "temp_hold_music" #define SWITCH_EXPORT_VARS_VARIABLE "export_vars" #define SWITCH_BRIDGE_EXPORT_VARS_VARIABLE "bridge_export_vars" #define SWITCH_R_SDP_VARIABLE "switch_r_sdp" @@ -631,9 +632,13 @@ typedef enum { This flag will never send any. Sheesh.... */ + RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6) - - + /* + Guess Who? ... Yep, Sonus (and who know's who else) likes to interweave DTMF with the audio stream making it take + 2X as long as it should and sending an incorrect duration making the DTMF very delayed. + This flag will treat every dtmf as if it were 50ms and queue it on recipt of the leading packet rather than at the end. + */ } switch_rtp_bug_flag_t; @@ -854,7 +859,7 @@ typedef enum { SWITCH_STATUS_FALSE, SWITCH_STATUS_TIMEOUT, SWITCH_STATUS_RESTART, - SWITCH_STATUS_TERM, + SWITCH_STATUS_INTR, SWITCH_STATUS_NOTIMPL, SWITCH_STATUS_MEMERR, SWITCH_STATUS_NOOP, @@ -871,6 +876,7 @@ typedef enum { SWITCH_STATUS_TOO_SMALL, SWITCH_STATUS_FOUND, SWITCH_STATUS_CONTINUE, + SWITCH_STATUS_TERM, SWITCH_STATUS_NOT_INITALIZED } switch_status_t; @@ -1035,6 +1041,8 @@ typedef enum { CC_MEDIA_ACK = 1, CC_BYPASS_MEDIA, CC_PROXY_MEDIA, + CC_JITTERBUFFER, + CC_FS_RTP, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CC_FLAG_MAX } switch_channel_cap_t; @@ -1814,6 +1822,8 @@ typedef struct switch_loadable_module_function_table { typedef int (*switch_modulename_callback_func_t) (void *user_data, const char *module_name); +typedef struct switch_slin_data switch_slin_data_t; + #define SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, flags) \ static const char modname[] = #name ; \ SWITCH_MOD_DECLARE_DATA switch_loadable_module_function_table_t name##_module_interface = { \ diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 3360f33fe5..2c4de14334 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -184,6 +184,32 @@ static inline switch_bool_t switch_is_digit_string(const char *s) return SWITCH_TRUE; } +static inline char switch_itodtmf(char i) +{ + char r = i; + + if (i > 9 && i < 14) { + r = i + 55; + } + + return r; +} + +static inline int switch_dtmftoi(char *s) +{ + int r; + + switch_assert(s); + + if (!(r = atoi(s))) { + int l = tolower(*s); + if (l > 96 && l < 101) { + r = l - 87; + } + } + + return r; +} static inline uint32_t switch_known_bitrate(switch_payload_t payload) { @@ -301,7 +327,7 @@ SWITCH_DECLARE(unsigned short) get_port(struct sockaddr *sa); */ SWITCH_DECLARE(int) switch_build_uri(char *uri, switch_size_t size, const char *scheme, const char *user, const switch_sockaddr_t *sa, int flags); -#define SWITCH_STATUS_IS_BREAK(x) (x == SWITCH_STATUS_BREAK || x == 730035 || x == 35) +#define SWITCH_STATUS_IS_BREAK(x) (x == SWITCH_STATUS_BREAK || x == 730035 || x == 35 || x == SWITCH_STATUS_INTR) /*! \brief Return a printable name of a switch_priority_t diff --git a/src/include/switch_xml.h b/src/include/switch_xml.h index 9b0fbb44f3..bd9e6a06da 100644 --- a/src/include/switch_xml.h +++ b/src/include/switch_xml.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/include/switch_xml_config.h b/src/include/switch_xml_config.h index 3e78f5f46f..49986c9211 100644 --- a/src/include/switch_xml_config.h +++ b/src/include/switch_xml_config.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index ca92b17fa4..d1de632ee6 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_cidlookup/mod_cidlookup.c b/src/mod/applications/mod_cidlookup/mod_cidlookup.c index 230c48ac8d..2ec41f19e4 100755 --- a/src/mod/applications/mod_cidlookup/mod_cidlookup.c +++ b/src/mod/applications/mod_cidlookup/mod_cidlookup.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_cluechoo/mod_cluechoo.c b/src/mod/applications/mod_cluechoo/mod_cluechoo.c index ab14b757aa..2699d82fc4 100644 --- a/src/mod/applications/mod_cluechoo/mod_cluechoo.c +++ b/src/mod/applications/mod_cluechoo/mod_cluechoo.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 20ee167945..62c919d470 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 21feaa99ca..2d9341a598 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -5046,7 +5046,7 @@ static switch_status_t conference_local_play_file(conference_obj_t *conference, goto done; } - if (conference->sound_prefix) { + if (!switch_is_file_path(path) && conference->sound_prefix) { if (!(dpath = switch_mprintf("%s%s%s", conference->sound_prefix, SWITCH_PATH_SEPARATOR, path))) { status = SWITCH_STATUS_MEMERR; goto done; @@ -5827,7 +5827,7 @@ SWITCH_STANDARD_APP(conference_function) toplay = conference->kicked_sound; } - if (conference->sound_prefix) { + if (!switch_is_file_path(toplay) && conference->sound_prefix) { dfile = switch_mprintf("%s%s%s", conference->sound_prefix, SWITCH_PATH_SEPARATOR, toplay); switch_assert(dfile); toplay = dfile; @@ -5845,6 +5845,8 @@ SWITCH_STANDARD_APP(conference_function) if (rl) { switch_thread_rwlock_unlock(conference->rwlock); } + + switch_channel_set_variable(channel, "last_transfered_conference", NULL); } /* Create a thread for the conference and launch it */ diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index 4f6aefd313..633e4c80e2 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index 088d9d0a85..e611d036ea 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_directory/mod_directory.c b/src/mod/applications/mod_directory/mod_directory.c index d92974766d..0127363064 100644 --- a/src/mod/applications/mod_directory/mod_directory.c +++ b/src/mod/applications/mod_directory/mod_directory.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_distributor/mod_distributor.c b/src/mod/applications/mod_distributor/mod_distributor.c index f4070a9bc6..b87b3edb75 100644 --- a/src/mod/applications/mod_distributor/mod_distributor.c +++ b/src/mod/applications/mod_distributor/mod_distributor.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 6fbf70bdfd..41417255bb 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -389,7 +389,7 @@ SWITCH_STANDARD_APP(dtmf_unbind_function) int kval = 0; if (key) { - kval = atoi(key); + kval = switch_dtmftoi(key); } switch_ivr_unbind_dtmf_meta_session(session, kval); @@ -405,7 +405,7 @@ SWITCH_STANDARD_APP(dtmf_bind_function) if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data)) && (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) == 4) { - int kval = atoi(argv[0]); + int kval = switch_dtmftoi(argv[0]); switch_bind_flag_t bind_flags = 0; if (strchr(argv[1], 'a')) { @@ -1485,6 +1485,8 @@ SWITCH_STANDARD_APP(ivr_application_function) } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to find menu\n"); } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No menus configured\n"); } switch_xml_free(cxml); } else { @@ -2531,7 +2533,7 @@ SWITCH_STANDARD_APP(audio_bridge_function) camp_data = (char *) data; } - if (!(moh = switch_channel_get_variable(caller_channel, "hold_music"))) { + if (!(moh = switch_channel_get_hold_music(caller_channel))) { moh = switch_channel_get_variable(caller_channel, "campon_hold_music"); } diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c index 8a21a2230c..481df958cf 100644 --- a/src/mod/applications/mod_easyroute/mod_easyroute.c +++ b/src/mod/applications/mod_easyroute/mod_easyroute.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_enum/mod_enum.c b/src/mod/applications/mod_enum/mod_enum.c index 1f00721bda..378c336810 100644 --- a/src/mod/applications/mod_enum/mod_enum.c +++ b/src/mod/applications/mod_enum/mod_enum.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index 20cad68c27..a2f8ddb8cd 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_expr/mod_expr.c b/src/mod/applications/mod_expr/mod_expr.c index f761b3c8e9..d562d8cd9c 100644 --- a/src/mod/applications/mod_expr/mod_expr.c +++ b/src/mod/applications/mod_expr/mod_expr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_fax/mod_fax.c b/src/mod/applications/mod_fax/mod_fax.c index da1a98edf6..a899d270fc 100644 --- a/src/mod/applications/mod_fax/mod_fax.c +++ b/src/mod/applications/mod_fax/mod_fax.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index e9d7cfb0e6..2e074138ba 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -397,12 +397,12 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit const char *moh_a = NULL, *moh_b = NULL; if (!(moh_b = switch_channel_get_variable(bchan, "fifo_music"))) { - moh_b = switch_channel_get_variable(bchan, "hold_music"); + moh_b = switch_channel_get_hold_music(bchan); } if (!(moh_a = switch_channel_get_variable(channel, "fifo_hold_music"))) { if (!(moh_a = switch_channel_get_variable(channel, "fifo_music"))) { - moh_a = switch_channel_get_variable(channel, "hold_music"); + moh_a = switch_channel_get_hold_music(channel); } } @@ -582,6 +582,8 @@ static int check_caller_outbound_call(const char *key) { int x = 0; + if (!key) return x; + switch_mutex_lock(globals.caller_orig_mutex); x = !!switch_core_hash_find(globals.caller_orig_hash, key); switch_mutex_unlock(globals.caller_orig_mutex); @@ -592,6 +594,8 @@ static int check_caller_outbound_call(const char *key) static void add_caller_outbound_call(const char *key, switch_call_cause_t *cancel_cause) { + if (!key) return; + switch_mutex_lock(globals.caller_orig_mutex); switch_core_hash_insert(globals.caller_orig_hash, key, cancel_cause); switch_mutex_unlock(globals.caller_orig_mutex); @@ -599,6 +603,8 @@ static void add_caller_outbound_call(const char *key, switch_call_cause_t *cance static void del_caller_outbound_call(const char *key) { + if (!key) return; + switch_mutex_lock(globals.caller_orig_mutex); switch_core_hash_delete(globals.caller_orig_hash, key); switch_mutex_unlock(globals.caller_orig_mutex); @@ -608,6 +614,8 @@ static void cancel_caller_outbound_call(const char *key, switch_call_cause_t cau { switch_call_cause_t *cancel_cause = NULL; + if (!key) return; + switch_mutex_lock(globals.caller_orig_mutex); if ((cancel_cause = (switch_call_cause_t *) switch_core_hash_find(globals.caller_orig_hash, key))) { *cancel_cause = cause; @@ -624,6 +632,8 @@ static int check_bridge_call(const char *key) { int x = 0; + if (!key) return x; + switch_mutex_lock(globals.bridge_mutex); x = !!switch_core_hash_find(globals.bridge_hash, key); switch_mutex_unlock(globals.bridge_mutex); @@ -634,6 +644,8 @@ static int check_bridge_call(const char *key) static void add_bridge_call(const char *key) { + if (!key) return; + switch_mutex_lock(globals.bridge_mutex); switch_core_hash_insert(globals.bridge_hash, key, (void *)&marker); switch_mutex_unlock(globals.bridge_mutex); @@ -651,6 +663,8 @@ static int check_consumer_outbound_call(const char *key) { int x = 0; + if (!key) return x; + switch_mutex_lock(globals.consumer_orig_mutex); x = !!switch_core_hash_find(globals.consumer_orig_hash, key); switch_mutex_unlock(globals.consumer_orig_mutex); @@ -660,6 +674,8 @@ static int check_consumer_outbound_call(const char *key) static void add_consumer_outbound_call(const char *key, switch_call_cause_t *cancel_cause) { + if (!key) return; + switch_mutex_lock(globals.consumer_orig_mutex); switch_core_hash_insert(globals.consumer_orig_hash, key, cancel_cause); switch_mutex_unlock(globals.consumer_orig_mutex); @@ -667,6 +683,8 @@ static void add_consumer_outbound_call(const char *key, switch_call_cause_t *can static void del_consumer_outbound_call(const char *key) { + if (!key) return; + switch_mutex_lock(globals.consumer_orig_mutex); switch_core_hash_delete(globals.consumer_orig_hash, key); switch_mutex_unlock(globals.consumer_orig_mutex); @@ -676,6 +694,8 @@ static void cancel_consumer_outbound_call(const char *key, switch_call_cause_t c { switch_call_cause_t *cancel_cause = NULL; + if (!key) return; + switch_mutex_lock(globals.consumer_orig_mutex); if ((cancel_cause = (switch_call_cause_t *) switch_core_hash_find(globals.consumer_orig_hash, key))) { *cancel_cause = cause; @@ -953,9 +973,14 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ consumer_channel = switch_core_session_get_channel(consumer_session); outbound_id = switch_channel_get_variable(consumer_channel, "fifo_outbound_uuid"); + if (!outbound_id) return SWITCH_STATUS_SUCCESS; + switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_BRIDGE: case SWITCH_MESSAGE_INDICATE_UNBRIDGE: + if (msg->numeric_arg == 42) { + goto end; + } if ((caller_session = switch_core_session_locate(msg->string_arg))) { caller_channel = switch_core_session_get_channel(caller_session); if (msg->message_id == SWITCH_MESSAGE_INDICATE_BRIDGE) { @@ -1008,7 +1033,6 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ switch_channel_get_variable(caller_channel, "fifo_import_prefix")); } - ced_name = switch_channel_get_variable(consumer_channel, "callee_id_name"); ced_number = switch_channel_get_variable(consumer_channel, "callee_id_number"); @@ -1949,6 +1973,8 @@ static uint32_t fifo_add_outbound(const char *node_name, const char *url, uint32 priority = MAX_PRI - 1; } + if (!node_name) return 0; + switch_mutex_lock(globals.mutex); if (!(node = switch_core_hash_find(globals.fifo_hash, node_name))) { @@ -2079,17 +2105,18 @@ SWITCH_STANDARD_APP(fifo_track_call_function) return; } - switch_core_event_hook_add_receive_message(session, messagehook); - switch_core_event_hook_add_state_run(session, hanguphook); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s tracking call on uuid %s!\n", switch_channel_get_name(channel), data); + switch_channel_set_variable(channel, "fifo_outbound_uuid", data); + switch_channel_set_variable(channel, "fifo_track_call", "true"); add_bridge_call(data); switch_channel_set_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_TRACKING); - switch_channel_set_variable(channel, "fifo_outbound_uuid", data); - switch_channel_set_variable(channel, "fifo_track_call", "true"); + switch_core_event_hook_add_receive_message(session, messagehook); + switch_core_event_hook_add_state_run(session, hanguphook); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s tracking call on uuid %s!\n", switch_channel_get_name(channel), data); + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { col1 = "manual_calls_in_count"; @@ -4166,6 +4193,8 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co char *sql, *name_dup, *p; fifo_node_t *node = NULL; + if (!fifo_name) return; + if (switch_stristr("fifo_outbound_uuid=", originate_string)) { extract_fifo_outbound_uuid(originate_string, digest, sizeof(digest)); } else { @@ -4213,6 +4242,9 @@ static void fifo_member_del(char *fifo_name, char *originate_string) callback_t cbt = { 0 }; fifo_node_t *node = NULL; + if (!fifo_name) return; + + if (switch_stristr("fifo_outbound_uuid=", originate_string)) { extract_fifo_outbound_uuid(originate_string, digest, sizeof(digest)); } else { diff --git a/src/mod/applications/mod_fsk/Makefile b/src/mod/applications/mod_fsk/Makefile new file mode 100644 index 0000000000..620f3f751c --- /dev/null +++ b/src/mod/applications/mod_fsk/Makefile @@ -0,0 +1,6 @@ +BASE=../../../.. + +LOCAL_SOURCES=fsk.c uart.c fsk_callerid.c +LOCAL_OBJS=fsk.o uart.o fsk_callerid.o +include $(BASE)/build/modmake.rules + diff --git a/src/mod/applications/mod_fsk/fsk.c b/src/mod/applications/mod_fsk/fsk.c new file mode 100644 index 0000000000..773b0deaae --- /dev/null +++ b/src/mod/applications/mod_fsk/fsk.c @@ -0,0 +1,351 @@ + +/* + * bell202.c + * + * Copyright (c) 2005 Robert Krten. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This module contains a Bell-202 1200-baud FSK decoder, suitable for + * use in a library. The general style of the library calls is modeled + * after the POSIX pthread_*() functions. + * + * 2005 03 20 R. Krten created +*/ + +#include +#include +#include +#include +#include + +#include "fsk.h" +#include "uart.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +fsk_modem_definition_t fsk_modem_definitions[] = +{ + { /* FSK_V23_FORWARD_MODE1 */ 1700, 1300, 600 }, + { /* FSK_V23_FORWARD_MODE2 */ 2100, 1300, 1200 }, + { /* FSK_V23_BACKWARD */ 450, 390, 75 }, + { /* FSK_BELL202 */ 2200, 1200, 1200 }, +}; + +/* + * dsp_fsk_attr_init + * + * Initializes the attributes structure; this must be done before the + * attributes structure is used. +*/ + +void dsp_fsk_attr_init (dsp_fsk_attr_t *attr) +{ + memset(attr, 0, sizeof(*attr)); +} + +/* + * dsp_fsk_attr_get_bithandler + * dsp_fsk_attr_set_bithandler + * dsp_fsk_attr_get_bytehandler + * dsp_fsk_attr_set_bytehandler + * dsp_fsk_attr_getsamplerate + * dsp_fsk_attr_setsamplerate + * + * These functions get and set their respective elements from the + * attributes structure. If an error code is returned, it is just + * zero == ok, -1 == fail. +*/ + +bithandler_func_t dsp_fsk_attr_get_bithandler(dsp_fsk_attr_t *attr, void **bithandler_arg) +{ + *bithandler_arg = attr->bithandler_arg; + return attr->bithandler; +} + +void dsp_fsk_attr_set_bithandler(dsp_fsk_attr_t *attr, bithandler_func_t bithandler, void *bithandler_arg) +{ + attr->bithandler = bithandler; + attr->bithandler_arg = bithandler_arg; +} + +bytehandler_func_t dsp_fsk_attr_get_bytehandler(dsp_fsk_attr_t *attr, void **bytehandler_arg) +{ + *bytehandler_arg = attr->bytehandler_arg; + return attr->bytehandler; +} + +void dsp_fsk_attr_set_bytehandler(dsp_fsk_attr_t *attr, bytehandler_func_t bytehandler, void *bytehandler_arg) +{ + attr->bytehandler = bytehandler; + attr->bytehandler_arg = bytehandler_arg; +} + +int dsp_fsk_attr_get_samplerate (dsp_fsk_attr_t *attr) +{ + return attr->sample_rate; +} + +int dsp_fsk_attr_set_samplerate (dsp_fsk_attr_t *attr, int samplerate) +{ + if (samplerate <= 0) { + return -1; + } + attr->sample_rate = samplerate; + return 0; +} + +/* + * dsp_fsk_create + * + * Creates a handle for subsequent use. The handle is created to contain + * a context data structure for use by the sample handler function. The + * function expects an initialized attributes structure, and returns the + * handle or a NULL if there were errors. + * + * Once created, the handle can be used until it is destroyed. +*/ + +dsp_fsk_handle_t *dsp_fsk_create(dsp_fsk_attr_t *attr) +{ + int i; + double phi_mark, phi_space; + dsp_fsk_handle_t *handle; + + handle = malloc(sizeof(*handle)); + if (!handle) { + return NULL; + } + + memset(handle, 0, sizeof(*handle)); + + /* fill the attributes member */ + memcpy(&handle->attr, attr, sizeof(*attr)); + + /* see if we can do downsampling. We only really need 6 samples to "match" */ + if (attr->sample_rate / fsk_modem_definitions[FSK_BELL202].freq_mark > 6) { + handle->downsampling_count = attr->sample_rate / fsk_modem_definitions[FSK_BELL202].freq_mark / 6; + } else { + handle->downsampling_count = 1; + } + handle->current_downsample = 1; + + /* calculate the correlate size (number of samples required for slowest wave) */ + handle->corrsize = attr->sample_rate / handle->downsampling_count / fsk_modem_definitions[FSK_BELL202].freq_mark; + + /* allocate the correlation sin/cos arrays and initialize */ + for (i = 0; i < 4; i++) { + handle->correlates[i] = malloc(sizeof(double) * handle->corrsize); + if (handle->correlates[i] == NULL) { + /* some failed, back out memory allocations */ + dsp_fsk_destroy(&handle); + return NULL; + } + } + + /* now initialize them */ + phi_mark = 2. * M_PI / ((double) attr->sample_rate / (double) handle->downsampling_count / (double) fsk_modem_definitions[FSK_BELL202].freq_mark); + phi_space = 2. * M_PI / ((double) attr->sample_rate / (double) handle->downsampling_count / (double) fsk_modem_definitions[FSK_BELL202].freq_space); + + for (i = 0; i < handle->corrsize; i++) { + handle->correlates[0][i] = sin(phi_mark * (double) i); + handle->correlates[1][i] = cos(phi_mark * (double) i); + handle->correlates[2][i] = sin(phi_space * (double) i); + handle->correlates[3][i] = cos(phi_space * (double) i); + } + + /* initialize the ring buffer */ + handle->buffer = malloc(sizeof(double) * handle->corrsize); + if (!handle->buffer) { /* failed; back out memory allocations */ + dsp_fsk_destroy(&handle); + return NULL; + } + memset(handle->buffer, 0, sizeof(double) * handle->corrsize); + handle->ringstart = 0; + + /* initalize intra-cell position */ + handle->cellpos = 0; + handle->celladj = fsk_modem_definitions[FSK_BELL202].baud_rate / (double) attr->sample_rate * (double) handle->downsampling_count; + + /* if they have provided a byte handler, add a UART to the processing chain */ + if (handle->attr.bytehandler) { + dsp_uart_attr_t uart_attr; + dsp_uart_handle_t *uart_handle; + + dsp_uart_attr_init(&uart_attr); + dsp_uart_attr_set_bytehandler(&uart_attr, handle->attr.bytehandler, handle->attr.bytehandler_arg); + uart_handle = dsp_uart_create(&uart_attr); + if (uart_handle == NULL) { + dsp_fsk_destroy(&handle); + return NULL; + } + handle->attr.bithandler = dsp_uart_bit_handler; + handle->attr.bithandler_arg = uart_handle; + } + + return handle; +} + +/* + * dsp_fsk_destroy + * + * Destroys a handle, releasing any associated memory. Sets handle pointer to NULL + * so A destroyed handle can not be used for anything after the destroy. +*/ + +void dsp_fsk_destroy(dsp_fsk_handle_t **handle) +{ + int i; + + /* if empty handle, just return */ + if (*handle == NULL) { + return; + } + + for (i = 0; i < 4; i++) { + if ((*handle)->correlates[i] != NULL) { + free((*handle)->correlates[i]); + (*handle)->correlates[i] = NULL; + } + } + + if ((*handle)->buffer != NULL) { + free((*handle)->buffer); + (*handle)->buffer = NULL; + } + + if ((*handle)->attr.bytehandler) { + dsp_uart_handle_t** dhandle = (void *)(&(*handle)->attr.bithandler_arg); + dsp_uart_destroy(dhandle); + } + + free(*handle); + *handle = NULL; +} + +/* + * dsp_fsk_sample + * + * This is the main processing entry point. The function accepts a normalized + * sample (i.e., one whose range is between -1 and +1). The function performs + * the Bell-202 FSK modem decode processing, and, if it detects a valid bit, + * will call the bithandler associated with the attributes structure. + * + * For the Bell-202 standard, a logical zero (space) is 2200 Hz, and a logical + * one (mark) is 1200 Hz. +*/ + +void +dsp_fsk_sample (dsp_fsk_handle_t *handle, double normalized_sample) +{ + double val; + double factors[4]; + int i, j; + + /* if we can avoid processing samples, do so */ + if (handle->downsampling_count != 1) { + if (handle->current_downsample < handle->downsampling_count) { + handle->current_downsample++; + return; /* throw this sample out */ + } + handle->current_downsample = 1; + } + + /* store sample in buffer */ + handle->buffer[handle->ringstart++] = normalized_sample; + if (handle->ringstart >= handle->corrsize) { + handle->ringstart = 0; + } + + /* do the correlation calculation */ + factors[0] = factors[1] = factors[2] = factors[3] = 0; /* clear out intermediate sums */ + j = handle->ringstart; + for (i = 0; i < handle->corrsize; i++) { + if (j >= handle->corrsize) { + j = 0; + } + val = handle->buffer[j]; + factors[0] += handle->correlates[0][i] * val; + factors[1] += handle->correlates[1][i] * val; + factors[2] += handle->correlates[2][i] * val; + factors[3] += handle->correlates[3][i] * val; + j++; + } + + /* store the bit (bit value is comparison of the two sets of correlate factors) */ + handle->previous_bit = handle->current_bit; + handle->current_bit = (factors[0] * factors[0] + factors[1] * factors[1] > factors[2] * factors[2] + factors[3] * factors[3]); + + /* if there's a transition, we can synchronize the cell position */ + if (handle->previous_bit != handle->current_bit) { + handle->cellpos = 0.5; /* adjust cell position to be in the middle of the cell */ + } + handle->cellpos += handle->celladj; /* walk the cell along */ + + if (handle->cellpos > 1.0) { + handle->cellpos -= 1.0; + + switch (handle->state) { + case FSK_STATE_DATA: + { + + (*handle->attr.bithandler) (handle->attr.bithandler_arg, handle->current_bit); + } + break; + case FSK_STATE_CHANSEIZE: + { + + if (handle->last_bit != handle->current_bit) { + handle->conscutive_state_bits++; + } else { + handle->conscutive_state_bits = 0; + } + + if (handle->conscutive_state_bits > 15) { + handle->state = FSK_STATE_CARRIERSIG; + handle->conscutive_state_bits = 0; + } + } + break; + case FSK_STATE_CARRIERSIG: + { + if (handle->current_bit) { + handle->conscutive_state_bits++; + } else { + handle->conscutive_state_bits = 0; + } + + if (handle->conscutive_state_bits > 15) { + handle->state = FSK_STATE_DATA; + handle->conscutive_state_bits = 0; + } + } + break; + } + + handle->last_bit = handle->current_bit; + } +} + diff --git a/src/mod/applications/mod_fsk/fsk.h b/src/mod/applications/mod_fsk/fsk.h new file mode 100644 index 0000000000..b098444d03 --- /dev/null +++ b/src/mod/applications/mod_fsk/fsk.h @@ -0,0 +1,113 @@ +/* + * bell202.h + * + * Copyright (c) 2005 Robert Krten. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This module contains the manifest constants and declarations for + * the Bell-202 1200 baud FSK modem. + * + * 2005 03 20 R. Krten created +*/ + +#ifndef __FSK_H__ +#define __FSK_H__ +#include "uart.h" + +typedef struct { + int freq_space; /* Frequency of the 0 bit */ + int freq_mark; /* Frequency of the 1 bit */ + int baud_rate; /* baud rate for the modem */ +} fsk_modem_definition_t; + +/* Must be kept in sync with fsk_modem_definitions array in fsk.c */ +/* V.23 definitions: http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-V.23 */ +typedef enum { + FSK_V23_FORWARD_MODE1 = 0, /* Maximum 600 bps for long haul */ + FSK_V23_FORWARD_MODE2, /* Standard 1200 bps V.23 */ + FSK_V23_BACKWARD, /* 75 bps return path for V.23 */ + FSK_BELL202 /* Bell 202 half-duplex 1200 bps */ +} fsk_modem_types_t; + +typedef enum { + FSK_STATE_CHANSEIZE = 0, + FSK_STATE_CARRIERSIG, + FSK_STATE_DATA +} fsk_state_t; + +typedef struct dsp_fsk_attr_s +{ + int sample_rate; /* sample rate in HZ */ + bithandler_func_t bithandler; /* bit handler */ + void *bithandler_arg; /* arbitrary ID passed to bithandler as first argument */ + bytehandler_func_t bytehandler; /* byte handler */ + void *bytehandler_arg; /* arbitrary ID passed to bytehandler as first argument */ +} dsp_fsk_attr_t; + +typedef struct +{ + fsk_state_t state; + dsp_fsk_attr_t attr; /* attributes structure */ + double *correlates[4]; /* one for each of sin/cos for mark/space */ + int corrsize; /* correlate size (also number of samples in ring buffer) */ + double *buffer; /* sample ring buffer */ + int ringstart; /* ring buffer start offset */ + double cellpos; /* bit cell position */ + double celladj; /* bit cell adjustment for each sample */ + int previous_bit; /* previous bit (for detecting a transition to sync-up cell position) */ + int current_bit; /* current bit */ + int last_bit; + int downsampling_count; /* number of samples to skip */ + int current_downsample; /* current skip count */ + int conscutive_state_bits; /* number of bits in a row that matches the pattern for the current state */ +} dsp_fsk_handle_t; + +/* + * Function prototypes + * + * General calling order is: + * a) create the attributes structure (dsp_fsk_attr_init) + * b) initialize fields in the attributes structure (dsp_fsk_attr_set_*) + * c) create a Bell-202 handle (dsp_fsk_create) + * d) feed samples through the handler (dsp_fsk_sample) +*/ + +void dsp_fsk_attr_init(dsp_fsk_attr_t *attributes); + +bithandler_func_t dsp_fsk_attr_get_bithandler(dsp_fsk_attr_t *attributes, void **bithandler_arg); +void dsp_fsk_attr_set_bithandler(dsp_fsk_attr_t *attributes, bithandler_func_t bithandler, void *bithandler_arg); +bytehandler_func_t dsp_fsk_attr_get_bytehandler(dsp_fsk_attr_t *attributes, void **bytehandler_arg); +void dsp_fsk_attr_set_bytehandler(dsp_fsk_attr_t *attributes, bytehandler_func_t bytehandler, void *bytehandler_arg); +int dsp_fsk_attr_get_samplerate(dsp_fsk_attr_t *attributes); +int dsp_fsk_attr_set_samplerate(dsp_fsk_attr_t *attributes, int samplerate); + +dsp_fsk_handle_t * dsp_fsk_create(dsp_fsk_attr_t *attributes); +void dsp_fsk_destroy(dsp_fsk_handle_t **handle); + +void dsp_fsk_sample(dsp_fsk_handle_t *handle, double normalized_sample); + +extern fsk_modem_definition_t fsk_modem_definitions[]; + +#endif + diff --git a/src/mod/applications/mod_fsk/fsk_callerid.c b/src/mod/applications/mod_fsk/fsk_callerid.c new file mode 100644 index 0000000000..2146f663c5 --- /dev/null +++ b/src/mod/applications/mod_fsk/fsk_callerid.c @@ -0,0 +1,398 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * mod_fsk -- FSK data transfer + * + */ + +#include "switch.h" +#include "fsk_callerid.h" + +void bitstream_init(bitstream_t *bsp, uint8_t *data, uint32_t datalen, endian_t endian, uint8_t ss) +{ + memset(bsp, 0, sizeof(*bsp)); + bsp->data = data; + bsp->datalen = datalen; + bsp->endian = endian; + bsp->ss = ss; + + if (endian < 0) { + bsp->top = bsp->bit_index = 7; + bsp->bot = 0; + } else { + bsp->top = bsp->bit_index = 0; + bsp->bot = 7; + } + +} + +int8_t bitstream_get_bit(bitstream_t *bsp) +{ + int8_t bit = -1; + + + if (bsp->byte_index >= bsp->datalen) { + goto done; + } + + if (bsp->ss) { + if (!bsp->ssv) { + bsp->ssv = 1; + return 0; + } else if (bsp->ssv == 2) { + bsp->byte_index++; + bsp->ssv = 0; + return 1; + } + } + + bit = (bsp->data[bsp->byte_index] >> (bsp->bit_index)) & 1; + + if (bsp->bit_index == bsp->bot) { + bsp->bit_index = bsp->top; + if (bsp->ss) { + bsp->ssv = 2; + goto done; + } + + if (++bsp->byte_index > bsp->datalen) { + bit = -1; + goto done; + } + + } else { + bsp->bit_index = bsp->bit_index + bsp->endian; + } + + + done: + return bit; +} + + + +static void fsk_byte_handler (void *x, int data) +{ + fsk_data_state_t *state = (fsk_data_state_t *) x; + uint8_t byte = (uint8_t)data; + + top: + + if (state->init == 3) { + return; + } + + if (state->dlen) { + goto add_byte; + } + + if (state->bpos == 1) { + state->blen = byte; + + if ((uint32_t)(state->dlen = state->bpos + byte + 2) > state->bufsize) { + state->dlen = state->bufsize; + } + goto top; + } + + add_byte: + + if (state->bpos <= state->dlen) { + state->buf[state->bpos++] = byte; + } else { + state->init = 3; + } +} + +switch_status_t fsk_data_init(fsk_data_state_t *state, uint8_t *data, uint32_t datalen) +{ + memset(state, 0, sizeof(*state)); + state->buf = data; + state->bufsize = datalen; + state->bpos = 2; + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t fsk_data_add_sdmf(fsk_data_state_t *state, const char *date, char *number) +{ + size_t dlen = strlen(date); + size_t nlen = strlen(number); + + state->buf[0] = CID_TYPE_SDMF; + memcpy(&state->buf[state->bpos], date, dlen); + state->bpos += dlen; + memcpy(&state->buf[state->bpos], number, nlen); + state->bpos += nlen; + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t fsk_data_add_mdmf(fsk_data_state_t *state, mdmf_type_t type, const uint8_t *data, uint32_t datalen) +{ + state->buf[0] = CID_TYPE_MDMF; + state->buf[state->bpos++] = type; + state->buf[state->bpos++] = (uint8_t)datalen; + memcpy(&state->buf[state->bpos], data, datalen); + state->bpos += datalen; + return SWITCH_STATUS_SUCCESS; +} + + +switch_status_t fsk_data_add_checksum(fsk_data_state_t *state) +{ + uint32_t i; + uint8_t check = 0; + + state->buf[1] = (uint8_t)(state->bpos - 2); + + for (i = 0; i < state->bpos; i++) { + check = check + state->buf[i]; + } + + state->checksum = state->buf[state->bpos] = (uint8_t)(256 - check); + state->bpos++; + + state->dlen = state->bpos; + state->blen = state->buf[1]; + + return SWITCH_STATUS_SUCCESS; +} + + +switch_status_t fsk_data_parse(fsk_data_state_t *state, size_t *type, char **data, size_t *len) +{ + + size_t i; + int sum = 0; + + top: + + if (state->checksum != 0 || state->ppos >= state->dlen - 1) { + return SWITCH_STATUS_FALSE; + } + + if (!state->ppos) { + for(i = 0; i < state->bpos; i++) { + sum += state->buf[i]; + } + state->checksum = sum % 256; + state->ppos = 2; + + if (state->buf[0] != CID_TYPE_MDMF && state->buf[0] != CID_TYPE_SDMF) { + state->checksum = -1; + } + goto top; + } + + if (state->buf[0] == CID_TYPE_SDMF) { + /* convert sdmf to mdmf so we don't need 2 parsers */ + if (state->ppos == 2) { + *type = MDMF_DATETIME; + *len = 8; + } else { + if (state->buf[state->ppos] == 'P' || state->buf[state->ppos] == 'O') { + *type = MDMF_NO_NUM; + *len = 1; + } else { + *type = MDMF_PHONE_NUM; + *len = state->blen - 8; + } + } + *data = (char *)&state->buf[state->ppos]; + state->ppos += *len; + return SWITCH_STATUS_SUCCESS; + } else if (state->buf[0] == CID_TYPE_MDMF) { + *type = state->buf[state->ppos++]; + *len = state->buf[state->ppos++]; + *data = (char *)&state->buf[state->ppos]; + state->ppos += *len; + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +switch_status_t fsk_demod_feed(fsk_data_state_t *state, int16_t *data, size_t samples) +{ + uint32_t x; + int16_t *sp = data; + + if (state->init == 3) { + return SWITCH_STATUS_FALSE; + } + + for (x = 0; x < samples; x++) { + dsp_fsk_sample (state->fsk1200_handle, (double) *sp++ / 32767.0); + if (state->dlen && state->bpos >= state->dlen) { + state->init = 3; + return SWITCH_STATUS_FALSE; + } + } + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t fsk_demod_destroy(fsk_data_state_t *state) +{ + dsp_fsk_destroy(&state->fsk1200_handle); + memset(state, 0, sizeof(*state)); + return SWITCH_STATUS_SUCCESS; +} + +int fsk_demod_init(fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize) +{ + + dsp_fsk_attr_t fsk1200_attr; + + if (state->fsk1200_handle) { + dsp_fsk_destroy(&state->fsk1200_handle); + } + + memset(state, 0, sizeof(*state)); + memset(buf, 0, bufsize); + state->buf = buf; + state->bufsize = bufsize; + + dsp_fsk_attr_init (&fsk1200_attr); + dsp_fsk_attr_set_samplerate (&fsk1200_attr, rate); + dsp_fsk_attr_set_bytehandler (&fsk1200_attr, fsk_byte_handler, state); + state->fsk1200_handle = dsp_fsk_create (&fsk1200_attr); + + if (state->fsk1200_handle == NULL) { + return SWITCH_STATUS_FALSE; + } + + return SWITCH_STATUS_SUCCESS; +} + +size_t fsk_modulator_generate_bit(fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, size_t buflen) +{ + size_t i; + + for(i = 0 ; i < buflen; i++) { + fsk_trans->bit_accum += fsk_trans->bit_factor; + if (fsk_trans->bit_accum >= FSK_MOD_FACTOR) { + fsk_trans->bit_accum -= (FSK_MOD_FACTOR + fsk_trans->bit_factor); + break; + } + + buf[i] = teletone_dds_state_modulate_sample(&fsk_trans->dds, bit); + } + + return i; +} + + +int32_t fsk_modulator_generate_carrier_bits(fsk_modulator_t *fsk_trans, uint32_t bits) +{ + uint32_t i = 0; + size_t r = 0; + int8_t bit = 1; + + for (i = 0; i < bits; i++) { + if ((r = fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { + if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != SWITCH_STATUS_SUCCESS) { + break; + } + } else { + break; + } + } + + return i; +} + + +void fsk_modulator_generate_chan_sieze(fsk_modulator_t *fsk_trans) +{ + uint32_t i = 0; + size_t r = 0; + int8_t bit = 0; + + for (i = 0; i < fsk_trans->chan_sieze_bits; i++) { + if ((r = fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { + if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != SWITCH_STATUS_SUCCESS) { + break; + } + } else { + break; + } + bit = !bit; + } + + +} + + +void fsk_modulator_send_data(fsk_modulator_t *fsk_trans) +{ + size_t r = 0; + int8_t bit = 0; + + while((bit = bitstream_get_bit(&fsk_trans->bs)) > -1) { + if ((r = fsk_modulator_generate_bit(fsk_trans, bit, fsk_trans->sample_buffer, sizeof(fsk_trans->sample_buffer) / 2))) { + if (fsk_trans->write_sample_callback(fsk_trans->sample_buffer, r, fsk_trans->user_data) != SWITCH_STATUS_SUCCESS) { + break; + } + } else { + break; + } + } +} + + +switch_status_t fsk_modulator_init(fsk_modulator_t *fsk_trans, + fsk_modem_types_t modem_type, + uint32_t sample_rate, + fsk_data_state_t *fsk_data, + float db_level, + uint32_t carrier_bits_start, + uint32_t carrier_bits_stop, + uint32_t chan_sieze_bits, + fsk_write_sample_t write_sample_callback, + void *user_data) +{ + memset(fsk_trans, 0, sizeof(*fsk_trans)); + fsk_trans->modem_type = modem_type; + teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_space, sample_rate, 0); + teletone_dds_state_set_tone(&fsk_trans->dds, fsk_modem_definitions[fsk_trans->modem_type].freq_mark, sample_rate, 1); + fsk_trans->bit_factor = (uint32_t)((fsk_modem_definitions[fsk_trans->modem_type].baud_rate * FSK_MOD_FACTOR) / (float)sample_rate); + fsk_trans->samples_per_bit = (uint32_t) (sample_rate / fsk_modem_definitions[fsk_trans->modem_type].baud_rate); + fsk_trans->est_bytes = (int32_t)(((fsk_data->dlen * 10) + carrier_bits_start + carrier_bits_stop + chan_sieze_bits) * ((fsk_trans->samples_per_bit + 1) * 2)); + fsk_trans->bit_accum = 0; + fsk_trans->fsk_data = fsk_data; + teletone_dds_state_set_tx_level(&fsk_trans->dds, db_level); + bitstream_init(&fsk_trans->bs, fsk_trans->fsk_data->buf, (uint32_t)fsk_trans->fsk_data->dlen, ENDIAN_BIG, 1); + fsk_trans->carrier_bits_start = carrier_bits_start; + fsk_trans->carrier_bits_stop = carrier_bits_stop; + fsk_trans->chan_sieze_bits = chan_sieze_bits; + fsk_trans->write_sample_callback = write_sample_callback; + fsk_trans->user_data = user_data; + return SWITCH_STATUS_SUCCESS; +} + diff --git a/src/mod/applications/mod_fsk/fsk_callerid.h b/src/mod/applications/mod_fsk/fsk_callerid.h new file mode 100644 index 0000000000..9018201ce5 --- /dev/null +++ b/src/mod/applications/mod_fsk/fsk_callerid.h @@ -0,0 +1,144 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * mod_fsk -- FSK data transfer + * + */ +#ifndef __FSK_CALLER_ID_H +#define __FSK_CALLER_ID_H +SWITCH_BEGIN_EXTERN_C +#include "fsk.h" +#include "uart.h" + +#define FSK_MOD_FACTOR 0x10000 + +typedef enum { + ENDIAN_BIG = 1, + ENDIAN_LITTLE = -1 +} endian_t; + +typedef enum { + CID_TYPE_SDMF = 0x04, + CID_TYPE_MDMF = 0x80 +} cid_type_t; + +typedef enum { + MDMF_DATETIME = 1, + MDMF_PHONE_NUM = 2, + MDMF_DDN = 3, + MDMF_NO_NUM = 4, + MDMF_PHONE_NAME = 7, + MDMF_NO_NAME = 8, + MDMF_ALT_ROUTE = 9, + MDMF_NAME_VALUE = 10, + MDMF_INVALID = 11 +} mdmf_type_t; + +struct bitstream { + uint8_t *data; + uint32_t datalen; + uint32_t byte_index; + uint8_t bit_index; + int8_t endian; + uint8_t top; + uint8_t bot; + uint8_t ss; + uint8_t ssv; +}; + +struct fsk_data_state { + dsp_fsk_handle_t *fsk1200_handle; + uint8_t init; + uint8_t *buf; + size_t bufsize; + size_t blen; + size_t bpos; + size_t dlen; + size_t ppos; + int checksum; +}; + +typedef struct bitstream bitstream_t; +typedef struct fsk_data_state fsk_data_state_t; +typedef switch_status_t (*fsk_write_sample_t)(int16_t *buf, size_t buflen, void *user_data); + +struct fsk_modulator { + teletone_dds_state_t dds; + bitstream_t bs; + uint32_t carrier_bits_start; + uint32_t carrier_bits_stop; + uint32_t chan_sieze_bits; + uint32_t bit_factor; + uint32_t bit_accum; + uint32_t sample_counter; + int32_t samples_per_bit; + int32_t est_bytes; + fsk_modem_types_t modem_type; + fsk_data_state_t *fsk_data; + fsk_write_sample_t write_sample_callback; + void *user_data; + int16_t sample_buffer[64]; +}; + + +typedef int (*fsk_data_decoder_t)(fsk_data_state_t *state); + +typedef void (*logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...); +typedef struct fsk_modulator fsk_modulator_t; + +switch_status_t fsk_data_init(fsk_data_state_t *state, uint8_t *data, uint32_t datalen); +void bitstream_init(bitstream_t *bsp, uint8_t *data, uint32_t datalen, endian_t endian, uint8_t ss); +int8_t bitstream_get_bit(bitstream_t *bsp); +switch_status_t fsk_data_add_mdmf(fsk_data_state_t *state, mdmf_type_t type, const uint8_t *data, uint32_t datalen); +switch_status_t fsk_data_add_checksum(fsk_data_state_t *state); +switch_status_t fsk_data_parse(fsk_data_state_t *state, size_t *type, char **data, size_t *len); +switch_status_t fsk_demod_feed(fsk_data_state_t *state, int16_t *data, size_t samples); +switch_status_t fsk_demod_destroy(fsk_data_state_t *state); +int fsk_demod_init(fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize); +size_t fsk_modulator_generate_bit(fsk_modulator_t *fsk_trans, int8_t bit, int16_t *buf, size_t buflen); +int32_t fsk_modulator_generate_carrier_bits(fsk_modulator_t *fsk_trans, uint32_t bits); +void fsk_modulator_generate_chan_sieze(fsk_modulator_t *fsk_trans); +void fsk_modulator_send_data(fsk_modulator_t *fsk_trans); +switch_status_t fsk_modulator_init(fsk_modulator_t *fsk_trans, + fsk_modem_types_t modem_type, + uint32_t sample_rate, + fsk_data_state_t *fsk_data, + float db_level, + uint32_t carrier_bits_start, + uint32_t carrier_bits_stop, + uint32_t chan_sieze_bits, + fsk_write_sample_t write_sample_callback, + void *user_data); + + +#define fsk_modulator_send_all(_it) fsk_modulator_generate_chan_sieze(_it); \ + fsk_modulator_generate_carrier_bits(_it, _it->carrier_bits_start); \ + fsk_modulator_send_data(_it); \ + fsk_modulator_generate_carrier_bits(_it, _it->carrier_bits_stop) + +SWITCH_END_EXTERN_C +#endif diff --git a/src/mod/applications/mod_fsk/mod_fsk.c b/src/mod/applications/mod_fsk/mod_fsk.c new file mode 100644 index 0000000000..9802353075 --- /dev/null +++ b/src/mod/applications/mod_fsk/mod_fsk.c @@ -0,0 +1,486 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * mod_fsk.c -- FSK data transfer + * + */ +#include +#include "fsk_callerid.h" + +/* Prototypes */ +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fsk_shutdown); +SWITCH_MODULE_RUNTIME_FUNCTION(mod_fsk_runtime); +SWITCH_MODULE_LOAD_FUNCTION(mod_fsk_load); + +/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime) + * Defines a switch_loadable_module_function_table_t and a static const char[] modname + */ +SWITCH_MODULE_DEFINITION(mod_fsk, mod_fsk_load, mod_fsk_shutdown, NULL); + +switch_status_t my_write_sample(int16_t *buf, size_t buflen, void *user_data) +{ + switch_buffer_t *buffer = (switch_buffer_t *) user_data; + + switch_buffer_write(buffer, buf, buflen * 2); + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t write_fsk_data(uint32_t rate, int32_t db, switch_buffer_t *buffer, switch_event_t *event, const char *prefix) +{ + fsk_modulator_t fsk_trans; + fsk_data_state_t fsk_data = {0}; + uint8_t databuf[1024] = ""; + char time_str[9]; + struct tm tm; + time_t now; + switch_event_header_t *hp; + switch_size_t plen = 0; + + memset(&fsk_trans, 0, sizeof(fsk_trans)); + + time(&now); + localtime_r(&now, &tm); + strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm); + + fsk_data_init(&fsk_data, databuf, sizeof(databuf)); + fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *)time_str, strlen(time_str)); + + if (prefix) { + plen = strlen(prefix); + } + + + if (event) { + for (hp = event->headers; hp; hp = hp->next) { + char *packed; + char *name = hp->name; + + if (plen && strncasecmp(name, prefix, plen)) { + continue; + } + + name += plen; + + if (zstr(name)) { + continue; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding [%s][%s]\n", hp->name, hp->value); + + if (!strcasecmp(name, "phone_num")) { + fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NUM, (uint8_t *)hp->value, strlen(hp->value)); + } else if (!strcasecmp(name, "phone_name")) { + fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NAME, (uint8_t *)hp->value, strlen(hp->value)); + } else { + packed = switch_mprintf("%q:%q", name, hp->value); + fsk_data_add_mdmf(&fsk_data, MDMF_NAME_VALUE, (uint8_t *)packed, strlen(packed)); + free(packed); + } + } + } + + fsk_data_add_checksum(&fsk_data); + + fsk_modulator_init(&fsk_trans, FSK_BELL202, rate, &fsk_data, db, 180, 5, 300, my_write_sample, buffer); + fsk_modulator_send_all((&fsk_trans)); + + fsk_demod_destroy(&fsk_data); + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_STANDARD_APP(fsk_send_function) { + switch_event_t *event = NULL; + switch_buffer_t *buffer; + switch_slin_data_t sdata = { 0 }; + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_frame_t *read_frame; + switch_status_t status; + + + if (data) { + switch_ivr_sleep(session, 1000, SWITCH_TRUE, NULL); + switch_core_session_send_dtmf_string(session, (const char *) data); + switch_ivr_sleep(session, 1500, SWITCH_TRUE, NULL); + } + + if (switch_core_session_set_codec_slin(session, &sdata) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_ERROR, "FAILURE\n"); + return; + } + + switch_buffer_create_dynamic(&buffer, 1024, 2048, 0); + + switch_channel_get_variables(channel, &event); + + write_fsk_data(sdata.codec.implementation->actual_samples_per_second, -14, buffer, event, "fsk_"); + + while(switch_channel_ready(channel)) { + status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + + if ((sdata.write_frame.datalen = switch_buffer_read(buffer, sdata.write_frame.data, + sdata.codec.implementation->decoded_bytes_per_packet)) <= 0) { + break; + } + + + if (sdata.write_frame.datalen < sdata.codec.implementation->decoded_bytes_per_packet) { + memset((char *)sdata.write_frame.data + sdata.write_frame.datalen, 255, + sdata.codec.implementation->decoded_bytes_per_packet - sdata.write_frame.datalen); + sdata.write_frame.datalen = sdata.codec.implementation->decoded_bytes_per_packet; + } + sdata.write_frame.samples = sdata.write_frame.datalen / 2; + switch_core_session_write_frame(sdata.session, &sdata.write_frame, SWITCH_IO_FLAG_NONE, 0); + } + + switch_buffer_destroy(&buffer); + switch_core_codec_destroy(&sdata.codec); + switch_core_session_set_read_codec(session, NULL); + +} + +typedef struct { + switch_core_session_t *session; + fsk_data_state_t fsk_data; + uint8_t fbuf[512]; + int skip; +} switch_fsk_detect_t; + + + + +static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +{ + switch_fsk_detect_t *pvt = (switch_fsk_detect_t *) user_data; + //switch_frame_t *frame = NULL; + switch_channel_t *channel = switch_core_session_get_channel(pvt->session); + + switch (type) { + case SWITCH_ABC_TYPE_INIT: { + switch_codec_implementation_t read_impl = { 0 }; + switch_core_session_get_read_impl(pvt->session, &read_impl); + + if (fsk_demod_init(&pvt->fsk_data, read_impl.actual_samples_per_second, pvt->fbuf, sizeof(pvt->fbuf))) { + return SWITCH_FALSE; + } + + break; + } + case SWITCH_ABC_TYPE_CLOSE: + { + fsk_demod_destroy(&pvt->fsk_data); + } + break; + + case SWITCH_ABC_TYPE_WRITE_REPLACE: + case SWITCH_ABC_TYPE_READ_REPLACE: + { + switch_frame_t *rframe; + + if (type == SWITCH_ABC_TYPE_READ_REPLACE) { + rframe = switch_core_media_bug_get_read_replace_frame(bug); + } else { + rframe = switch_core_media_bug_get_write_replace_frame(bug); + } + + if (!pvt->skip && fsk_demod_feed(&pvt->fsk_data, rframe->data, rframe->datalen / 2) != SWITCH_STATUS_SUCCESS) { + char str[1024] = ""; + size_t type, mlen; + char *sp; + switch_event_t *event; + const char *app_var; + + switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA); + + while(fsk_data_parse(&pvt->fsk_data, &type, &sp, &mlen) == SWITCH_STATUS_SUCCESS) { + char *varname = NULL, *val, *p; + + switch_copy_string(str, sp, mlen+1); + *(str+mlen) = '\0'; + switch_clean_string(str); + //printf("TYPE %u LEN %u VAL [%s]\n", (unsigned)type, (unsigned)mlen, str); + + val = str; + + switch(type) { + case MDMF_DATETIME: + varname = "fsk_datetime"; + break; + case MDMF_PHONE_NAME: + varname = "fsk_phone_name"; + break; + case MDMF_PHONE_NUM: + varname = "fsk_phone_num"; + break; + case MDMF_NAME_VALUE: + varname = switch_core_session_sprintf(pvt->session, "fsk_%s", val); + if ((p = strchr(varname, ':'))) { + *p++ = '\0'; + val = p; + } + break; + default: + break; + } + + if (varname && val) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n", + switch_channel_get_name(channel), varname, val); + switch_channel_set_variable(channel, varname, val); + if (event) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, varname, val); + } + } + } + + if (event) { + if (switch_core_session_queue_event(pvt->session, &event) != SWITCH_STATUS_SUCCESS) { + switch_event_destroy(&event); + } + } + + if ((app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) { + char *app_arg; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n", + switch_channel_get_name(channel), app_var); + if ((app_arg = strchr(app_var, ' '))) { + *app_arg++ = '\0'; + } + switch_core_session_execute_application(pvt->session, app_var, app_arg); + } + + pvt->skip = 10; + } + + memset(rframe->data, 255, rframe->datalen); + + if (type == SWITCH_ABC_TYPE_READ_REPLACE) { + switch_core_media_bug_set_read_replace_frame(bug, rframe); + } else { + switch_core_media_bug_set_write_replace_frame(bug, rframe); + } + + if (pvt->skip && !--pvt->skip) { + return SWITCH_FALSE; + } + + } + break; + case SWITCH_ABC_TYPE_WRITE: + default: + break; + } + + return SWITCH_TRUE; +} + +switch_status_t stop_fsk_detect_session(switch_core_session_t *session) +{ + switch_media_bug_t *bug; + switch_channel_t *channel = switch_core_session_get_channel(session); + + if ((bug = switch_channel_get_private(channel, "fsk"))) { + switch_channel_set_private(channel, "fsk", NULL); + switch_core_media_bug_remove(session, &bug); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + +switch_status_t fsk_detect_session(switch_core_session_t *session, const char *flags) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_media_bug_t *bug; + switch_status_t status; + switch_fsk_detect_t *pvt = { 0 }; + switch_codec_implementation_t read_impl = { 0 }; + int bflags = SMBF_READ_REPLACE; + + if (strchr(flags, 'w')) { + bflags = SMBF_WRITE_REPLACE; + } + + switch_core_session_get_read_impl(session, &read_impl); + + if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) { + return SWITCH_STATUS_MEMERR; + } + + pvt->session = session; + + + if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + + if ((status = switch_core_media_bug_add(session, "fsk_detect", NULL, + fsk_detect_callback, pvt, 0, bflags | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) { + return status; + } + + switch_channel_set_private(channel, "fsk", bug); + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_STANDARD_APP(fsk_recv_function) +{ + fsk_detect_session(session, data); +} + +SWITCH_STANDARD_APP(fsk_display_function) +{ + /* expected to be called via 'execute_on_fsk' -- passes display update over FSK */ + + const char *cid_name, *cid_num; + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_core_session_message_t *msg; + switch_core_session_t *psession, *usession = NULL; + char *flags = (char *) data; + + cid_name = switch_channel_get_variable(channel, "fsk_phone_name"); + cid_num = switch_channel_get_variable(channel, "fsk_phone_num"); + + if (zstr(cid_name)) { + cid_name = cid_num; + } + + if (zstr(cid_num)) { + return; + } + + if (strchr(flags, 'b')) { + if (switch_core_session_get_partner(session, &psession) == SWITCH_STATUS_SUCCESS) { + usession = psession; + } + } + + if (!usession) { + usession = session; + } + + msg = switch_core_session_alloc(usession, sizeof(*msg)); + MESSAGE_STAMP_FFL(msg); + msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY; + msg->string_array_arg[0] = switch_core_session_strdup(usession, cid_name); + msg->string_array_arg[1] = switch_core_session_strdup(usession, cid_num); + msg->from = __FILE__; + switch_core_session_queue_message(usession, msg); + + if (psession) { + switch_core_session_rwunlock(psession); + psession = NULL; + } +} + +SWITCH_STANDARD_APP(fsk_simplify_function) +{ + /* expected to be called via 'execute_on_fsk' -- redirects call to point-to-point and eliminates legs in the middle */ + switch_channel_t *channel = switch_core_session_get_channel(session); + const char *sip_uri, *fsk_simplify_profile, *fsk_simplify_context; + char *bridgeto; + + if (!(sip_uri = switch_channel_get_variable(channel, "fsk_uri"))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Missing URI field!\n", switch_channel_get_name(channel)); + } + + if (!(fsk_simplify_profile = switch_channel_get_variable(channel, "fsk_simplify_profile"))) { + fsk_simplify_profile = "internal"; + } + + fsk_simplify_context = switch_channel_get_variable(channel, "fsk_simplify_context"); + + if (!zstr(sip_uri)) { + switch_core_session_t *psession; + switch_channel_t *pchannel; + + bridgeto = switch_core_session_sprintf(session, "bridge:sofia/%s/sip:%s", fsk_simplify_profile, sip_uri); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s transfering to [%s]\n", + switch_channel_get_name(channel), bridgeto); + + + if (switch_core_session_get_partner(session, &psession) == SWITCH_STATUS_SUCCESS) { + pchannel = switch_core_session_get_channel(psession); + switch_channel_set_flag(pchannel, CF_REDIRECT); + switch_channel_set_flag(pchannel, CF_TRANSFER); + } + + switch_ivr_session_transfer(session, bridgeto, "inline", fsk_simplify_context); + + if (psession) { + switch_ivr_session_transfer(psession, "sleep:5000", "inline", NULL); + switch_core_session_rwunlock(psession); + } + } +} + +/* Macro expands to: switch_status_t mod_fsk_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */ +SWITCH_MODULE_LOAD_FUNCTION(mod_fsk_load) +{ + switch_application_interface_t *app_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_APP(app_interface, "fsk_send", "fsk_send", NULL, fsk_send_function, NULL, SAF_NONE); + SWITCH_ADD_APP(app_interface, "fsk_recv", "fsk_recv", NULL, fsk_recv_function, NULL, SAF_NONE); + SWITCH_ADD_APP(app_interface, "fsk_simplify", "fsk_simplify", NULL, fsk_simplify_function, NULL, SAF_NONE); + SWITCH_ADD_APP(app_interface, "fsk_display", "fsk_display", NULL, fsk_display_function, NULL, SAF_NONE); + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* + Called when the system shuts down + Macro expands to: switch_status_t mod_fsk_shutdown() */ +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fsk_shutdown) +{ + /* Cleanup dynamically allocated config settings */ + + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 + */ diff --git a/src/mod/applications/mod_fsk/uart.c b/src/mod/applications/mod_fsk/uart.c new file mode 100644 index 0000000000..5e0dd85350 --- /dev/null +++ b/src/mod/applications/mod_fsk/uart.c @@ -0,0 +1,124 @@ + +/* + * uart.c + * + * Copyright (c) 2005 Robert Krten. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This module contains a simple 8-bit UART, which performs a callback + * with the decoded byte value. + * + * 2005 06 11 R. Krten created +*/ + +#include +#include +#include +#include + +#include "uart.h" + +/* + * dsp_uart_attr_init + * + * Initializes the attributes structure; this must be done before the + * attributes structure is used. +*/ + +void dsp_uart_attr_init (dsp_uart_attr_t *attr) +{ + memset (attr, 0, sizeof (*attr)); +} + +/* + * dsp_uart_attr_get_bytehandler + * dsp_uart_attr_set_bytehandler + * + * These functions get and set their respective elements from the + * attributes structure. If an error code is returned, it is just + * zero == ok, -1 == fail. +*/ + +bytehandler_func_t dsp_uart_attr_get_bytehandler(dsp_uart_attr_t *attr, void **bytehandler_arg) +{ + *bytehandler_arg = attr->bytehandler_arg; + return attr->bytehandler; +} + +void dsp_uart_attr_set_bytehandler(dsp_uart_attr_t *attr, bytehandler_func_t bytehandler, void *bytehandler_arg) +{ + attr->bytehandler = bytehandler; + attr->bytehandler_arg = bytehandler_arg; +} + +dsp_uart_handle_t *dsp_uart_create(dsp_uart_attr_t *attr) +{ + dsp_uart_handle_t *handle; + + handle = malloc(sizeof (*handle)); + if (handle) { + memset(handle, 0, sizeof (*handle)); + + /* fill the attributes member */ + memcpy(&handle->attr, attr, sizeof (*attr)); + } + return handle; +} + +void dsp_uart_destroy(dsp_uart_handle_t **handle) +{ + if (*handle) { + free(*handle); + *handle = NULL; + } +} + + +void dsp_uart_bit_handler(void *x, int bit) +{ + dsp_uart_handle_t *handle = (dsp_uart_handle_t *) x; + + if (!handle->have_start) { + if (bit) { + return; /* waiting for start bit (0) */ + } + handle->have_start = 1; + handle->data = 0; + handle->nbits = 0; + return; + } + + handle->data >>= 1; + handle->data |= 0x80 * !!bit; + handle->nbits++; + + if (handle->nbits == 8) { + handle->attr.bytehandler(handle->attr.bytehandler_arg, handle->data); + handle->nbits = 0; + handle->data = 0; + handle->have_start = 0; + } +/* might consider handling errors in the future... */ +} + diff --git a/src/mod/applications/mod_fsk/uart.h b/src/mod/applications/mod_fsk/uart.h new file mode 100644 index 0000000000..89c3a13abc --- /dev/null +++ b/src/mod/applications/mod_fsk/uart.h @@ -0,0 +1,76 @@ +/* + * uart.h + * + * Copyright (c) 2005 Robert Krten. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This module contains the manifest constants and declarations for + * the UART module. + * + * 2005 06 19 R. Krten created +*/ + +#ifndef __UART_H__ +#define __UART_H__ + +typedef void (*bytehandler_func_t) (void *, int); +typedef void (*bithandler_func_t) (void *, int); + + +typedef struct dsp_uart_attr_s +{ + bytehandler_func_t bytehandler; /* byte handler */ + void *bytehandler_arg; /* arbitrary ID passed to bytehandler as first argument */ +} dsp_uart_attr_t; + +typedef struct +{ + dsp_uart_attr_t attr; + int have_start; /* wait for start bit to show up */ + int data; /* data buffer */ + int nbits; /* number of bits accumulated so far */ +} dsp_uart_handle_t; + +/* + * Function prototypes + * + * General calling order is: + * a) create the attributes structure (dsp_uart_attr_init) + * b) initialize fields in the attributes structure (dsp_uart_attr_set_*) + * c) create a Bell-202 handle (dsp_uart_create) + * d) feed bits through dsp_uart_bit_handler +*/ + +void dsp_uart_attr_init(dsp_uart_attr_t *attributes); + +bytehandler_func_t dsp_uart_attr_get_bytehandler(dsp_uart_attr_t *attributes, void **bytehandler_arg); +void dsp_uart_attr_set_bytehandler(dsp_uart_attr_t *attributes, bytehandler_func_t bytehandler, void *bytehandler_arg); + +dsp_uart_handle_t * dsp_uart_create(dsp_uart_attr_t *attributes); +void dsp_uart_destroy(dsp_uart_handle_t **handle); + +void dsp_uart_bit_handler(void *handle, int bit); + +#endif + diff --git a/src/mod/applications/mod_fsv/mod_fsv.c b/src/mod/applications/mod_fsv/mod_fsv.c index 200706c4e7..7b59796d99 100644 --- a/src/mod/applications/mod_fsv/mod_fsv.c +++ b/src/mod/applications/mod_fsv/mod_fsv.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_hash/mod_hash.c b/src/mod/applications/mod_hash/mod_hash.c index 2609b6cb87..e3f01cec96 100644 --- a/src/mod/applications/mod_hash/mod_hash.c +++ b/src/mod/applications/mod_hash/mod_hash.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -263,10 +263,14 @@ SWITCH_HASH_DELETE_FUNC(limit_hash_remote_cleanup_callback) SWITCH_STANDARD_SCHED_FUNC(limit_hash_cleanup_callback) { switch_thread_rwlock_wrlock(globals.limit_hash_rwlock); - switch_core_hash_delete_multi(globals.limit_hash, limit_hash_cleanup_delete_callback, NULL); + if (globals.limit_hash) { + switch_core_hash_delete_multi(globals.limit_hash, limit_hash_cleanup_delete_callback, NULL); + } switch_thread_rwlock_unlock(globals.limit_hash_rwlock); - - task->runtime = switch_epoch_time_now(NULL) + LIMIT_HASH_CLEANUP_INTERVAL; + + if (globals.limit_hash) { + task->runtime = switch_epoch_time_now(NULL) + LIMIT_HASH_CLEANUP_INTERVAL; + } } /* !\brief Releases usage of a limit_hash-controlled ressource */ @@ -991,7 +995,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_hash_shutdown) free(val); switch_core_hash_delete(globals.db_hash, key); } - + + switch_core_hash_destroy(&globals.limit_hash); + switch_core_hash_destroy(&globals.db_hash); switch_thread_rwlock_unlock(globals.limit_hash_rwlock); switch_thread_rwlock_unlock(globals.db_hash_rwlock); @@ -999,8 +1005,6 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_hash_shutdown) switch_thread_rwlock_destroy(globals.db_hash_rwlock); switch_thread_rwlock_destroy(globals.limit_hash_rwlock); - switch_core_hash_destroy(&globals.limit_hash); - switch_core_hash_destroy(&globals.db_hash); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index 5f70e0ab77..2f2bc7d421 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_limit/mod_limit.c b/src/mod/applications/mod_limit/mod_limit.c index 3378cfda93..56da299941 100644 --- a/src/mod/applications/mod_limit/mod_limit.c +++ b/src/mod/applications/mod_limit/mod_limit.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_memcache/mod_memcache.c b/src/mod/applications/mod_memcache/mod_memcache.c index 9aa0c97853..6016639d4f 100755 --- a/src/mod/applications/mod_memcache/mod_memcache.c +++ b/src/mod/applications/mod_memcache/mod_memcache.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_mp4/mod_mp4.cpp b/src/mod/applications/mod_mp4/mod_mp4.cpp index a1114d1ffc..0d9eac113f 100644 --- a/src/mod/applications/mod_mp4/mod_mp4.cpp +++ b/src/mod/applications/mod_mp4/mod_mp4.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index 42369f5d0b..8487d0be62 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,7 +17,7 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * * The Initial Developer of this module is * Darren Schreiber diff --git a/src/mod/applications/mod_rad_auth/mod_rad_auth.c b/src/mod/applications/mod_rad_auth/mod_rad_auth.c index 1cb81b0b88..1dc6d6bbdc 100644 --- a/src/mod/applications/mod_rad_auth/mod_rad_auth.c +++ b/src/mod/applications/mod_rad_auth/mod_rad_auth.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application -* Copyright (C) 2005/2006, Anthony Minessale II +* Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,13 +17,13 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is -* Anthony Minessale II +* Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * -* Anthony Minessale II +* Anthony Minessale II * Neal Horman * Tihomir Culjaga * diff --git a/src/mod/applications/mod_redis/mod_redis.c b/src/mod/applications/mod_redis/mod_redis.c index d20ab934f3..1e999675b1 100755 --- a/src/mod/applications/mod_redis/mod_redis.c +++ b/src/mod/applications/mod_redis/mod_redis.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_rss/mod_rss.c b/src/mod/applications/mod_rss/mod_rss.c index 2eaae2f16f..b85d86bb99 100644 --- a/src/mod/applications/mod_rss/mod_rss.c +++ b/src/mod/applications/mod_rss/mod_rss.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_skel/mod_skel.c b/src/mod/applications/mod_skel/mod_skel.c index c96d6b368d..c5445f3166 100644 --- a/src/mod/applications/mod_skel/mod_skel.c +++ b/src/mod/applications/mod_skel/mod_skel.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_snapshot/mod_snapshot.c b/src/mod/applications/mod_snapshot/mod_snapshot.c index 20b311029b..854292c777 100644 --- a/src/mod/applications/mod_snapshot/mod_snapshot.c +++ b/src/mod/applications/mod_snapshot/mod_snapshot.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_snipe_hunt/mod_snipe_hunt.c b/src/mod/applications/mod_snipe_hunt/mod_snipe_hunt.c index 387ee93210..334a0c5e20 100644 --- a/src/mod/applications/mod_snipe_hunt/mod_snipe_hunt.c +++ b/src/mod/applications/mod_snipe_hunt/mod_snipe_hunt.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_snom/mod_snom.c b/src/mod/applications/mod_snom/mod_snom.c index 1a16dd920f..3c50ea1699 100644 --- a/src/mod/applications/mod_snom/mod_snom.c +++ b/src/mod/applications/mod_snom/mod_snom.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp b/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp index 17e6b1f524..4b9c772ee3 100644 --- a/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp +++ b/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index ea5385089f..d9b9ff084a 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.h b/src/mod/applications/mod_spandsp/mod_spandsp.h index fdd754b43d..09e816627a 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.h +++ b/src/mod/applications/mod_spandsp/mod_spandsp.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_codecs.c b/src/mod/applications/mod_spandsp/mod_spandsp_codecs.c index 9852ac81f2..4e7f048ef7 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_codecs.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_codecs.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c index f576b7dd01..b31f6e15f1 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 27878246f0..21c6a68a0e 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/applications/mod_spy/mod_spy.c b/src/mod/applications/mod_spy/mod_spy.c index cb8981d264..9986703f66 100644 --- a/src/mod/applications/mod_spy/mod_spy.c +++ b/src/mod/applications/mod_spy/mod_spy.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -83,7 +83,7 @@ static switch_status_t spy_on_exchange_media(switch_core_session_t *session) static switch_status_t spy_on_park(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); - const char *moh = switch_channel_get_variable(channel, "hold_music"); + const char *moh = switch_channel_get_hold_music(channel); while (switch_channel_ready(channel) && switch_channel_get_state(channel) == CS_PARK) { if (moh) { diff --git a/src/mod/applications/mod_stress/mod_stress.cpp b/src/mod/applications/mod_stress/mod_stress.cpp index 37fe45e073..d96739da0a 100644 --- a/src/mod/applications/mod_stress/mod_stress.cpp +++ b/src/mod/applications/mod_stress/mod_stress.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * 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 b6f13a93e9..42ece97e28 100644 --- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c +++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -234,7 +234,7 @@ SWITCH_STANDARD_APP(valet_parking_function) } if (!(tmp = switch_channel_get_variable(channel, "valet_hold_music"))) { - tmp = switch_channel_get_variable(channel, "hold_music"); + tmp = switch_channel_get_hold_music(channel); } if (tmp) music = tmp; diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index e939d7f315..76870f75b9 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -311,6 +311,7 @@ static void destroy_profile(const char *profile_name, switch_bool_t block) /* Static buffer, 2 bytes */ static switch_xml_config_string_options_t config_dtmf = { NULL, 2, "[0-9#\\*]" }; +static switch_xml_config_string_options_t config_dtmf_optional = { NULL, 2, "[0-9#\\*]?" }; static switch_xml_config_string_options_t config_login_keys = { NULL, 16, "[0-9#\\*]*" }; static switch_xml_config_string_options_t config_file_ext = { NULL, 10, NULL }; static switch_xml_config_int_options_t config_int_0_10000 = { SWITCH_TRUE, 0, SWITCH_TRUE, 10000 }; @@ -520,8 +521,8 @@ vm_profile_t *profile_set_config(vm_profile_t *profile) SWITCH_CONFIG_SET_ITEM(profile->config[i++], "urgent-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->urgent_key, "*", &config_dtmf, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "operator-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, - &profile->operator_key, "", &config_dtmf, NULL, NULL); - SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->vmain_key, "", &config_dtmf, NULL, NULL); + &profile->operator_key, "", &config_dtmf_optional, NULL, NULL); + SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->vmain_key, "", &config_dtmf_optional, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-extension", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->vmain_ext, "", &profile->config_str_pool, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "forward-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, @@ -1973,12 +1974,22 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_FAIL_MACRO, NULL, NULL, NULL)); } else { + switch_event_t *params; + TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_SELECTED_MACRO, input, NULL, NULL)); sql = switch_mprintf("update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s'", file_path, myid, domain_name); vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(sql); + + switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "change-greeting"); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Greeting-Path", file_path); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-User", myid); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name); + switch_channel_event_set_data(channel, params); + switch_event_fire(¶ms); } switch_safe_free(file_path); } else if (!strcmp(input, profile->record_greeting_key)) { @@ -1989,6 +2000,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p if (num < 1 || num > VM_MAX_GREETINGS) { TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_FAIL_MACRO, NULL, NULL, NULL)); } else { + switch_event_t *params; file_path = switch_mprintf("%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext); TRY_CODE(create_file(session, profile, VM_RECORD_GREETING_MACRO, file_path, &message_len, SWITCH_TRUE, NULL, NULL)); sql = @@ -1997,6 +2009,14 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(sql); switch_safe_free(file_path); + + switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "record-greeting"); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Greeting-Path", file_path); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-User", myid); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name); + switch_channel_event_set_data(channel, params); + switch_event_fire(¶ms); } } else if (!strcmp(input, profile->change_pass_key)) { @@ -2027,12 +2047,21 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p switch_event_fire(¶ms); } else if (!strcmp(input, profile->record_name_key)) { + switch_event_t *params; file_path = switch_mprintf("%s%srecorded_name.%s", dir_path, SWITCH_PATH_SEPARATOR, profile->file_ext); TRY_CODE(create_file(session, profile, VM_RECORD_NAME_MACRO, file_path, &message_len, SWITCH_FALSE, NULL, NULL)); sql = switch_mprintf("update voicemail_prefs set name_path='%s' where username='%s' and domain='%s'", file_path, myid, domain_name); vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(file_path); switch_safe_free(sql); + + switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "record-name"); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Name-Path", file_path); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-User", myid); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name); + switch_channel_event_set_data(channel, params); + switch_event_fire(¶ms); } continue; } @@ -2337,6 +2366,7 @@ static switch_status_t deliver_vm(vm_profile_t *profile, const char *filename; switch_xml_t x_param, x_params; char *vm_email = NULL; + char *vm_email_from = NULL; char *vm_notify_email = NULL; char *email_addr = NULL; char *vm_timezone = NULL; @@ -2401,6 +2431,8 @@ static switch_status_t deliver_vm(vm_profile_t *profile, vm_email = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "vm-notify-mailto")) { vm_notify_email = switch_core_strdup(pool, val); + } else if (!strcasecmp(var, "vm-mailfrom")) { + vm_email_from = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "email-addr")) { email_addr = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "vm-email-all-messages") && (send_main = switch_true(val))) { @@ -2544,7 +2576,9 @@ static switch_status_t deliver_vm(vm_profile_t *profile, switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_message_len", duration_str); - if (zstr(profile->email_from)) { + if (!zstr(vm_email_from)) { + from = switch_core_strdup(pool, vm_email_from); + } else if (zstr(profile->email_from)) { from = switch_core_sprintf(pool, "%s@%s", myid, domain_name); } else { from = switch_event_expand_headers(params, profile->email_from); diff --git a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c index 3cd955727b..432a0b7c99 100644 --- a/src/mod/asr_tts/mod_cepstral/mod_cepstral.c +++ b/src/mod/asr_tts/mod_cepstral/mod_cepstral.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/asr_tts/mod_flite/mod_flite.c b/src/mod/asr_tts/mod_flite/mod_flite.c index c96164a585..cd4bbfa66a 100644 --- a/src/mod/asr_tts/mod_flite/mod_flite.c +++ b/src/mod/asr_tts/mod_flite/mod_flite.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/asr_tts/mod_pocketsphinx/mod_pocketsphinx.c b/src/mod/asr_tts/mod_pocketsphinx/mod_pocketsphinx.c index 2740b8721a..b257278e4d 100644 --- a/src/mod/asr_tts/mod_pocketsphinx/mod_pocketsphinx.c +++ b/src/mod/asr_tts/mod_pocketsphinx/mod_pocketsphinx.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_amr/mod_amr.c b/src/mod/codecs/mod_amr/mod_amr.c index e8925c4581..0523e64fdd 100644 --- a/src/mod/codecs/mod_amr/mod_amr.c +++ b/src/mod/codecs/mod_amr/mod_amr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_amrwb/mod_amrwb.c b/src/mod/codecs/mod_amrwb/mod_amrwb.c index 73b1cec535..d71953b224 100644 --- a/src/mod/codecs/mod_amrwb/mod_amrwb.c +++ b/src/mod/codecs/mod_amrwb/mod_amrwb.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,7 +17,7 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * diff --git a/src/mod/codecs/mod_bv/mod_bv.c b/src/mod/codecs/mod_bv/mod_bv.c index 54158c243e..d8560094b4 100644 --- a/src/mod/codecs/mod_bv/mod_bv.c +++ b/src/mod/codecs/mod_bv/mod_bv.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_celt/Makefile b/src/mod/codecs/mod_celt/Makefile index cdcc045bdb..2d2e27f04c 100644 --- a/src/mod/codecs/mod_celt/Makefile +++ b/src/mod/codecs/mod_celt/Makefile @@ -1,6 +1,6 @@ BASE=../../../.. -CELT=celt-0.7.1 +CELT=celt-0.10.0 CELT_DIR=$(switch_srcdir)/libs/$(CELT) CELT_BUILDDIR=$(switch_builddir)/libs/$(CELT) diff --git a/src/mod/codecs/mod_celt/mod_celt.c b/src/mod/codecs/mod_celt/mod_celt.c index 0c66469705..37983f3683 100644 --- a/src/mod/codecs/mod_celt/mod_celt.c +++ b/src/mod/codecs/mod_celt/mod_celt.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -54,7 +54,7 @@ static switch_status_t switch_celt_init(switch_codec_t *codec, switch_codec_flag } context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL); - celt_mode_info(context->mode_object, CELT_GET_FRAME_SIZE, &context->frame_size); + context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size / codec->implementation->actual_samples_per_second + 4) / 8; /* @@ -111,7 +111,7 @@ static switch_status_t switch_celt_encode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; } - *encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, NULL, + *encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, (unsigned char *) encoded_data, context->bytes_per_packet); return SWITCH_STATUS_SUCCESS; @@ -130,7 +130,7 @@ static switch_status_t switch_celt_decode(switch_codec_t *codec, return SWITCH_STATUS_FALSE; } - if (celt_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data)) { + if (celt_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, codec->implementation->samples_per_packet)) { return SWITCH_STATUS_GENERR; } diff --git a/src/mod/codecs/mod_celt/mod_celt.vcproj b/src/mod/codecs/mod_celt/mod_celt.vcproj index 6eb457d5ae..080f95ebbd 100644 --- a/src/mod/codecs/mod_celt/mod_celt.vcproj +++ b/src/mod/codecs/mod_celt/mod_celt.vcproj @@ -42,7 +42,7 @@ /> - ..\..\..\..\libs\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\..\..\libs\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) @@ -80,7 +80,7 @@ X64 - ..\..\..\..\libs\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\..\..\libs\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) @@ -93,7 +93,7 @@ - ..\..\..\..\libs\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\..\..\libs\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) @@ -108,7 +108,7 @@ X64 - ..\..\..\..\libs\celt-0.7.1\libcelt;%(AdditionalIncludeDirectories) + ..\..\..\..\libs\celt-0.10.0\libcelt;%(AdditionalIncludeDirectories) diff --git a/src/mod/codecs/mod_codec2/mod_codec2.c b/src/mod/codecs/mod_codec2/mod_codec2.c index e7aa645090..866a39c9df 100644 --- a/src/mod/codecs/mod_codec2/mod_codec2.c +++ b/src/mod/codecs/mod_codec2/mod_codec2.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c b/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c index 55afff6115..0553607bfe 100644 --- a/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c +++ b/src/mod/codecs/mod_dahdi_codec/mod_dahdi_codec.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_g723_1/mod_g723_1.c b/src/mod/codecs/mod_g723_1/mod_g723_1.c index ac74746158..cd5defb8e9 100644 --- a/src/mod/codecs/mod_g723_1/mod_g723_1.c +++ b/src/mod/codecs/mod_g723_1/mod_g723_1.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_g729/mod_g729.c b/src/mod/codecs/mod_g729/mod_g729.c index 468aac2457..0b1d2ada0e 100644 --- a/src/mod/codecs/mod_g729/mod_g729.c +++ b/src/mod/codecs/mod_g729/mod_g729.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_h26x/mod_h26x.c b/src/mod/codecs/mod_h26x/mod_h26x.c index 40952ae89e..7f9ec543f6 100644 --- a/src/mod/codecs/mod_h26x/mod_h26x.c +++ b/src/mod/codecs/mod_h26x/mod_h26x.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_ilbc/mod_ilbc.c b/src/mod/codecs/mod_ilbc/mod_ilbc.c index 85298375db..23ca642c22 100644 --- a/src/mod/codecs/mod_ilbc/mod_ilbc.c +++ b/src/mod/codecs/mod_ilbc/mod_ilbc.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -163,7 +163,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_ilbc_load) "mode=30", /* default fmtp to send (can be overridden by the init function) */ 8000, /* samples transferred per second */ 8000, /* actual samples transferred per second */ - 13300, /* bits transferred per second */ + 13330, /* bits transferred per second */ 30000, /* number of microseconds per frame */ ILBC_BLOCK_LEN_30MS, /* number of samples per frame */ ILBC_BLOCK_LEN_30MS * 2, /* number of bytes per frame decompressed */ diff --git a/src/mod/codecs/mod_mp4v/mod_mp4v.c b/src/mod/codecs/mod_mp4v/mod_mp4v.c index 5a8dc713a6..d4e0a1ea23 100644 --- a/src/mod/codecs/mod_mp4v/mod_mp4v.c +++ b/src/mod/codecs/mod_mp4v/mod_mp4v.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_siren/mod_siren.c b/src/mod/codecs/mod_siren/mod_siren.c index 4646ffc5ae..224a8258a6 100644 --- a/src/mod/codecs/mod_siren/mod_siren.c +++ b/src/mod/codecs/mod_siren/mod_siren.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_skel_codec/mod_skel_codec.c b/src/mod/codecs/mod_skel_codec/mod_skel_codec.c index d1a4b371e0..cab5c7e8df 100644 --- a/src/mod/codecs/mod_skel_codec/mod_skel_codec.c +++ b/src/mod/codecs/mod_skel_codec/mod_skel_codec.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_speex/mod_speex.c b/src/mod/codecs/mod_speex/mod_speex.c index a951b12d84..6e21939d33 100644 --- a/src/mod/codecs/mod_speex/mod_speex.c +++ b/src/mod/codecs/mod_speex/mod_speex.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_theora/mod_theora.c b/src/mod/codecs/mod_theora/mod_theora.c index 41871bfdf4..f1601436ca 100644 --- a/src/mod/codecs/mod_theora/mod_theora.c +++ b/src/mod/codecs/mod_theora/mod_theora.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c b/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c index e447d725ed..68bec657e6 100644 --- a/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c +++ b/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c index 9ccaaad4cd..5869d14c3a 100644 --- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c +++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c b/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c index ec22222363..d28804e3b8 100644 --- a/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c +++ b/src/mod/dialplans/mod_dialplan_directory/mod_dialplan_directory.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c index 4fc240dec2..929372be1a 100644 --- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c +++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/directories/mod_ldap/mod_ldap.c b/src/mod/directories/mod_ldap/mod_ldap.c index b875c00ff4..1bc9b9d61b 100644 --- a/src/mod/directories/mod_ldap/mod_ldap.c +++ b/src/mod/directories/mod_ldap/mod_ldap.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_alsa/mod_alsa.c b/src/mod/endpoints/mod_alsa/mod_alsa.c index 065386bc9f..40c1362f3d 100644 --- a/src/mod/endpoints/mod_alsa/mod_alsa.c +++ b/src/mod/endpoints/mod_alsa/mod_alsa.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 75329a0848..66f62b2295 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_gsmopen/gsmopen.h b/src/mod/endpoints/mod_gsmopen/gsmopen.h index 05ef1641bf..37eb15741c 100644 --- a/src/mod/endpoints/mod_gsmopen/gsmopen.h +++ b/src/mod/endpoints/mod_gsmopen/gsmopen.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005/2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,7 +17,7 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp index 13e433557d..fe1f7cb8c0 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005/2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,7 +17,7 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * @@ -1512,7 +1512,7 @@ static switch_status_t load_config(int reload_type) hotline = val; } else if (!strcasecmp(var, "dial_regex")) { dial_regex = val; - } else if (!strcasecmp(var, "hold_music")) { + } else if (!strcasecmp(var, SWITCH_HOLD_MUSIC_VARIABLE)) { hold_music = val; } else if (!strcasecmp(var, "fail_dial_regex")) { fail_dial_regex = val; diff --git a/src/mod/endpoints/mod_h323/mod_h323.cpp b/src/mod/endpoints/mod_h323/mod_h323.cpp index a31f9a81fc..44295f618f 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.cpp +++ b/src/mod/endpoints/mod_h323/mod_h323.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_h323/mod_h323.h b/src/mod/endpoints/mod_h323/mod_h323.h index 8127206126..5477f9aa59 100644 --- a/src/mod/endpoints/mod_h323/mod_h323.h +++ b/src/mod/endpoints/mod_h323/mod_h323.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_khomp/src/khomp_pvt_kxe1.cpp b/src/mod/endpoints/mod_khomp/src/khomp_pvt_kxe1.cpp index 0d3c3b38ff..997973b1df 100644 --- a/src/mod/endpoints/mod_khomp/src/khomp_pvt_kxe1.cpp +++ b/src/mod/endpoints/mod_khomp/src/khomp_pvt_kxe1.cpp @@ -2744,7 +2744,7 @@ bool BoardE1::KhompPvtFXS::transfer(std::string & context, bool blind) callFXS()->_uuid_other_session = getUUID(peer_session); const char *stream = NULL; - if (!(stream = switch_channel_get_variable(peer_channel, SWITCH_HOLD_MUSIC_VARIABLE))) + if (!(stream = switch_channel_get_hold_music(peer_channel))) { stream = "silence"; } diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 7c69ff252e..f875f6b804 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index a4a380d74e..8978b85fc2 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_reference/mod_reference.c b/src/mod/endpoints/mod_reference/mod_reference.c index 385e29321f..f895e81338 100644 --- a/src/mod/endpoints/mod_reference/mod_reference.c +++ b/src/mod/endpoints/mod_reference/mod_reference.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.c b/src/mod/endpoints/mod_skypopen/mod_skypopen.c index 56188a4188..eac0a67943 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.c +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005/2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,7 +17,7 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * diff --git a/src/mod/endpoints/mod_skypopen/skypopen.h b/src/mod/endpoints/mod_skypopen/skypopen.h index 2f1c8e48e9..2be11bf4fc 100644 --- a/src/mod/endpoints/mod_skypopen/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/skypopen.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005/2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,7 +17,7 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 6558eff9d7..33b8a8bbd3 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -43,8 +43,6 @@ SWITCH_MODULE_DEFINITION(mod_sofia, mod_sofia_load, mod_sofia_shutdown, NULL); struct mod_sofia_globals mod_sofia_globals; switch_endpoint_interface_t *sofia_endpoint_interface; -static switch_frame_t silence_frame = { 0 }; -static char silence_data[13] = ""; #define STRLEN 15 @@ -1094,8 +1092,10 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f sofia_glue_do_invite(session); } #endif - - *frame = &silence_frame; + *frame = &tech_pvt->read_frame; + switch_set_flag((*frame), SFF_CNG); + (*frame)->datalen = tech_pvt->read_impl.encoded_bytes_per_packet; + memset((*frame)->data, 0, (*frame)->datalen); return SWITCH_STATUS_SUCCESS; } @@ -1346,7 +1346,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi char *p; const char *s; - if (!strncasecmp(msg->string_arg, "debug:", 6)) { + if (!strcasecmp(msg->string_arg, "pause")) { + switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_TRUE); + goto end; + } else if (!strcasecmp(msg->string_arg, "resume")) { + switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_FALSE); + goto end; + } else if (!strncasecmp(msg->string_arg, "debug:", 6)) { s = msg->string_arg + 6; if (s && !strcmp(s, "off")) { s = NULL; @@ -1426,10 +1432,16 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi { sofia_glue_tech_simplify(tech_pvt); - + if (switch_rtp_ready(tech_pvt->rtp_session)) { const char *val; int ok = 0; + + if (switch_channel_test_flag(tech_pvt->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(tech_pvt->channel, CC_FS_RTP)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s PAUSE Jitterbuffer\n", switch_channel_get_name(channel)); + switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_TRUE); + } if (sofia_test_flag(tech_pvt, TFLAG_PASS_RFC2833) && switch_channel_test_flag_partner(channel, CF_FS_RTP)) { switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833); @@ -1455,6 +1467,12 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (switch_rtp_ready(tech_pvt->rtp_session)) { const char *val; int ok = 0; + + if (switch_channel_test_flag(tech_pvt->channel, CF_JITTERBUFFER)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s RESUME Jitterbuffer\n", switch_channel_get_name(channel)); + switch_rtp_pause_jitter_buffer(tech_pvt->rtp_session, SWITCH_FALSE); + } if (switch_rtp_test_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s deactivate passthru 2833 mode.\n", @@ -3704,7 +3722,7 @@ SWITCH_STANDARD_API(sofia_function) "--------------------------------------------------------------------------------\n" "sofia help\n" "sofia profile [[start|stop|restart|rescan]|" - "flush_inbound_reg [] [reboot]|" + "flush_inbound_reg [|<[user]@domain>] [reboot]|" "[register|unregister] [|all]|" "killgw |" "[stun-auto-disable|stun-enabled] [true|false]]|" @@ -3772,11 +3790,39 @@ SWITCH_STANDARD_API(sofia_function) int wdon = -1; if (argc > 1) { + if (!strcasecmp(argv[1], "debug")) { + + if (argc > 2) { + if (strstr(argv[2], "presence")) { + mod_sofia_globals.debug_presence = 1; + stream->write_function(stream, "+OK Debugging presence\n"); + } + + if (strstr(argv[2], "sla")) { + mod_sofia_globals.debug_sla = 1; + stream->write_function(stream, "+OK Debugging sla\n"); + } + + if (strstr(argv[2], "none")) { + stream->write_function(stream, "+OK Debugging nothing\n"); + mod_sofia_globals.debug_presence = 0; + mod_sofia_globals.debug_sla = 0; + } + } + + stream->write_function(stream, "+OK Debugging summary: presence: %s sla: %s\n", + mod_sofia_globals.debug_presence ? "on" : "off", + mod_sofia_globals.debug_sla ? "on" : "off"); + + goto done; + } + if (!strcasecmp(argv[1], "siptrace")) { if (argc > 2) { ston = switch_true(argv[2]); } } + if (!strcasecmp(argv[1], "watchdog")) { if (argc > 2) { wdon = switch_true(argv[2]); @@ -3791,7 +3837,7 @@ SWITCH_STANDARD_API(sofia_function) sofia_glue_global_watchdog(wdon); stream->write_function(stream, "+OK Global watchdog %s", wdon ? "on" : "off"); } else { - stream->write_function(stream, "-ERR Usage: siptrace |watchdog "); + stream->write_function(stream, "-ERR Usage: siptrace |watchdog |debug + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -225,6 +225,8 @@ typedef enum { PFLAG_DEL_SUBS_ON_REG, PFLAG_IGNORE_183NOSDP, PFLAG_PRESENCE_PROBE_ON_REGISTER, + PFLAG_PRESENCE_ON_REGISTER, + PFLAG_PRESENCE_ON_FIRST_REGISTER, PFLAG_NO_CONNECTION_REUSE, /* No new flags below this line */ PFLAG_MAX @@ -403,6 +405,7 @@ struct sofia_gateway { char *register_from; char *register_contact; char *extension; + char *real_extension; char *register_to; char *register_proxy; char *register_sticky_proxy; @@ -501,6 +504,7 @@ struct sofia_profile { char *challenge_realm; char *rtcp_audio_interval_msec; char *rtcp_video_interval_msec; + char *jb_msec; sofia_cid_type_t cid_type; sofia_dtmf_t dtmf_type; int auto_restart; @@ -1050,3 +1054,4 @@ void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const void sofia_glue_check_dtmf_type(private_object_t *tech_pvt); void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str); char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np); +void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 9e412bbbb7..643b3dd814 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -161,6 +161,15 @@ static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, swit char *full; if (sip) { + if (sip->sip_route) { + if ((full = sip_header_as_string(profile->home, (void *) sip->sip_route))) { + const char *v = switch_channel_get_variable(channel, "sip_full_route"); + if (!v) { + switch_channel_set_variable(channel, "sip_full_route", full); + } + su_free(profile->home, full); + } + } if (sip->sip_via) { if ((full = sip_header_as_string(profile->home, (void *) sip->sip_via))) { const char *v = switch_channel_get_variable(channel, "sip_full_via"); @@ -1468,8 +1477,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void TPTAG_TLS_VERIFY_POLICY(0)), TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), TPTAG_TLS_VERSION(profile->tls_version)), - TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), - TPTAG_KEEPALIVE(20000)), TAG_IF(!strchr(profile->sipip, ':'), NTATAG_UDP_MTU(65535)), TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV), @@ -2056,10 +2063,6 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) from_user = username; } - if (zstr(extension)) { - extension = username; - } - if (zstr(proxy)) { proxy = realm; } @@ -2151,8 +2154,13 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) sipip = profile->sipip; } - gateway->extension = switch_core_strdup(gateway->pool, extension); + if (zstr(extension)) { + extension = username; + } else { + gateway->real_extension = switch_core_strdup(gateway->pool, extension); + } + gateway->extension = switch_core_strdup(gateway->pool, extension); if (!strncasecmp(proxy, "sip:", 4)) { gateway->register_proxy = switch_core_strdup(gateway->pool, proxy); @@ -2351,6 +2359,11 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_DISABLE_HOLD); } + } else if (!strcasecmp(var, "auto-jitterbuffer-msec")) { + int msec = atoi(val); + if (msec > 19) { + profile->jb_msec = switch_core_strdup(profile->pool, val); + } } else if (!strcasecmp(var, "sip-trace")) { if (switch_true(val)) { sofia_set_flag(profile, TFLAG_TPORT_LOG); @@ -2406,6 +2419,17 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER); } + + } else if (!strcasecmp(var, "send-presence-on-register")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); + } else if (!strcasecmp(val, "first-only")) { + sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); + sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); + } else { + sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); + sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); + } } else if (!strcasecmp(var, "cid-in-1xx")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_CID_IN_1XX); @@ -2995,6 +3019,7 @@ switch_status_t config_sofia(int reload, char *profile_name) sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER); sofia_set_pflag(profile, PFLAG_SQL_IN_TRANS); + sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); profile->shutdown_type = "false"; profile->local_network = "localnet.auto"; sofia_set_flag(profile, TFLAG_ENABLE_SOA); @@ -3077,6 +3102,16 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER); } + } else if (!strcasecmp(var, "send-presence-on-register")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); + } else if (!strcasecmp(val, "first-only")) { + sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); + sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); + } else { + sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER); + sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER); + } } else if (!strcasecmp(var, "cid-in-1xx")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_CID_IN_1XX); @@ -3089,6 +3124,11 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_DISABLE_HOLD); } + } else if (!strcasecmp(var, "auto-jitterbuffer-msec")) { + int msec = atoi(val); + if (msec > 19) { + profile->jb_msec = switch_core_strdup(profile->pool, val); + } } else if (!strcasecmp(var, "dtmf-type")) { if (!strcasecmp(val, "rfc2833")) { profile->dtmf_type = DTMF_2833; @@ -5550,7 +5590,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_core_event_hook_add_state_change(a_session, xfer_hanguphook); switch_channel_set_variable(a_channel, "att_xfer_kill_uuid", switch_core_session_get_uuid(b_session)); - if ((tmp = switch_channel_get_variable(a_channel, SWITCH_HOLD_MUSIC_VARIABLE))) { + if ((tmp = switch_channel_get_hold_music(a_channel))) { moh = tmp; } @@ -6212,6 +6252,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ char acl_token[512] = ""; sofia_transport_t transport; const char *gw_name = NULL; + const char *gw_param_name = NULL; char *call_info_str = NULL; nua_handle_t *bnh = NULL; char sip_acl_authed_by[512] = ""; @@ -6844,7 +6885,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (sip->sip_request->rq_url->url_params) { - gw_name = sofia_glue_find_parameter_value(session, sip->sip_request->rq_url->url_params, "gw="); + gw_param_name = sofia_glue_find_parameter_value(session, sip->sip_request->rq_url->url_params, "gw="); } if (strstr(destination_number, "gw+")) { @@ -6859,19 +6900,35 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } } - if (gw_name) { - sofia_gateway_t *gateway; - if (gw_name && (gateway = sofia_reg_find_gateway(gw_name))) { + if (gw_name || gw_param_name) { + sofia_gateway_t *gateway = NULL; + char *extension = NULL; + + if (gw_name && ((gateway = sofia_reg_find_gateway(gw_name)))) { + gw_param_name = NULL; + extension = gateway->extension; + } + + if (!gateway && gw_param_name) { + gateway = sofia_reg_find_gateway(gw_param_name); + extension = gateway->real_extension; + } + + if (gateway) { context = switch_core_session_strdup(session, gateway->register_context); switch_channel_set_variable(channel, "sip_gateway", gateway->name); - if (gateway->extension) { - if (!strcasecmp(gateway->extension, "auto_to_user")) { + if (!zstr(extension)) { + if (!strcasecmp(extension, "auto_to_user")) { destination_number = sip->sip_to->a_url->url_user; + } else if (!strcasecmp(extension, "auto")) { + if (gw_name) { + destination_number = sip->sip_to->a_url->url_user; + } } else { - destination_number = switch_core_session_strdup(session, gateway->extension); + destination_number = switch_core_session_strdup(session, extension); } - } else { + } else if (!gw_param_name) { destination_number = sip->sip_to->a_url->url_user; } @@ -7100,6 +7157,9 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ switch_channel_set_variable(channel, "sip_history_info", un->un_value); } } + } else if (!strcasecmp(un->un_name, "X-FS-Channel-Name") && !zstr(un->un_value)) { + switch_channel_set_name(channel, un->un_value); + switch_channel_set_variable(channel, "push_channel_name", "true"); } else if (!strcasecmp(un->un_name, "X-FS-Support")) { tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, un->un_value); } else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2)) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 4779ef167f..dfd6a76974 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -70,7 +70,7 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * port = tech_pvt->proxy_sdp_audio_port; } } - + if (!port) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(tech_pvt->channel)); return; @@ -377,6 +377,13 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 sofia_glue_check_dtmf_type(tech_pvt); + if (sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) || + ((val = switch_channel_get_variable(tech_pvt->channel, "supress_cng")) && switch_true(val)) || + ((val = switch_channel_get_variable(tech_pvt->channel, "suppress_cng")) && switch_true(val))) { + use_cng = 0; + tech_pvt->cng_pt = 0; + } + if (!tech_pvt->payload_space) { int i; @@ -388,6 +395,13 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 tech_pvt->ianacodes[i] = imp->ianacode; if (tech_pvt->ianacodes[i] > 64) { + if (tech_pvt->dtmf_type == DTMF_2833 && tech_pvt->te > 95 && tech_pvt->te == tech_pvt->payload_space) { + tech_pvt->payload_space++; + } + if (!sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) && + tech_pvt->cng_pt && use_cng && tech_pvt->cng_pt == tech_pvt->payload_space) { + tech_pvt->payload_space++; + } tech_pvt->ianacodes[i] = tech_pvt->payload_space++; } } @@ -401,13 +415,6 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32 verbose_sdp = 1; } - if (sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) || - ((val = switch_channel_get_variable(tech_pvt->channel, "supress_cng")) && switch_true(val)) || - ((val = switch_channel_get_variable(tech_pvt->channel, "suppress_cng")) && switch_true(val))) { - use_cng = 0; - tech_pvt->cng_pt = 0; - } - if (!force && !ip && !sr && (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA))) { return; @@ -832,6 +839,8 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK); switch_channel_set_cap(tech_pvt->channel, CC_BYPASS_MEDIA); switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA); + switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER); + switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP); switch_core_session_set_private(session, tech_pvt); @@ -2693,8 +2702,8 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) 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); switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); + switch_goto_status(SWITCH_STATUS_FALSE, end); } if (switch_core_codec_init_with_bitrate(&tech_pvt->write_codec, @@ -3152,8 +3161,8 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f } } - if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) { - int len = atoi(val); + if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec")) || (val = tech_pvt->profile->jb_msec)) { + int jb_msec = atoi(val); int maxlen = 0; char *p; @@ -3162,13 +3171,13 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f maxlen = atoi(p); } - if (len < 20 || len > 10000) { + if (jb_msec < 20 || jb_msec > 10000) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, - "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", len); + "Invalid Jitterbuffer spec [%d] must be between 20 and 10000\n", jb_msec); } else { int qlen, maxqlen = 50; - qlen = len / (tech_pvt->read_impl.microseconds_per_packet / 1000); + qlen = jb_msec / (tech_pvt->read_impl.microseconds_per_packet / 1000); if (maxlen) { maxqlen = maxlen / (tech_pvt->read_impl.microseconds_per_packet / 1000); @@ -3178,11 +3187,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f tech_pvt->read_impl.samples_per_packet, tech_pvt->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), - SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen); switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), - SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen); } } @@ -3548,13 +3557,53 @@ void sofia_glue_set_r_sdp_codec_string(switch_core_session_t *session, const cha } if (match) { - if (ptime > 0) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh@%di", imp->iananame, (unsigned int) map->rm_rate, - ptime); - } else { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh", imp->iananame, (unsigned int) map->rm_rate); + int codec_ms = ptime; + uint32_t map_bit_rate = 0; + char ptstr[20] = ""; + char ratestr[20] = ""; + char bitstr[20] = ""; + switch_codec_fmtp_t codec_fmtp = { 0 }; + + if (!codec_ms) { + codec_ms = switch_default_ptime(map->rm_encoding, map->rm_pt); } - already_did[imp->ianacode] = 1; + + map_bit_rate = switch_known_bitrate(map->rm_pt); + + if (!ptime && !strcasecmp(map->rm_encoding, "g723")) { + ptime = codec_ms = 30; + } + + if (zstr(map->rm_fmtp)) { + if (!strcasecmp(map->rm_encoding, "ilbc")) { + ptime = codec_ms = 30; + map_bit_rate = 13330; + } + } else { + if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) { + if (codec_fmtp.bits_per_second) { + map_bit_rate = codec_fmtp.bits_per_second; + } + if (codec_fmtp.microseconds_per_packet) { + codec_ms = (codec_fmtp.microseconds_per_packet / 1000); + } + } + } + + if (map->rm_rate) { + switch_snprintf(ratestr, sizeof(ratestr), "@%uh", (unsigned int) map->rm_rate); + } + + if (codec_ms) { + switch_snprintf(ptstr, sizeof(ptstr), "@%di", codec_ms); + } + + if (map_bit_rate) { + switch_snprintf(bitstr, sizeof(bitstr), "@%db", map_bit_rate); + } + + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s%s%s%s", map->rm_encoding, ratestr, ptstr, bitstr); + break; } } @@ -3661,7 +3710,7 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly) switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, tech_pvt->max_missed_hold_packets); } - if (!(stream = switch_channel_get_variable(tech_pvt->channel, SWITCH_HOLD_MUSIC_VARIABLE))) { + if (!(stream = switch_channel_get_hold_music(tech_pvt->channel))) { stream = tech_pvt->profile->hold_music; } @@ -3998,7 +4047,7 @@ 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 sendonly = 0; + int sendonly = 0, recvonly = 0; int greedy = 0, x = 0, skip = 0, mine = 0; switch_channel_t *channel = switch_core_session_get_channel(session); const char *val; @@ -4066,6 +4115,19 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s if (!strcasecmp(attr->a_name, "sendonly") || !strcasecmp(attr->a_name, "inactive")) { sendonly = 1; + switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "recvonly"); + } else if (!strcasecmp(attr->a_name, "recvonly")) { + switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", "sendonly"); + recvonly = 1; + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + switch_rtp_set_max_missed_packets(tech_pvt->rtp_session, 0); + tech_pvt->max_missed_hold_packets = 0; + tech_pvt->max_missed_packets = 0; + } else { + switch_channel_set_variable(tech_pvt->channel, "rtp_timeout_sec", "0"); + switch_channel_set_variable(tech_pvt->channel, "rtp_hold_timeout_sec", "0"); + } } else if (sendonly < 2 && !strcasecmp(attr->a_name, "sendrecv")) { sendonly = 0; } else if (!strcasecmp(attr->a_name, "ptime")) { @@ -4075,6 +4137,11 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } } + if (sendonly != 1 && recvonly != 1) { + switch_channel_set_variable(tech_pvt->channel, "media_audio_mode", NULL); + } + + 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; @@ -4376,6 +4443,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s if (zstr(map->rm_fmtp)) { if (!strcasecmp(map->rm_encoding, "ilbc")) { ptime = codec_ms = 30; + map_bit_rate = 13330; } } else { if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) { @@ -4387,8 +4455,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } } } - - for (i = first; i < last && i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; @@ -4399,7 +4465,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } 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, ptime, map_bit_rate, + 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; @@ -6065,6 +6131,19 @@ void sofia_glue_tech_simplify(private_object_t *tech_pvt) } } +void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on) +{ + switch_core_session_message_t *msg; + msg = switch_core_session_alloc(session, sizeof(*msg)); + MESSAGE_STAMP_FFL(msg); + msg->message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER; + msg->string_arg = switch_core_session_strdup(session, on ? "pause" : "resume"); + msg->from = __FILE__; + + switch_core_session_queue_message(session, msg); +} + + void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl) { switch_core_session_message_t *msg; @@ -6134,6 +6213,14 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str) if (switch_stristr("~NEVER_SEND_MARKER", str)) { *flag_pole &= ~RTP_BUG_NEVER_SEND_MARKER; } + + if (switch_stristr("IGNORE_DTMF_DURATION", str)) { + *flag_pole |= RTP_BUG_IGNORE_DTMF_DURATION; + } + + if (switch_stristr("~IGNORE_DTMF_DURATION", str)) { + *flag_pole &= ~RTP_BUG_IGNORE_DTMF_DURATION; + } } char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 04d5b0142e..94fef61181 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 1589eeb8e1..f644ff772b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -606,16 +606,16 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires" ",user_agent,server_user,server_host,profile_name,network_ip" ",%d from sip_registrations where call_id='%q' %s", reboot, call_id, sqlextra); - switch_safe_free(sqlextra); switch_mutex_lock(profile->ireg_mutex); sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile); switch_mutex_unlock(profile->ireg_mutex); switch_safe_free(sql); - sql = switch_mprintf("delete from sip_registrations where call_id='%q' or (sip_user='%q' and sip_host='%q')", call_id, user, host); + sql = switch_mprintf("delete from sip_registrations where call_id='%q' %s", call_id, sqlextra); sofia_glue_execute_sql_now(profile, &sql, SWITCH_FALSE); + switch_safe_free(sqlextra); switch_safe_free(sql); switch_safe_free(dup); @@ -875,9 +875,19 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand long reg_count = 0; int delete_subs; const char *agent = "unknown"; - + const char *pres_on_reg = NULL; + int send_pres = 0; + delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG); + if (v_event && *v_event) pres_on_reg = switch_event_get_header(*v_event, "send-presence-on-register"); + + if (!(send_pres = switch_true(pres_on_reg))) { + if (pres_on_reg && !strcasecmp(pres_on_reg, "first-only")) { + send_pres = 2; + } + } + /* 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); @@ -1078,7 +1088,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (exptime && v_event && *v_event) { char *exp_var; char *allow_multireg = NULL; - int force_connectile = 0; + int auto_connectile = 0; allow_multireg = switch_event_get_header(*v_event, "sip-allow-multiple-registrations"); if (allow_multireg && switch_false(allow_multireg)) { @@ -1097,11 +1107,26 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (profile->rport_level == 3 && sip->sip_user_agent && sip->sip_user_agent->g_string && !strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7)) { - force_connectile = 1; + if (sip && sip->sip_via) { + const char *host = sip->sip_via->v_host; + const char *c_port = sip->sip_via->v_port; + int port = 0; + + if (c_port) port = atoi(c_port); + if (!port) port = 5060; + + if (host && strcmp(network_ip, host)) { + auto_connectile = 1; + } else if (port != network_port) { + auto_connectile = 1; + } + } else { + auto_connectile = 1; + } } - if ((v_contact_str = switch_event_get_header(*v_event, "sip-force-contact")) || force_connectile) { - if ((!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction-2.0")) || force_connectile) { + if ((v_contact_str = switch_event_get_header(*v_event, "sip-force-contact")) || auto_connectile) { + if ((!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction-2.0")) || auto_connectile) { char *path_encoded; size_t path_encoded_len; char my_contact_str[1024]; @@ -1314,7 +1339,9 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (sofia_reg_reg_count(profile, to_user, reg_host) == 1) { sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' and profile_name='%q' and open_closed='closed'", to_user, reg_host, profile->name); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DELETE PRESENCE SQL: %s\n", sql); + if (mod_sofia_globals.debug_presence > 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DELETE PRESENCE SQL: %s\n", sql); + } sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } @@ -1388,7 +1415,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } } - if (send && switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid); @@ -1476,27 +1502,31 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } } - if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) { - if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == 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, "login", profile->name); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence"); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); - switch_event_fire(&s_event); + if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) || + (reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER)) + || send_pres == 1 || (reg_count == 1 && send_pres == 2)) { + + if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) { + if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == 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, "login", profile->name); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); + switch_event_fire(&s_event); + } + } else { + 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, "login", profile->name); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown"); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered"); + switch_event_fire(&s_event); + } } - } else { - 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, "login", profile->name); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown"); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered"); - switch_event_fire(&s_event); - } } - } else { if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); diff --git a/src/mod/endpoints/mod_sofia/sofia_sla.c b/src/mod/endpoints/mod_sofia/sofia_sla.c index ab8a8226c5..05eba011bb 100644 --- a/src/mod/endpoints/mod_sofia/sofia_sla.c +++ b/src/mod/endpoints/mod_sofia/sofia_sla.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c index c1b4b77998..c139c053b1 100644 --- a/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c +++ b/src/mod/event_handlers/mod_cdr_csv/mod_cdr_csv.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c index 9cc1d8cf2c..5227161f23 100644 --- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c +++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005/2006, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -17,7 +17,7 @@ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * diff --git a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c index 1b91f1242a..9a286d454f 100644 --- a/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c +++ b/src/mod/event_handlers/mod_cdr_sqlite/mod_cdr_sqlite.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c index aca2497052..a99b52074c 100644 --- a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c +++ b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_erlang_event/handle_msg.c b/src/mod/event_handlers/mod_erlang_event/handle_msg.c index bb37cddc59..9ae15277fd 100644 --- a/src/mod/event_handlers/mod_erlang_event/handle_msg.c +++ b/src/mod/event_handlers/mod_erlang_event/handle_msg.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index e375515f4f..8d3c594b75 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h index eb36612ce6..dacfbd661b 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c index cb31aa220d..5c4d11e807 100644 --- a/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c +++ b/src/mod/event_handlers/mod_event_multicast/mod_event_multicast.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index 9d575dba2a..344b0ee117 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -1548,7 +1548,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even char api_reply[512] = "Allowed-API: all\n"; char log_reply[512] = ""; int allowed_log = 1; - + char *tmp; switch_clear_flag(listener, LFLAG_ALLOW_LOG); @@ -1564,8 +1564,9 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even *pass++ = '\0'; } - if ((pass = strchr(user, ':'))) { - *pass++ = '\0'; + if ((tmp = strchr(user, ':'))) { + *tmp++ = '\0'; + pass = tmp; } if (zstr(user) || zstr(domain_name)) { diff --git a/src/mod/event_handlers/mod_event_test/mod_event_test.c b/src/mod/event_handlers/mod_event_test/mod_event_test.c index ba5a2aaae4..d960b08ec5 100644 --- a/src/mod/event_handlers/mod_event_test/mod_event_test.c +++ b/src/mod/event_handlers/mod_event_test/mod_event_test.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c index 92a5d67045..c97ce1fe6e 100644 --- a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c +++ b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c index 71159654c0..440cbf90a7 100644 --- a/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c +++ b/src/mod/event_handlers/mod_radius_cdr/mod_radius_cdr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_file_string/mod_file_string.c b/src/mod/formats/mod_file_string/mod_file_string.c index a222f7bc1d..ca86cbdfcf 100644 --- a/src/mod/formats/mod_file_string/mod_file_string.c +++ b/src/mod/formats/mod_file_string/mod_file_string.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index e7c130c35b..ea94bd1cd6 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_native_file/mod_native_file.c b/src/mod/formats/mod_native_file/mod_native_file.c index 272fc5d504..d28b8dcf3a 100644 --- a/src/mod/formats/mod_native_file/mod_native_file.c +++ b/src/mod/formats/mod_native_file/mod_native_file.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c b/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c index ee320716e7..1ad1645554 100644 --- a/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c +++ b/src/mod/formats/mod_portaudio_stream/mod_portaudio_stream.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_shell_stream/mod_shell_stream.c b/src/mod/formats/mod_shell_stream/mod_shell_stream.c index 6e70ed4d61..57d4029232 100644 --- a/src/mod/formats/mod_shell_stream/mod_shell_stream.c +++ b/src/mod/formats/mod_shell_stream/mod_shell_stream.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 97f20b867a..a4965c4d67 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c b/src/mod/formats/mod_sndfile/mod_sndfile.c index 2b661ed2c2..d2c53f0ba1 100644 --- a/src/mod/formats/mod_sndfile/mod_sndfile.c +++ b/src/mod/formats/mod_sndfile/mod_sndfile.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/formats/mod_tone_stream/mod_tone_stream.c b/src/mod/formats/mod_tone_stream/mod_tone_stream.c index 6b0423574d..f02dc31cab 100644 --- a/src/mod/formats/mod_tone_stream/mod_tone_stream.c +++ b/src/mod/formats/mod_tone_stream/mod_tone_stream.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index cea764d9d6..9ccaf8ea9f 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -90,6 +90,7 @@ class Dbh { bool release(); bool connected(); bool query(char *sql, SWIGLUA_FN lua_fun); + int affected_rows(); }; } diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index aad87fa6c1..1a170dcc98 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -384,3 +384,11 @@ bool Dbh::query(char *sql, SWIGLUA_FN lua_fun) } return false; } + +int Dbh::affected_rows() +{ + if (m_connected) { + return switch_cache_db_affected_rows(dbh); + } + return 0; +} diff --git a/src/mod/languages/mod_lua/freeswitch_lua.h b/src/mod/languages/mod_lua/freeswitch_lua.h index 3c43ebdd9f..5f7966266c 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.h +++ b/src/mod/languages/mod_lua/freeswitch_lua.h @@ -63,6 +63,7 @@ namespace LUA { bool release(); bool connected(); bool query(char *sql, SWIGLUA_FN lua_fun); + int affected_rows(); }; } #endif diff --git a/src/mod/languages/mod_lua/mod_lua.cpp b/src/mod/languages/mod_lua/mod_lua.cpp index b5a4999909..56e49d5f5e 100644 --- a/src/mod/languages/mod_lua/mod_lua.cpp +++ b/src/mod/languages/mod_lua/mod_lua.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 4e2971098b..f10ed63fca 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -7296,6 +7296,31 @@ fail: } +static int _wrap_Dbh_affected_rows(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + int result; + + SWIG_check_num_args("affected_rows",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("affected_rows",1,"LUA::Dbh *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_affected_rows",1,SWIGTYPE_p_LUA__Dbh); + } + + result = (int)(arg1)->affected_rows(); + SWIG_arg=0; + lua_pushnumber(L, (lua_Number) result); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + static void swig_delete_Dbh(void *obj) { LUA::Dbh *arg1 = (LUA::Dbh *) obj; delete arg1; @@ -7304,6 +7329,7 @@ static swig_lua_method swig_LUA_Dbh_methods[] = { {"release", _wrap_Dbh_release}, {"connected", _wrap_Dbh_connected}, {"query", _wrap_Dbh_query}, + {"affected_rows", _wrap_Dbh_affected_rows}, {0,0} }; static swig_lua_attribute swig_LUA_Dbh_attributes[] = { diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index f5e9e31f72..9ebd6ff9df 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -1331,6 +1331,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("temp_hold_music"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_EXPORT_VARS_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -7112,6 +7122,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_dmachine(void * jar } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_set_codec_slin(void * jarg1, void * jarg2) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_slin_data_t *arg2 = (switch_slin_data_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (switch_slin_data_t *)jarg2; + result = (switch_status_t)switch_core_session_set_codec_slin(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_uuid() { char * jresult ; char *result = 0 ; @@ -10392,6 +10416,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_execute_sql_callback(void * ja } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_affected_rows(void * jarg1) { + int jresult ; + switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; + int result; + + arg1 = (switch_cache_db_handle_t *)jarg1; + result = (int)switch_cache_db_affected_rows(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_status(void * jarg1) { switch_stream_handle_t *arg1 = (switch_stream_handle_t *) 0 ; @@ -11972,6 +12008,30 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_digit_string(char * jarg1) { } +SWIGEXPORT char SWIGSTDCALL CSharp_switch_itodtmf(char jarg1) { + char jresult ; + char arg1 ; + char result; + + arg1 = (char)jarg1; + result = (char)switch_itodtmf(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dtmftoi(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_dtmftoi(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_known_bitrate(unsigned char jarg1) { unsigned long jresult ; switch_payload_t arg1 ; @@ -22102,6 +22162,119 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_api_interface(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_session_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_core_session_t *arg2 = (switch_core_session_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_core_session_t *)jarg2; + if (arg1) (arg1)->session = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_session_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_core_session_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_core_session_t *) ((arg1)->session); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_write_frame_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_frame_t *arg2 = (switch_frame_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_frame_t *)jarg2; + if (arg1) (arg1)->write_frame = *arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_write_frame_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_frame_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_frame_t *)& ((arg1)->write_frame); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_codec_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_codec_t *arg2 = (switch_codec_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_codec_t *)jarg2; + if (arg1) (arg1)->codec = *arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_codec_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_codec_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_codec_t *)& ((arg1)->codec); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_frame_data_set(void * jarg1, char * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + char *arg2 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (char *)jarg2; + { + if(arg2) { + strncpy((char*)arg1->frame_data, (const char *)arg2, 4096-1); + arg1->frame_data[4096-1] = 0; + } else { + arg1->frame_data[0] = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_slin_data_frame_data_get(void * jarg1) { + char * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + char *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (char *)(char *) ((arg1)->frame_data); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_slin_data() { + void * jresult ; + switch_slin_data *result = 0 ; + + result = (switch_slin_data *)new switch_slin_data(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_slin_data(void * jarg1) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_profile_created_set(void * jarg1, void * jarg2) { switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; switch_time_t arg2 ; @@ -22834,6 +23007,30 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_variable_partner(void * } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music(void * jarg1) { + char * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + result = (char *)switch_channel_get_hold_music(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music_partner(void * jarg1) { + char * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + result = (char *)switch_channel_get_hold_music_partner(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -23079,6 +23276,20 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap(void * jarg1 } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap_partner(void * jarg1, int jarg2) { + unsigned long jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_channel_cap_t arg2 ; + uint32_t result; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (switch_channel_cap_t)jarg2; + result = (uint32_t)switch_channel_test_cap_partner(arg1,arg2); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_flag_partner(void * jarg1, int jarg2) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -28362,6 +28573,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jar } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_pause_jitter_buffer(void * jarg1, int jarg2) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_bool_t arg2 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + arg2 = (switch_bool_t)jarg2; + result = (switch_status_t)switch_rtp_pause_jitter_buffer(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_flag(void * jarg1, unsigned long jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_rtp_flag_t arg2 ; @@ -33252,6 +33477,24 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_CoreSession_voice_name_get(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_insertFile(void * jarg1, char * jarg2, char * jarg3, int jarg4) { + int jresult ; + CoreSession *arg1 = (CoreSession *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + int arg4 ; + int result; + + arg1 = (CoreSession *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + arg4 = (int)jarg4; + result = (int)(arg1)->insertFile((char const *)arg2,(char const *)arg3,arg4); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Answer(void * jarg1) { int jresult ; CoreSession *arg1 = (CoreSession *) 0 ; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 33ceb470a1..aa2a84f3f6 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -1422,6 +1422,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get() { + char * jresult ; + char *result = 0 ; + + result = (char *) "temp_hold_music"; + + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_EXPORT_VARS_VARIABLE_get() { char * jresult ; char *result = 0 ; @@ -10688,6 +10699,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_execute_sql_callback(void * ja } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_cache_db_affected_rows(void * jarg1) { + int jresult ; + switch_cache_db_handle_t *arg1 = (switch_cache_db_handle_t *) 0 ; + int result; + + arg1 = (switch_cache_db_handle_t *)jarg1; + result = (int)switch_cache_db_affected_rows(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_cache_db_status(void * jarg1) { switch_stream_handle_t *arg1 = (switch_stream_handle_t *) 0 ; @@ -12292,6 +12315,30 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_is_digit_string(char * jarg1) { } +SWIGEXPORT char SWIGSTDCALL CSharp_switch_itodtmf(char jarg1) { + char jresult ; + char arg1 ; + char result; + + arg1 = (char)jarg1; + result = (char)switch_itodtmf(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_dtmftoi(char * jarg1) { + int jresult ; + char *arg1 = (char *) 0 ; + int result; + + arg1 = (char *)jarg1; + result = (int)switch_dtmftoi(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_known_bitrate(unsigned char jarg1) { unsigned long jresult ; switch_payload_t arg1 ; @@ -23489,6 +23536,30 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_variable_partner(void * } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music(void * jarg1) { + char * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + result = (char *)switch_channel_get_hold_music(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_hold_music_partner(void * jarg1) { + char * jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + char *result = 0 ; + + arg1 = (switch_channel_t *)jarg1; + result = (char *)switch_channel_get_hold_music_partner(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_export_variable_var_check(void * jarg1, char * jarg2, char * jarg3, char * jarg4, int jarg5) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -23734,6 +23805,20 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap(void * jarg1 } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_cap_partner(void * jarg1, int jarg2) { + unsigned long jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_channel_cap_t arg2 ; + uint32_t result; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (switch_channel_cap_t)jarg2; + result = (uint32_t)switch_channel_test_cap_partner(arg1,arg2); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_flag_partner(void * jarg1, int jarg2) { int jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -29065,6 +29150,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_deactivate_jitter_buffer(void * jar } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_pause_jitter_buffer(void * jarg1, int jarg2) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_bool_t arg2 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + arg2 = (switch_bool_t)jarg2; + result = (switch_status_t)switch_rtp_pause_jitter_buffer(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_flag(void * jarg1, unsigned long jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_rtp_flag_t arg2 ; diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index b792fb0ac8..059fb89a1c 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -224,6 +224,11 @@ public class CoreSession : IDisposable { } } + public int insertFile(string file, string insert_file, int sample_point) { + int ret = freeswitchPINVOKE.CoreSession_insertFile(swigCPtr, file, insert_file, sample_point); + return ret; + } + public int Answer() { int ret = freeswitchPINVOKE.CoreSession_Answer(swigCPtr); return ret; @@ -1362,6 +1367,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session session, switch_slin_data data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_slin_data.getCPtr(data)); + return ret; + } + public static string switch_core_get_uuid() { string ret = freeswitchPINVOKE.switch_core_get_uuid(); return ret; @@ -2338,6 +2348,11 @@ public class freeswitch { return ret; } + public static int switch_cache_db_affected_rows(switch_cache_db_handle_t dbh) { + int ret = freeswitchPINVOKE.switch_cache_db_affected_rows(switch_cache_db_handle_t.getCPtr(dbh)); + return ret; + } + public static void switch_cache_db_status(switch_stream_handle stream) { freeswitchPINVOKE.switch_cache_db_status(switch_stream_handle.getCPtr(stream)); } @@ -2732,6 +2747,16 @@ public class freeswitch { return ret; } + public static char switch_itodtmf(char i) { + char ret = freeswitchPINVOKE.switch_itodtmf(i); + return ret; + } + + public static int switch_dtmftoi(string s) { + int ret = freeswitchPINVOKE.switch_dtmftoi(s); + return ret; + } + public static uint switch_known_bitrate(byte payload) { uint ret = freeswitchPINVOKE.switch_known_bitrate(payload); return ret; @@ -3281,6 +3306,16 @@ public class freeswitch { return ret; } + public static string switch_channel_get_hold_music(SWIGTYPE_p_switch_channel channel) { + string ret = freeswitchPINVOKE.switch_channel_get_hold_music(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + + public static string switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel channel) { + string ret = freeswitchPINVOKE.switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string val, string export_varname, switch_bool_t var_check) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, val, export_varname, (int)var_check); return ret; @@ -3369,6 +3404,11 @@ public class freeswitch { return ret; } + public static uint switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel channel, switch_channel_cap_t cap) { + uint ret = freeswitchPINVOKE.switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)cap); + return ret; + } + public static switch_bool_t switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) { switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag); return ret; @@ -4664,6 +4704,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, switch_bool_t pause) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)pause); + return ret; + } + public static void switch_rtp_set_flag(SWIGTYPE_p_switch_rtp rtp_session, uint flags) { freeswitchPINVOKE.switch_rtp_set_flag(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), flags); } @@ -5418,6 +5463,7 @@ public class freeswitch { public static readonly string SWITCH_PROXY_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_PROXY_MEDIA_VARIABLE_get(); public static readonly string SWITCH_ENDPOINT_DISPOSITION_VARIABLE = freeswitchPINVOKE.SWITCH_ENDPOINT_DISPOSITION_VARIABLE_get(); public static readonly string SWITCH_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_HOLD_MUSIC_VARIABLE_get(); + public static readonly string SWITCH_TEMP_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get(); public static readonly string SWITCH_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_EXPORT_VARS_VARIABLE_get(); public static readonly string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get(); public static readonly string SWITCH_R_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_R_SDP_VARIABLE_get(); @@ -6010,6 +6056,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get")] public static extern string SWITCH_HOLD_MUSIC_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get")] + public static extern string SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_EXPORT_VARS_VARIABLE_get")] public static extern string SWITCH_EXPORT_VARS_VARIABLE_get(); @@ -7474,6 +7523,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_dmachine")] public static extern IntPtr switch_core_session_get_dmachine(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_codec_slin")] + public static extern int switch_core_session_set_codec_slin(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_uuid")] public static extern string switch_core_get_uuid(); @@ -8218,6 +8270,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql_callback")] public static extern int switch_cache_db_execute_sql_callback(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, ref string jarg5); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_affected_rows")] + public static extern int switch_cache_db_affected_rows(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_status")] public static extern void switch_cache_db_status(HandleRef jarg1); @@ -8590,6 +8645,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_is_digit_string")] public static extern int switch_is_digit_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_itodtmf")] + public static extern char switch_itodtmf(char jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmftoi")] + public static extern int switch_dtmftoi(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_known_bitrate")] public static extern uint switch_known_bitrate(byte jarg1); @@ -11149,6 +11210,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_api_interface")] public static extern void delete_switch_api_interface(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_set")] + public static extern void switch_slin_data_session_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_get")] + public static extern IntPtr switch_slin_data_session_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_set")] + public static extern void switch_slin_data_write_frame_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_get")] + public static extern IntPtr switch_slin_data_write_frame_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_set")] + public static extern void switch_slin_data_codec_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_get")] + public static extern IntPtr switch_slin_data_codec_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_set")] + public static extern void switch_slin_data_frame_data_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_get")] + public static extern string switch_slin_data_frame_data_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_slin_data")] + public static extern IntPtr new_switch_slin_data(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_slin_data")] + public static extern void delete_switch_slin_data(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_profile_created_set")] public static extern void switch_channel_timetable_profile_created_set(HandleRef jarg1, HandleRef jarg2); @@ -11311,6 +11402,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_partner")] public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music")] + public static extern string switch_channel_get_hold_music(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music_partner")] + public static extern string switch_channel_get_hold_music_partner(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")] public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5); @@ -11368,6 +11465,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap")] public static extern uint switch_channel_test_cap(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap_partner")] + public static extern uint switch_channel_test_cap_partner(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_flag_partner")] public static extern int switch_channel_set_flag_partner(HandleRef jarg1, int jarg2); @@ -12481,6 +12581,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")] public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_pause_jitter_buffer")] + public static extern int switch_rtp_pause_jitter_buffer(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")] public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2); @@ -13672,6 +13775,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_voice_name_get")] public static extern string CoreSession_voice_name_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_insertFile")] + public static extern int CoreSession_insertFile(HandleRef jarg1, string jarg2, string jarg3, int jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_Answer")] public static extern int CoreSession_Answer(HandleRef jarg1); @@ -21515,6 +21621,8 @@ public enum switch_channel_cap_t { CC_MEDIA_ACK = 1, CC_BYPASS_MEDIA, CC_PROXY_MEDIA, + CC_JITTERBUFFER, + CC_FS_RTP, CC_FLAG_MAX } @@ -29531,6 +29639,98 @@ public enum switch_signal_t { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_slin_data : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_slin_data(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_slin_data obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_slin_data() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_slin_data(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_core_session session { + set { + freeswitchPINVOKE.switch_slin_data_session_set(swigCPtr, SWIGTYPE_p_switch_core_session.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_session_get(swigCPtr); + SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false); + return ret; + } + } + + public switch_frame write_frame { + set { + freeswitchPINVOKE.switch_slin_data_write_frame_set(swigCPtr, switch_frame.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_write_frame_get(swigCPtr); + switch_frame ret = (cPtr == IntPtr.Zero) ? null : new switch_frame(cPtr, false); + return ret; + } + } + + public switch_codec codec { + set { + freeswitchPINVOKE.switch_slin_data_codec_set(swigCPtr, switch_codec.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_codec_get(swigCPtr); + switch_codec ret = (cPtr == IntPtr.Zero) ? null : new switch_codec(cPtr, false); + return ret; + } + } + + public string frame_data { + set { + freeswitchPINVOKE.switch_slin_data_frame_data_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_slin_data_frame_data_get(swigCPtr); + return ret; + } + } + + public switch_slin_data() : this(freeswitchPINVOKE.new_switch_slin_data(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + [System.Flags] public enum switch_speech_flag_enum_t { SWITCH_SPEECH_FLAG_NONE = 0, SWITCH_SPEECH_FLAG_HASTEXT = (1 << 0), diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index e51b050b25..5a2188ac83 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -2333,6 +2333,11 @@ public class freeswitch { return ret; } + public static int switch_cache_db_affected_rows(switch_cache_db_handle_t dbh) { + int ret = freeswitchPINVOKE.switch_cache_db_affected_rows(switch_cache_db_handle_t.getCPtr(dbh)); + return ret; + } + public static void switch_cache_db_status(switch_stream_handle stream) { freeswitchPINVOKE.switch_cache_db_status(switch_stream_handle.getCPtr(stream)); } @@ -2727,6 +2732,16 @@ public class freeswitch { return ret; } + public static char switch_itodtmf(char i) { + char ret = freeswitchPINVOKE.switch_itodtmf(i); + return ret; + } + + public static int switch_dtmftoi(string s) { + int ret = freeswitchPINVOKE.switch_dtmftoi(s); + return ret; + } + public static uint switch_known_bitrate(byte payload) { uint ret = freeswitchPINVOKE.switch_known_bitrate(payload); return ret; @@ -3276,6 +3291,16 @@ public class freeswitch { return ret; } + public static string switch_channel_get_hold_music(SWIGTYPE_p_switch_channel channel) { + string ret = freeswitchPINVOKE.switch_channel_get_hold_music(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + + public static string switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel channel) { + string ret = freeswitchPINVOKE.switch_channel_get_hold_music_partner(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + public static switch_status_t switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel channel, string varname, string val, string export_varname, switch_bool_t var_check) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_export_variable_var_check(SWIGTYPE_p_switch_channel.getCPtr(channel), varname, val, export_varname, (int)var_check); return ret; @@ -3364,6 +3389,11 @@ public class freeswitch { return ret; } + public static uint switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel channel, switch_channel_cap_t cap) { + uint ret = freeswitchPINVOKE.switch_channel_test_cap_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)cap); + return ret; + } + public static switch_bool_t switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) { switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag); return ret; @@ -4659,6 +4689,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, switch_bool_t pause) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_pause_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)pause); + return ret; + } + public static void switch_rtp_set_flag(SWIGTYPE_p_switch_rtp rtp_session, uint flags) { freeswitchPINVOKE.switch_rtp_set_flag(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), flags); } @@ -5413,6 +5448,7 @@ public class freeswitch { public static readonly string SWITCH_PROXY_MEDIA_VARIABLE = freeswitchPINVOKE.SWITCH_PROXY_MEDIA_VARIABLE_get(); public static readonly string SWITCH_ENDPOINT_DISPOSITION_VARIABLE = freeswitchPINVOKE.SWITCH_ENDPOINT_DISPOSITION_VARIABLE_get(); public static readonly string SWITCH_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_HOLD_MUSIC_VARIABLE_get(); + public static readonly string SWITCH_TEMP_HOLD_MUSIC_VARIABLE = freeswitchPINVOKE.SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get(); public static readonly string SWITCH_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_EXPORT_VARS_VARIABLE_get(); public static readonly string SWITCH_BRIDGE_EXPORT_VARS_VARIABLE = freeswitchPINVOKE.SWITCH_BRIDGE_EXPORT_VARS_VARIABLE_get(); public static readonly string SWITCH_R_SDP_VARIABLE = freeswitchPINVOKE.SWITCH_R_SDP_VARIABLE_get(); @@ -6001,6 +6037,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_HOLD_MUSIC_VARIABLE_get")] public static extern string SWITCH_HOLD_MUSIC_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get")] + public static extern string SWITCH_TEMP_HOLD_MUSIC_VARIABLE_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_EXPORT_VARS_VARIABLE_get")] public static extern string SWITCH_EXPORT_VARS_VARIABLE_get(); @@ -8209,6 +8248,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_execute_sql_callback")] public static extern int switch_cache_db_execute_sql_callback(HandleRef jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4, ref string jarg5); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_affected_rows")] + public static extern int switch_cache_db_affected_rows(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_cache_db_status")] public static extern void switch_cache_db_status(HandleRef jarg1); @@ -8581,6 +8623,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_is_digit_string")] public static extern int switch_is_digit_string(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_itodtmf")] + public static extern char switch_itodtmf(char jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmftoi")] + public static extern int switch_dtmftoi(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_known_bitrate")] public static extern uint switch_known_bitrate(byte jarg1); @@ -11302,6 +11350,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_variable_partner")] public static extern string switch_channel_get_variable_partner(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music")] + public static extern string switch_channel_get_hold_music(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_hold_music_partner")] + public static extern string switch_channel_get_hold_music_partner(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_export_variable_var_check")] public static extern int switch_channel_export_variable_var_check(HandleRef jarg1, string jarg2, string jarg3, string jarg4, int jarg5); @@ -11359,6 +11413,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap")] public static extern uint switch_channel_test_cap(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_cap_partner")] + public static extern uint switch_channel_test_cap_partner(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_flag_partner")] public static extern int switch_channel_set_flag_partner(HandleRef jarg1, int jarg2); @@ -12472,6 +12529,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_deactivate_jitter_buffer")] public static extern int switch_rtp_deactivate_jitter_buffer(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_pause_jitter_buffer")] + public static extern int switch_rtp_pause_jitter_buffer(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_flag")] public static extern void switch_rtp_set_flag(HandleRef jarg1, uint jarg2); @@ -21469,6 +21529,8 @@ public enum switch_channel_cap_t { CC_MEDIA_ACK = 1, CC_BYPASS_MEDIA, CC_PROXY_MEDIA, + CC_JITTERBUFFER, + CC_FS_RTP, CC_FLAG_MAX } diff --git a/src/mod/languages/mod_perl/mod_perl.c b/src/mod/languages/mod_perl/mod_perl.c index 716a6e39e3..55bc44f2de 100644 --- a/src/mod/languages/mod_perl/mod_perl.c +++ b/src/mod/languages/mod_perl/mod_perl.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp index c22905285d..e8a4b9f409 100644 --- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp +++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp @@ -9793,17 +9793,17 @@ XS(SWIG_init) { SWIG_TypeClientData(SWIGTYPE_p_IVRMenu, (void*) "freeswitch::IVRMenu"); SWIG_TypeClientData(SWIGTYPE_p_API, (void*) "freeswitch::API"); SWIG_TypeClientData(SWIGTYPE_p_input_callback_state, (void*) "freeswitch::input_callback_state_t"); - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_HUP", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_HUP))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_FREE", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_FREE))); SvREADONLY_on(sv); } while(0) /*@SWIG@*/; - /*@SWIG:/usr/local/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { + /*@SWIG:/usr/share/swig/1.3.35/perl5/perltypemaps.swg,64,%set_constant@*/ do { SV *sv = get_sv((char*) SWIG_prefix "S_RDLOCK", TRUE | 0x2 | GV_ADDMULTI); sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(S_RDLOCK))); SvREADONLY_on(sv); diff --git a/src/mod/languages/mod_python/mod_python.c b/src/mod/languages/mod_python/mod_python.c index 7e15a5226a..bcaebd8856 100644 --- a/src/mod/languages/mod_python/mod_python.c +++ b/src/mod/languages/mod_python/mod_python.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c index 16679d7ffa..9eb2636f4a 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h index 1fbe066d00..aeb0245f11 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_core_db.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_core_db.c index 25333149ed..e7a68a632f 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_core_db.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_core_db.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_curl.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_curl.c index fe489af806..5fb7b7f0be 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_curl.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_curl.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c index c205e6e432..e60d8ce793 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_odbc.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_skel.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_skel.c index 9717ff8cbf..7bc73d07e7 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_skel.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_skel.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_teletone.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_teletone.c index d68e87c4a9..4f142dbc2f 100644 --- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey_teletone.c +++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey_teletone.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/languages/mod_yaml/mod_yaml.c b/src/mod/languages/mod_yaml/mod_yaml.c index 1571570b3c..7142997868 100644 --- a/src/mod/languages/mod_yaml/mod_yaml.c +++ b/src/mod/languages/mod_yaml/mod_yaml.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/loggers/mod_console/mod_console.c b/src/mod/loggers/mod_console/mod_console.c index 7a9c471f9e..06956708fc 100644 --- a/src/mod/loggers/mod_console/mod_console.c +++ b/src/mod/loggers/mod_console/mod_console.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/say/mod_say_ru/mod_say_ru.c b/src/mod/say/mod_say_ru/mod_say_ru.c index 9b9fcda896..21e3017ef9 100644 --- a/src/mod/say/mod_say_ru/mod_say_ru.c +++ b/src/mod/say/mod_say_ru/mod_say_ru.c @@ -31,13 +31,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The Initial Developer of the Original Code is - * Anthony Minessale II + * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * Contributor(s): * - * Anthony Minessale II + * Anthony Minessale II * Michael B. Murdock * Boris Buklov (BBV) * 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 84643dcd0b..a439ab8203 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 @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c index e0cda427b6..9bf837e1e4 100644 --- a/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c +++ b/src/mod/xml_int/mod_xml_curl/mod_xml_curl.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c index b374665189..e58377ef5a 100644 --- a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * 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 2e9a1a3a1a..468190d887 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 @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -744,6 +744,7 @@ abyss_bool handler_hook(TSession * r) if (dateValue) { ResponseAddField(r, "Date", dateValue); + free(dateValue); } } diff --git a/src/switch.c b/src/switch.c index ef69bee34e..65b2eeb21a 100644 --- a/src/switch.c +++ b/src/switch.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_apr.c b/src/switch_apr.c index 2e7d8f7c88..efbed0a490 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_buffer.c b/src/switch_buffer.c index 09d3219d31..39d7bf04a1 100644 --- a/src/switch_buffer.c +++ b/src/switch_buffer.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_caller.c b/src/switch_caller.c index 5d5d1ab4ca..d0d242fe90 100644 --- a/src/switch_caller.c +++ b/src/switch_caller.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_channel.c b/src/switch_channel.c index aa7f6699b7..918ad82a99 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -362,11 +362,11 @@ SWITCH_DECLARE(switch_status_t) switch_channel_queue_dtmf(switch_channel_t *chan int x = 0; if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", switch_channel_get_name(channel), new_dtmf.digit, new_dtmf.duration); new_dtmf.duration = switch_core_max_dtmf_duration(0); } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", switch_channel_get_name(channel), new_dtmf.digit, new_dtmf.duration); new_dtmf.duration = switch_core_min_dtmf_duration(0); } else if (!new_dtmf.duration) { @@ -646,6 +646,30 @@ SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_ } +SWITCH_DECLARE(const char *) switch_channel_get_hold_music(switch_channel_t *channel) +{ + const char *var; + + if (!(var = switch_channel_get_variable(channel, SWITCH_TEMP_HOLD_MUSIC_VARIABLE))) { + var = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE); + } + + return var; +} + +SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channel_t *channel) +{ + switch_core_session_t *session; + const char *r = NULL; + + if (switch_core_session_get_partner(channel->session, &session) == SWITCH_STATUS_SUCCESS) { + r = switch_channel_get_hold_music(switch_core_session_get_channel(session)); + switch_core_session_rwunlock(session); + } + + return r; +} + SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup) { const char *v = NULL, *r = NULL; @@ -1261,6 +1285,24 @@ SWITCH_DECLARE(uint32_t) switch_channel_test_cap(switch_channel_t *channel, swit return channel->caps[cap] ? 1 : 0; } +SWITCH_DECLARE(uint32_t) switch_channel_test_cap_partner(switch_channel_t *channel, switch_channel_cap_t cap) +{ + const char *uuid; + int r = 0; + + switch_assert(channel != NULL); + + if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { + switch_core_session_t *session; + if ((session = switch_core_session_locate(uuid))) { + r = switch_channel_test_cap(switch_core_session_get_channel(session), cap); + switch_core_session_rwunlock(session); + } + } + + return r; +} + SWITCH_DECLARE(char *) switch_channel_get_flag_string(switch_channel_t *channel) { switch_stream_handle_t stream = { 0 }; diff --git a/src/switch_config.c b/src/switch_config.c index 5de08ba39d..912094024e 100644 --- a/src/switch_config.c +++ b/src/switch_config.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_console.c b/src/switch_console.c index 7f2ce6f7ab..38263df383 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core.c b/src/switch_core.c index 0b5fbd7051..360d810ead 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_asr.c b/src/switch_core_asr.c index fa4446ec46..a040366ad0 100644 --- a/src/switch_core_asr.c +++ b/src/switch_core_asr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index d6b627093e..96f8d57726 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_db.c b/src/switch_core_db.c index 9f557cf590..b3cd2ceff8 100644 --- a/src/switch_core_db.c +++ b/src/switch_core_db.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_directory.c b/src/switch_core_directory.c index 7d33008429..5ff4e05c6c 100644 --- a/src/switch_core_directory.c +++ b/src/switch_core_directory.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_event_hook.c b/src/switch_core_event_hook.c index 102ea20776..9cfe1ac79f 100644 --- a/src/switch_core_event_hook.c +++ b/src/switch_core_event_hook.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_file.c b/src/switch_core_file.c index 76b6b29fad..c00756ffc6 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_hash.c b/src/switch_core_hash.c index 2b62258bd1..8d04e9c5f3 100644 --- a/src/switch_core_hash.c +++ b/src/switch_core_hash.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 49956b3172..decb587ef7 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -1265,11 +1265,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio new_dtmf = *dtmf; if (new_dtmf.duration > switch_core_max_dtmf_duration(0)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s EXCESSIVE DTMF DIGIT [%c] LEN [%d]\n", switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); new_dtmf.duration = switch_core_max_dtmf_duration(0); } else if (new_dtmf.duration < switch_core_min_dtmf_duration(0)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s SHORT DTMF DIGIT [%c] LEN [%d]\n", switch_channel_get_name(session->channel), new_dtmf.digit, new_dtmf.duration); new_dtmf.duration = switch_core_min_dtmf_duration(0); } else if (!new_dtmf.duration) { diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index 21db3a9aff..1e7b260078 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index a63ce0d6f9..dd87f8f4a2 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_port_allocator.c b/src/switch_core_port_allocator.c index 49a44b9248..580e45bd91 100644 --- a/src/switch_core_port_allocator.c +++ b/src/switch_core_port_allocator.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_rwlock.c b/src/switch_core_rwlock.c index 57168d9a29..09c50cb604 100644 --- a/src/switch_core_rwlock.c +++ b/src/switch_core_rwlock.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 252b5e205b..4836aae73f 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -58,6 +58,39 @@ SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *sess session->soft_lock = 0; } +SWITCH_DECLARE(switch_status_t) switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data) + +{ + switch_codec_implementation_t read_impl = { 0 }; + int interval; + + switch_core_session_get_read_impl(session, &read_impl); + interval = read_impl.microseconds_per_packet / 1000; + data->session = session; + + if (switch_core_codec_init(&data->codec, + "L16", + NULL, + read_impl.actual_samples_per_second, + interval, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %dms\n", read_impl.actual_samples_per_second, interval); + + memset(&data->write_frame, 0, sizeof(data->write_frame)); + + data->write_frame.codec = &data->codec; + data->write_frame.data = data->frame_data; + data->write_frame.buflen = sizeof(data->frame_data); + data->write_frame.datalen = 0; + switch_core_session_set_read_codec(session, &data->codec); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + + #ifdef SWITCH_DEBUG_RWLOCKS SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_locate(const char *uuid_str, const char *file, const char *func, int line) #else diff --git a/src/switch_core_speech.c b/src/switch_core_speech.c index 81ce5d3e2e..12b60538d1 100644 --- a/src/switch_core_speech.c +++ b/src/switch_core_speech.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index b561ebe775..4167b4a89c 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -573,6 +573,24 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_hand } +SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh) +{ + switch (dbh->type) { + case SCDB_TYPE_CORE_DB: + { + return switch_core_db_changes(dbh->native_handle.core_db_dbh); + } + break; + case SCDB_TYPE_ODBC: + { + return switch_odbc_handle_affected_rows(dbh->native_handle.odbc_dbh); + } + break; + } + return 0; +} + + SWITCH_DECLARE(char *) switch_cache_db_execute_sql2str(switch_cache_db_handle_t *dbh, char *sql, char *str, size_t len, char **err) { switch_status_t status = SWITCH_STATUS_FALSE; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index ccd6dacc9c..276acb8585 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_core_timer.c b/src/switch_core_timer.c index 8d563b08b5..1798442509 100644 --- a/src/switch_core_timer.c +++ b/src/switch_core_timer.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 88af2423ca..bbcd05d21c 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_event.c b/src/switch_event.c index dce42f8e29..003fc82296 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -744,7 +744,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *even tp = tp->next; x++; - switch_assert(x < 1000); + switch_assert(x < 1000000); hash = switch_ci_hashfunc_default(header_name, &hlen); if ((!hp->hash || hash == hp->hash) && !strcasecmp(header_name, hp->name) && (zstr(val) || !strcmp(hp->value, val))) { diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 82c6ff4791..496c29b524 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -540,8 +540,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se const char *stream; b_uuid = switch_core_session_strdup(session, b_uuid); - if (!(stream = switch_channel_get_variable_partner(channel, SWITCH_HOLD_MUSIC_VARIABLE))) { - stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE); + if (!(stream = switch_channel_get_hold_music_partner(channel))) { + stream = switch_channel_get_hold_music(channel); } if (stream && switch_is_moh(stream)) { @@ -1269,7 +1269,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_hold(switch_core_session_t *session, switch_core_session_receive_message(session, &msg); - if (moh && (stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE))) { + if (moh && (stream = switch_channel_get_hold_music(channel))) { if ((other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { switch_ivr_broadcast(other_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP); } @@ -1514,6 +1514,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ /* clear all state handlers */ switch_channel_clear_state_handler(channel, NULL); + /* reset temp hold music */ + switch_channel_set_variable(channel, SWITCH_TEMP_HOLD_MUSIC_VARIABLE, NULL); + if ((profile = switch_channel_get_caller_profile(channel))) { const char *var; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 5d35524e25..4354f0dc0d 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -2727,7 +2727,7 @@ typedef struct { } dtmf_meta_app_t; typedef struct { - dtmf_meta_app_t map[10]; + dtmf_meta_app_t map[14]; time_t last_digit; switch_bool_t meta_on; char meta; @@ -2825,11 +2825,11 @@ static switch_status_t meta_on_dtmf(switch_core_session_t *session, const switch } if (md->sr[direction].meta_on) { - if (dtmf->digit >= '0' && dtmf->digit <= '9') { + if (is_dtmf(dtmf->digit)) { int ok = 0; *digit = dtmf->digit; - dval = atoi(digit); - + dval = switch_dtmftoi(digit); + if (direction == SWITCH_DTMF_RECV && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_ALEG)) { ok = 1; } else if (direction == SWITCH_DTMF_SEND && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_BLEG)) { @@ -2974,14 +2974,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_bind_dtmf_meta_session(switch_core_se if (meta != '*' && meta != '#') { str[0] = meta; - if (atoi(str) == (int)key) { + if (switch_dtmftoi(str) == (char)key) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u, same as META CHAR\n", key); return SWITCH_STATUS_FALSE; } } - if (key > 9) { + if (key > 13) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u\n", key); return SWITCH_STATUS_FALSE; } @@ -3000,8 +3000,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_bind_dtmf_meta_session(switch_core_se md->sr[SWITCH_DTMF_RECV].map[key].app = switch_core_session_strdup(session, app); md->sr[SWITCH_DTMF_RECV].map[key].flags |= SMF_HOLD_BLEG; md->sr[SWITCH_DTMF_RECV].map[key].bind_flags = bind_flags; - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound A-Leg: %c%d %s\n", meta, key, app); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound A-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app); } if ((bind_flags & SBF_DIAL_BLEG)) { md->sr[SWITCH_DTMF_SEND].meta = meta; @@ -3009,12 +3009,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_bind_dtmf_meta_session(switch_core_se md->sr[SWITCH_DTMF_SEND].map[key].app = switch_core_session_strdup(session, app); md->sr[SWITCH_DTMF_SEND].map[key].flags |= SMF_HOLD_BLEG; md->sr[SWITCH_DTMF_SEND].map[key].bind_flags = bind_flags; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound B-Leg: %c%d %s\n", meta, key, app); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound B-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app); } } else { if ((bind_flags & SBF_DIAL_ALEG)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: %c%d\n", meta, key); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: %c%c\n", meta, switch_itodtmf((char)key)); md->sr[SWITCH_DTMF_SEND].map[key].app = NULL; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound: B-Leg %c%d\n", meta, key); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index aa5ddb9232..6f84de3893 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -315,6 +315,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if (read_frame_count > DEFAULT_LEAD_FRAMES && switch_channel_media_ack(chan_a) && switch_core_session_private_event_count(session_a)) { switch_channel_set_flag(chan_b, CF_SUSPEND); + msg.numeric_arg = 42; msg.string_arg = data->b_uuid; msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; msg.from = __FILE__; @@ -1141,7 +1142,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA) || switch_channel_test_flag(peer_channel, CF_RING_READY)) { const char *app, *data; - + switch_channel_set_state(peer_channel, CS_CONSUME_MEDIA); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { @@ -1184,6 +1185,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses } } + switch_channel_wait_for_flag(peer_channel, CF_BROADCAST, SWITCH_FALSE, 10000, caller_channel); + switch_ivr_parse_all_events(peer_session); + switch_ivr_parse_all_events(session); + msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; msg.from = __FILE__; msg.string_arg = switch_core_session_strdup(peer_session, switch_core_session_get_uuid(session)); diff --git a/src/switch_ivr_menu.c b/src/switch_ivr_menu.c index 255ab61c76..c70db2399d 100644 --- a/src/switch_ivr_menu.c +++ b/src/switch_ivr_menu.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 28af589518..d156c700fd 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -1705,6 +1705,16 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * switch_channel_get_state(_peer) == CS_RESET || \ !switch_channel_test_flag(_peer, CF_ORIGINATING))) +static void wait_for_cause(switch_channel_t *channel) +{ + int sanity = 5; + + while (--sanity > 0 && peer_eligible(channel) && switch_channel_get_cause(channel) == SWITCH_CAUSE_NONE) { + switch_yield(10000); + } +} + + SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *session, switch_core_session_t **bleg, @@ -2602,6 +2612,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } + if (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "push_channel_name"))) { + char *new_name = switch_core_session_sprintf(session, "%s__B", switch_channel_get_name(caller_channel)); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_channel_name", new_name); + new_name = switch_core_session_sprintf(session, "_%s", switch_channel_get_name(caller_channel)); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Channel-Name", new_name); + } + /* make a special var event with mixture of the {} and the [] vars to pass down as global vars to the outgoing channel so if something like the user channel does another originate our options will be passed down properly */ @@ -2690,6 +2707,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (switch_true(switch_channel_get_variable(originate_status[i].peer_channel, "leg_required"))) { originate_status[i].tagged = 1; } + + if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_channel_name"))) { + switch_channel_set_name(originate_status[i].peer_channel, vvar); + } if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_callee_id_name"))) { switch_channel_set_profile_var(originate_status[i].peer_channel, "callee_id_name", vvar); @@ -3260,7 +3281,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (i != oglobals.idx) { holding = NULL; - + if (oglobals.idx == IDX_TIMEOUT || to) { reason = SWITCH_CAUSE_NO_ANSWER; } else { @@ -3269,6 +3290,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } else { if (and_argc > 1) { reason = SWITCH_CAUSE_LOSE_RACE; + } else if (!switch_channel_ready(originate_status[i].peer_channel)) { + wait_for_cause(originate_status[i].peer_channel); + if (switch_channel_down(originate_status[i].peer_channel)) { + reason = switch_channel_get_cause(originate_status[i].peer_channel); + } } else { reason = SWITCH_CAUSE_NO_ANSWER; } @@ -3374,6 +3400,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } if (peer_channel) { + wait_for_cause(peer_channel); *cause = switch_channel_get_cause(peer_channel); } else { for (i = 0; i < and_argc; i++) { @@ -3424,6 +3451,19 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess *cause = switch_channel_get_cause(caller_channel); } else { *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + for (i = 0; i < and_argc; i++) { + if (!peer_eligible(originate_status[i].peer_channel)) { + continue; + } + + wait_for_cause(originate_status[i].peer_channel); + + if (switch_channel_down(originate_status[i].peer_channel)) { + *cause = switch_channel_get_cause(originate_status[i].peer_channel); + break; + } + + } } } @@ -3518,7 +3558,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess continue; } pchannel = switch_core_session_get_channel(originate_status[i].peer_session); - + wait_for_cause(pchannel); if (switch_channel_down(pchannel)) { cause_str = switch_channel_cause2str(switch_channel_get_cause(pchannel)); if (switch_stristr(cause_str, fail_on_single_reject_var)) { diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index b983d5ed91..523dfdeb02 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -2394,7 +2394,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess if (moh_b) { moh = moh_b; } else { - moh = switch_channel_get_variable(other_channel, "hold_music"); + moh = switch_channel_get_hold_music(other_channel); } if (!zstr(moh) && strcasecmp(moh, "silence") && !switch_channel_test_flag(other_channel, CF_BROADCAST)) { @@ -2405,7 +2405,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess if (moh_a) { moh = moh_a; } else { - moh = switch_channel_get_variable(channel, "hold_music"); + moh = switch_channel_get_hold_music(channel); } if (!zstr(moh) && strcasecmp(moh, "silence")) { diff --git a/src/switch_ivr_say.c b/src/switch_ivr_say.c index 23be59edaa..9ba60fb5d5 100644 --- a/src/switch_ivr_say.c +++ b/src/switch_ivr_say.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index c603e27459..03858aca29 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_log.c b/src/switch_log.c index c7307fdc02..d195b6e585 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_odbc.c b/src/switch_odbc.c index 5a88ba7690..a7c2153304 100644 --- a/src/switch_odbc.c +++ b/src/switch_odbc.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -56,6 +56,8 @@ struct switch_odbc_handle { switch_odbc_state_t state; char odbc_driver[256]; BOOL is_firebird; + int affected_rows; + int num_retries; }; #endif @@ -88,6 +90,8 @@ SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, c new_handle->env = SQL_NULL_HANDLE; new_handle->state = SWITCH_ODBC_STATE_INIT; + new_handle->affected_rows = 0; + new_handle->num_retries = DEFAULT_ODBC_RETRIES; return new_handle; @@ -102,6 +106,15 @@ SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, c return NULL; } +SWITCH_DECLARE(void) switch_odbc_set_num_retries(switch_odbc_handle_t *handle, int num_retries) +{ +#ifdef SWITCH_HAVE_ODBC + if (handle) { + handle->num_retries = num_retries; + } +#endif +} + SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle) { #ifdef SWITCH_HAVE_ODBC @@ -131,6 +144,53 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_h #ifdef SWITCH_HAVE_ODBC +static switch_odbc_status_t init_odbc_handles(switch_odbc_handle_t *handle, switch_bool_t do_reinit) +{ + int result; + + if (!handle) { + return SWITCH_ODBC_FAIL; + } + + /* if handle is already initialized, and we're supposed to reinit - free old handle first */ + if (do_reinit == SWITCH_TRUE && handle->env != SQL_NULL_HANDLE) { + SQLFreeHandle(SQL_HANDLE_DBC, handle->con); + SQLFreeHandle(SQL_HANDLE_ENV, handle->env); + handle->env = SQL_NULL_HANDLE; + } + + if (handle->env == SQL_NULL_HANDLE) { + result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHandle\n"); + handle->env = SQL_NULL_HANDLE; /* Reset handle value, just in case */ + return SWITCH_ODBC_FAIL; + } + + result = SQLSetEnvAttr(handle->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SetEnv\n"); + SQLFreeHandle(SQL_HANDLE_ENV, handle->env); + handle->env = SQL_NULL_HANDLE; /* Reset handle value after it's freed */ + return SWITCH_ODBC_FAIL; + } + + result = SQLAllocHandle(SQL_HANDLE_DBC, handle->env, &handle->con); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHDB %d\n", result); + SQLFreeHandle(SQL_HANDLE_ENV, handle->env); + handle->env = SQL_NULL_HANDLE; /* Reset handle value after it's freed */ + return SWITCH_ODBC_FAIL; + } + SQLSetConnectAttr(handle->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0); + } + + return SWITCH_ODBC_SUCCESS; +} + static int db_is_up(switch_odbc_handle_t *handle) { int ret = 0; @@ -141,12 +201,18 @@ static int db_is_up(switch_odbc_handle_t *handle) switch_odbc_status_t recon = 0; char *err_str = NULL; SQLCHAR sql[255] = ""; - int max_tries = 120; + int max_tries = DEFAULT_ODBC_RETRIES; int code = 0; SQLRETURN rc; SQLSMALLINT nresultcols; + if (handle) { + max_tries = handle->num_retries; + if (max_tries < 1) + max_tries = DEFAULT_ODBC_RETRIES; + } + top: if (!handle) { @@ -165,6 +231,8 @@ static int db_is_up(switch_odbc_handle_t *handle) goto error; } + SQLSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER)30, 0); + if (SQLPrepare(stmt, sql, SQL_NTS) != SQL_SUCCESS) { code = __LINE__; goto error; @@ -195,6 +263,13 @@ static int db_is_up(switch_odbc_handle_t *handle) error: err_str = switch_odbc_handle_get_error(handle, stmt); + + /* Make sure to free the handle before we try to reconnect */ + if (stmt) { + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + stmt = NULL; + } + recon = switch_odbc_handle_connect(handle); max_tries--; @@ -224,11 +299,6 @@ static int db_is_up(switch_odbc_handle_t *handle) goto done; } - if (stmt) { - SQLFreeHandle(SQL_HANDLE_STMT, stmt); - stmt = NULL; - } - switch_safe_free(err_str); switch_yield(1000000); goto top; @@ -270,31 +340,8 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand SQLSMALLINT valueLength = 0; int i = 0; - if (handle->env == SQL_NULL_HANDLE) { - result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env); + init_odbc_handles(handle, SWITCH_FALSE); /* Init ODBC handles, if they are already initialized, don't do it again */ - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHandle\n"); - return SWITCH_ODBC_FAIL; - } - - result = SQLSetEnvAttr(handle->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0); - - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SetEnv\n"); - SQLFreeHandle(SQL_HANDLE_ENV, handle->env); - return SWITCH_ODBC_FAIL; - } - - result = SQLAllocHandle(SQL_HANDLE_DBC, handle->env, &handle->con); - - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHDB %d\n", result); - SQLFreeHandle(SQL_HANDLE_ENV, handle->env); - return SWITCH_ODBC_FAIL; - } - SQLSetConnectAttr(handle->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0); - } if (handle->state == SWITCH_ODBC_STATE_CONNECTED) { switch_odbc_handle_disconnect(handle); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Re-connecting %s\n", handle->dsn); @@ -321,7 +368,9 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand SQLGetDiagRec(SQL_HANDLE_DBC, handle->con, 1, stat, &err, msg, 100, &mlen); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SQLConnect=%d errno=%d %s\n", result, (int) err, msg); } - SQLFreeHandle(SQL_HANDLE_ENV, handle->env); + + /* Deallocate handles again, more chanses to succeed when reconnecting */ + init_odbc_handles(handle, SWITCH_TRUE); /* Reinit ODBC handles */ return SWITCH_ODBC_FAIL; } @@ -353,12 +402,15 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec_string(switch_odbc_ SQLCHAR name[1024]; SQLLEN m = 0; + handle->affected_rows = 0; + if (switch_odbc_handle_exec(handle, sql, &stmt, err) == SWITCH_ODBC_SUCCESS) { SQLSMALLINT NameLength, DataType, DecimalDigits, Nullable; SQLULEN ColumnSize; int result; SQLRowCount(stmt, &m); + handle->affected_rows = (int) m; if (m <= 0) { goto done; @@ -393,6 +445,9 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_ SQLHSTMT stmt = NULL; int result; char *err_str = NULL; + SQLLEN m = 0; + + handle->affected_rows = 0; if (!db_is_up(handle)) { goto error; @@ -412,6 +467,9 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_exec(switch_odbc_handle_ goto error; } + SQLRowCount(stmt, &m); + handle->affected_rows = (int) m; + if (rstmt) { *rstmt = stmt; } else { @@ -460,6 +518,8 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c int err_cnt = 0; int done = 0; + handle->affected_rows = 0; + switch_assert(callback != NULL); if (!db_is_up(handle)) { @@ -484,6 +544,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c SQLNumResultCols(stmt, &c); SQLRowCount(stmt, &m); + handle->affected_rows = (int) m; while (!done) { @@ -538,6 +599,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c } SQLFreeHandle(SQL_HANDLE_STMT, stmt); + stmt = NULL; /* Make sure we don't try to free this handle again */ if (!err_cnt) { return SWITCH_ODBC_SUCCESS; @@ -577,8 +639,10 @@ SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep) if (handle) { switch_odbc_handle_disconnect(handle); - SQLFreeHandle(SQL_HANDLE_DBC, handle->con); - SQLFreeHandle(SQL_HANDLE_ENV, handle->env); + if (handle->env != SQL_NULL_HANDLE) { + SQLFreeHandle(SQL_HANDLE_DBC, handle->con); + SQLFreeHandle(SQL_HANDLE_ENV, handle->env); + } switch_safe_free(handle->dsn); switch_safe_free(handle->username); switch_safe_free(handle->password); @@ -619,6 +683,15 @@ SWITCH_DECLARE(char *) switch_odbc_handle_get_error(switch_odbc_handle_t *handle #endif } +SWITCH_DECLARE(int) switch_odbc_handle_affected_rows(switch_odbc_handle_t *handle) +{ +#ifdef SWITCH_HAVE_ODBC + return handle->affected_rows; +#else + return 0; +#endif +} + SWITCH_DECLARE(switch_bool_t) switch_odbc_available(void) { #ifdef SWITCH_HAVE_ODBC diff --git a/src/switch_pcm.c b/src/switch_pcm.c index 8f8b06c4c5..8fbfefed10 100644 --- a/src/switch_pcm.c +++ b/src/switch_pcm.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_regex.c b/src/switch_regex.c index 38c527cc0a..787ab0dcf4 100644 --- a/src/switch_regex.c +++ b/src/switch_regex.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_resample.c b/src/switch_resample.c index 65ebe3c32f..10c633c01a 100644 --- a/src/switch_resample.c +++ b/src/switch_resample.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 5c4aa307fd..4e5450d7e8 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -126,6 +126,7 @@ struct switch_rtp_rfc2833_data { uint16_t in_digit_seq; uint32_t in_digit_ts; uint32_t in_digit_sanity; + uint32_t in_interleaved; uint32_t timestamp_dtmf; uint16_t last_duration; uint32_t flip; @@ -133,6 +134,7 @@ struct switch_rtp_rfc2833_data { char last_digit; switch_queue_t *dtmf_inqueue; switch_mutex_t *dtmf_mutex; + uint8_t in_digit_queued; }; struct switch_rtp { @@ -242,6 +244,7 @@ struct switch_rtp { switch_time_t send_time; switch_byte_t auto_adj_used; + uint8_t pause_jb; }; struct switch_rtcp_senderinfo { @@ -1640,6 +1643,26 @@ static void jb_callback(stfu_instance_t *i, void *udata) } +SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause) +{ + + if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) { + return SWITCH_STATUS_FALSE; + } + + if (!!pause == !!rtp_session->pause_jb) { + return SWITCH_STATUS_FALSE; + } + + if (rtp_session->pause_jb && !pause) { + stfu_n_reset(rtp_session->jb); + } + + rtp_session->pause_jb = pause ? 1 : 0; + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session) { @@ -2174,7 +2197,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t ts = ntohl(rtp_session->recv_msg.header.ts); if (*bytes && (!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) && - ts && !rtp_session->jb && ts == rtp_session->last_cng_ts) { + ts && !rtp_session->jb && !rtp_session->pause_jb && ts == rtp_session->last_cng_ts) { /* we already sent this frame..... */ *bytes = 0; return SWITCH_STATUS_SUCCESS; @@ -2204,7 +2227,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->last_read_ts = ts; - if (rtp_session->jb && rtp_session->recv_msg.header.version == 2 && *bytes) { + if (rtp_session->jb && !rtp_session->pause_jb && rtp_session->recv_msg.header.version == 2 && *bytes) { if (rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) { stfu_n_reset(rtp_session->jb); @@ -2217,7 +2240,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t status = SWITCH_STATUS_FALSE; } - if (rtp_session->jb && !rtp_session->checked_jb) { + if (rtp_session->jb && !rtp_session->pause_jb && !rtp_session->checked_jb) { if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) { memcpy(rtp_session->recv_msg.body, jb_frame->data, jb_frame->dlen); @@ -2417,6 +2440,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ recvfrom: bytes = 0; read_loops++; + poll_loop = 0; if (!switch_rtp_ready(rtp_session)) { break; @@ -2443,26 +2467,41 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ status = read_rtp_packet(rtp_session, &bytes, flags); } else { if (!SWITCH_STATUS_IS_BREAK(poll_status) && poll_status != SWITCH_STATUS_TIMEOUT) { + char tmp[128] = ""; + strerror_r(poll_status, tmp, sizeof(tmp)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Poll failed with error: %d [%s]\n", poll_status, tmp); ret = -1; goto end; } poll_loop = 1; - rtp_session->missed_count += (poll_sec * 1000) / (rtp_session->ms_per_packet ? rtp_session->ms_per_packet / 1000 : 20); - bytes = 0; - if (rtp_session->max_missed_packets) { - if (rtp_session->missed_count >= rtp_session->max_missed_packets) { - ret = -2; - goto end; + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) { + rtp_session->missed_count += (poll_sec * 1000) / (rtp_session->ms_per_packet ? rtp_session->ms_per_packet / 1000 : 20); + bytes = 0; + + if (rtp_session->max_missed_packets) { + if (rtp_session->missed_count >= rtp_session->max_missed_packets) { + ret = -2; + goto end; + } } } - - if ((!(io_flags & SWITCH_IO_FLAG_NOBLOCK)) && (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(); } } - + + if (rtp_session->recv_msg.header.pt != 13 && + rtp_session->recv_msg.header.pt != rtp_session->recv_te && + (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && + rtp_session->recv_msg.header.pt != rtp_session->payload) { + /* drop frames of incorrect payload number and return CNG frame instead */ + return_cng_frame(); + } + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_read_pollfd) { rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0); @@ -2798,7 +2837,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } #ifdef DEBUG_2833 if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { - printf("sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); } #endif @@ -2848,7 +2887,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } #ifdef DEBUG_2833 - printf("packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) packet[1], (unsigned) packet[2], (unsigned) packet[3]); #endif @@ -2857,16 +2896,28 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->dtmf_data.in_digit_seq = in_digit_seq; #ifdef DEBUG_2833 - printf("read: %c %u %u %u %u %d %d %s\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : ""); #endif + + if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && + rtp_session->dtmf_data.in_digit_ts) { + switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0) }; +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); +#endif + switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); + rtp_session->dtmf_data.in_digit_queued = 1; + } + /* only set sanity if we do NOT ignore the packet */ if (rtp_session->dtmf_data.in_digit_ts) { rtp_session->dtmf_data.in_digit_sanity = 2000; } - if (rtp_session->dtmf_data.last_duration > duration && rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) { + if (rtp_session->dtmf_data.last_duration > duration && + rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) { rtp_session->dtmf_data.flip++; } @@ -2881,18 +2932,26 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF; rtp_session->dtmf_data.flip = 0; #ifdef DEBUG_2833 - printf("you're welcome!\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n"); #endif } #ifdef DEBUG_2833 - printf("done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration); #endif - switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); + + if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) { +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); +#endif + switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); + } + rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit; rtp_session->dtmf_data.in_digit_ts = 0; rtp_session->dtmf_data.in_digit_sanity = 0; + rtp_session->dtmf_data.in_digit_queued = 0; do_cng = 1; } else { if (!switch_rtp_ready(rtp_session)) { @@ -2911,7 +2970,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->dtmf_data.last_duration = duration; } else { #ifdef DEBUG_2833 - printf("drop: %c %u %u %u %u %d %d\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n", key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end); #endif switch_cond_next(); @@ -2920,10 +2979,27 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } if (rtp_session->dtmf_data.in_digit_ts) { + + } + + + if (bytes && rtp_session->dtmf_data.in_digit_ts) { if (!switch_rtp_ready(rtp_session)) { goto end; } - return_cng_frame(); + + if (!rtp_session->dtmf_data.in_interleaved && rtp_session->recv_msg.header.pt != rtp_session->recv_te) { + /* Drat, they are sending audio still as well as DTMF ok fine..... *sigh* */ + rtp_session->dtmf_data.in_interleaved = 1; + } + + if (rtp_session->dtmf_data.in_interleaved || (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION)) { + if (rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + goto recvfrom; + } + } else { + return_cng_frame(); + } } timer_check: @@ -3193,21 +3269,25 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp switch_rtp_t *other_rtp_session = switch_channel_get_private(other_channel, "__zrtp_audio_rtp_session"); if (other_rtp_session) { - if (zrtp_status_ok == zrtp_session_get(other_rtp_session->zrtp_session, &zrtp_session_info)) { - if (rtp_session->zrtp_mitm_tries > ZRTP_MITM_TRIES) { - switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); - switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); - switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); - switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); - } else if (zrtp_status_ok == zrtp_resolve_mitm_call(other_rtp_session->zrtp_stream, rtp_session->zrtp_stream)) { - switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); - switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); - switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); - switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); - zrtp_verified_set(zrtp_global, &rtp_session->zrtp_session->zid, - &rtp_session->zrtp_session->peer_zid, zrtp_session_info.sas_is_verified ^ 1); - rtp_session->zrtp_mitm_tries++; + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { + switch_mutex_lock(other_rtp_session->read_mutex); + if (zrtp_status_ok == zrtp_session_get(other_rtp_session->zrtp_session, &zrtp_session_info)) { + if (rtp_session->zrtp_mitm_tries > ZRTP_MITM_TRIES) { + switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); + switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); + switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); + switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); + } else if (zrtp_status_ok == zrtp_resolve_mitm_call(other_rtp_session->zrtp_stream, rtp_session->zrtp_stream)) { + switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); + switch_clear_flag(rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); + switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_RECV); + switch_clear_flag(other_rtp_session, SWITCH_ZRTP_FLAG_SECURE_MITM_SEND); + zrtp_verified_set(zrtp_global, &rtp_session->zrtp_session->zid, + &rtp_session->zrtp_session->peer_zid, zrtp_session_info.sas_is_verified ^ 1); + rtp_session->zrtp_mitm_tries++; + } } + switch_mutex_unlock(other_rtp_session->read_mutex); } } @@ -3233,7 +3313,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp } frame->datalen = bytes; - return SWITCH_STATUS_SUCCESS; } @@ -3519,7 +3598,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, #ifdef RTP_DEBUG_WRITE_DELTA { int delta = (int) (now - rtp_session->send_time) / 1000; - printf("WRITE %d delta %d\n", (int) bytes, delta); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WRITE %d delta %d\n", (int) bytes, delta); } #endif rtp_session->send_time = now; diff --git a/src/switch_scheduler.c b/src/switch_scheduler.c index 93894b5a97..3268d270d1 100644 --- a/src/switch_scheduler.c +++ b/src/switch_scheduler.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_stun.c b/src/switch_stun.c index 89e42e0b17..0045feb557 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_swig.c b/src/switch_swig.c index d222b4e54d..c041e1b1da 100644 --- a/src/switch_swig.c +++ b/src/switch_swig.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_time.c b/src/switch_time.c index ad721bee08..dc428f1f77 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_utils.c b/src/switch_utils.c index 7331a971b3..850b07f51d 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * @@ -372,7 +372,7 @@ SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char clos if (s && *s == open) { depth++; for (e = s + 1; e && *e; e++) { - if (*e == open) { + if (*e == open && open != close) { depth++; } else if (*e == close) { depth--; @@ -809,23 +809,29 @@ SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str) { const char *sp = str; char *p, *s = NULL; + size_t len; - if (!sp) - return NULL; + if (zstr(sp)) { + return strdup(SWITCH_BLANK_STRING); + } while ((*sp == 13 ) || (*sp == 10 ) || (*sp == 9 ) || (*sp == 32) || (*sp == 11) ) { sp++; } + + if (zstr(sp)) { + return strdup(SWITCH_BLANK_STRING); + } s = strdup(sp); + switch_assert(s); - if (!s) - return NULL; + if ((len = strlen(s)) > 0) { + p = s + (len - 1); - p = s + (strlen(s) - 1); - - while ((*p == 13 ) || (*p == 10 ) || (*p == 9 ) || (*p == 32) || (*p == 11) ) { - *p-- = '\0'; + while ((p >= s) && ((*p == 13 ) || (*p == 10 ) || (*p == 9 ) || (*p == 32) || (*p == 11))) { + *p-- = '\0'; + } } return s; @@ -835,9 +841,11 @@ SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup) { char *sp = str; char *p, *s = NULL; + size_t len; - if (!sp) - return NULL; + if (zstr(sp)) { + return dup ? strdup(SWITCH_BLANK_STRING) : sp; + } while (*sp == ' ') { sp++; @@ -845,17 +853,21 @@ SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup) if (dup) { s = strdup(sp); + switch_assert(s); } else { s = sp; } - if (!s) - return NULL; + if (zstr(s)) { + return s; + } - p = s + (strlen(s) - 1); + if ((len = strlen(s)) > 0) { + p = s + (len - 1); - while (*p == ' ') { - *p-- = '\0'; + while (p && *p && (p >= s) && *p == ' ') { + *p-- = '\0'; + } } return s; diff --git a/src/switch_xml.c b/src/switch_xml.c index 05cfe9fd4c..fe6a19949d 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c index 288ff2d919..b6b37bd7db 100644 --- a/src/switch_xml_config.c +++ b/src/switch_xml_config.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 * diff --git a/src/tone2wav.c b/src/tone2wav.c index 8d4978a57c..403f45a727 100644 --- a/src/tone2wav.c +++ b/src/tone2wav.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2010, Anthony Minessale II + * Copyright (C) 2005-2011, Anthony Minessale II * * Version: MPL 1.1 *