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