From f3082c7d75926e77062bc83c0318979e89ad0857 Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Mon, 17 Jan 2011 19:15:02 -0500 Subject: [PATCH 01/54] freetdm: enable ec only upon SIGEVENT_PROGRESS_MEDIA --- libs/freetdm/src/ftdm_io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 6bfa37576c..c13fe76447 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2417,8 +2417,6 @@ static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *f 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); - 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; @@ -5548,6 +5546,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t } break; + case FTDM_SIGEVENT_PROGRESS_MEDIA: + { + ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Enabling echo cancellation on progress media\n"); + ftdm_set_echocancel_call_begin(sigmsg->channel); + } + 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 ... */ From de49305ad501b4bba758679be7b5e80b68eba1cf Mon Sep 17 00:00:00 2001 From: Travis Cross <tc@traviscross.com> Date: Tue, 18 Jan 2011 04:23:45 +0000 Subject: [PATCH 02/54] let vmain-key and operator-key be set empty The defaults for these keys are empty. This change allows them to be set empty in the XML config without error. --- src/mod/applications/mod_voicemail/mod_voicemail.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 1799e5c7dc..76870f75b9 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -311,6 +311,7 @@ static void destroy_profile(const char *profile_name, switch_bool_t block) /* Static buffer, 2 bytes */ static switch_xml_config_string_options_t config_dtmf = { NULL, 2, "[0-9#\\*]" }; +static switch_xml_config_string_options_t config_dtmf_optional = { NULL, 2, "[0-9#\\*]?" }; static switch_xml_config_string_options_t config_login_keys = { NULL, 16, "[0-9#\\*]*" }; static switch_xml_config_string_options_t config_file_ext = { NULL, 10, NULL }; static switch_xml_config_int_options_t config_int_0_10000 = { SWITCH_TRUE, 0, SWITCH_TRUE, 10000 }; @@ -520,8 +521,8 @@ vm_profile_t *profile_set_config(vm_profile_t *profile) SWITCH_CONFIG_SET_ITEM(profile->config[i++], "urgent-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->urgent_key, "*", &config_dtmf, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "operator-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, - &profile->operator_key, "", &config_dtmf, NULL, NULL); - SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->vmain_key, "", &config_dtmf, NULL, NULL); + &profile->operator_key, "", &config_dtmf_optional, NULL, NULL); + SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->vmain_key, "", &config_dtmf_optional, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "vmain-extension", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->vmain_ext, "", &profile->config_str_pool, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "forward-key", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, From 7438e24d1ab38317d73ace94150573fb84778f59 Mon Sep 17 00:00:00 2001 From: cypromis <michal.bielicki@seventhsignal.de> Date: Tue, 18 Jan 2011 10:32:45 +0100 Subject: [PATCH 03/54] fix a fedora dep and fix python path to be variable in sopec file --- freeswitch.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/freeswitch.spec b/freeswitch.spec index 66db65c698..cb83ffbeb1 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,6 +89,9 @@ BuildRequires: libtool >= 1.5.17 BuildRequires: ncurses-devel BuildRequires: openssl-devel BuildRequires: perl +%if %{_vendor} == redhat && 0%{?fedora} <= 8 +BuildRequires: perl-ExtUtils-Embed +%endif BuildRequires: pkgconfig BuildRequires: termcap BuildRequires: unixODBC-devel @@ -893,7 +896,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 From af0dc500ae8639d2b19c9a1a55937e7bb6f27db2 Mon Sep 17 00:00:00 2001 From: cypromis <michal.bielicki@seventhsignal.de> Date: Tue, 18 Jan 2011 11:20:12 +0100 Subject: [PATCH 04/54] more fedora fixes --- freeswitch.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/freeswitch.spec b/freeswitch.spec index cb83ffbeb1..c434af6728 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -89,11 +89,13 @@ BuildRequires: libtool >= 1.5.17 BuildRequires: ncurses-devel BuildRequires: openssl-devel BuildRequires: perl -%if %{_vendor} == redhat && 0%{?fedora} <= 8 +% 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 @@ -954,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 From 54879c381e287b6cf0344c08086bf9d8faf686de Mon Sep 17 00:00:00 2001 From: cypromis <michal.bielicki@seventhsignal.de> Date: Tue, 18 Jan 2011 11:21:35 +0100 Subject: [PATCH 05/54] added rpm building for callie soundfiles --- build/buildsounds-callie.sh | 15 ++ freeswitch-sounds-en-us-callie.spec | 319 ++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+) create mode 100755 build/buildsounds-callie.sh create mode 100644 freeswitch-sounds-en-us-callie.spec diff --git a/build/buildsounds-callie.sh b/build/buildsounds-callie.sh new file mode 100755 index 0000000000..06099e6c5e --- /dev/null +++ b/build/buildsounds-callie.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +sounds_location=$1 +for rate in 32000 16000 8000 +do + for i in ascii base256 conference currency digits 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 diff --git a/freeswitch-sounds-en-us-callie.spec b/freeswitch-sounds-en-us-callie.spec new file mode 100644 index 0000000000..2dbb91a94e --- /dev/null +++ b/freeswitch-sounds-en-us-callie.spec @@ -0,0 +1,319 @@ +############################################################################## +# 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 <vc-rpms@voipconsulting.nl> +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 + +%if %{is_rhel5}0 +%BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +%endif + +%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 + +# copy buildsounds-callie.sh script to working dir +%{__install} -m 0750 build/buildsounds-callie.sh ./us/callie + +############################################################################## +# 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/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/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/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/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/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/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/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/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 <michal.bielicki@seventhsignal.de> - 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 <vc-rpms@voipconsulting.nl> - 1.0.12-8 +- update perms and user/group to sync with the old situation + +* Wed Dec 16 2009 Patrick Laimbock <vc-rpms@voipconsulting.nl> - 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 <vc-rpms@voipconsulting.nl> - 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 <vc-rpms@voipconsulting.nl> - 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 <vc-rpms@voipconsulting.nl> - 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 <vc-rpms@voipconsulting.nl> - 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 <vc-rpms@voipconsulting.nl> - 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 + From 10b38944f6e51f33e3d0092ea1dcf3e88538a5a7 Mon Sep 17 00:00:00 2001 From: cypromis <michal.bielicki@seventhsignal.de> Date: Tue, 18 Jan 2011 11:40:37 +0100 Subject: [PATCH 06/54] updated sounds version in version file --- build/sounds_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 90e87a481145242bf661de4a96a7ccda1476034e Mon Sep 17 00:00:00 2001 From: Michal Bielicki <michal.bielicki@seventhsignal.de> Date: Tue, 18 Jan 2011 15:27:57 +0300 Subject: [PATCH 07/54] this file is not needed anymore, included in spec file for sounds --- build/buildsounds-callie.sh | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100755 build/buildsounds-callie.sh diff --git a/build/buildsounds-callie.sh b/build/buildsounds-callie.sh deleted file mode 100755 index 06099e6c5e..0000000000 --- a/build/buildsounds-callie.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -sounds_location=$1 -for rate in 32000 16000 8000 -do - for i in ascii base256 conference currency digits 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 From b683bb6585165c29ef883b41b97400d8ebc550df Mon Sep 17 00:00:00 2001 From: Michal Bielicki <michal.bielicki@seventhsignal.de> Date: Tue, 18 Jan 2011 17:58:36 +0300 Subject: [PATCH 08/54] final version I hope --- freeswitch-sounds-en-us-callie.spec | 32 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/freeswitch-sounds-en-us-callie.spec b/freeswitch-sounds-en-us-callie.spec index 2dbb91a94e..c4764570f5 100644 --- a/freeswitch-sounds-en-us-callie.spec +++ b/freeswitch-sounds-en-us-callie.spec @@ -46,10 +46,7 @@ BuildArch: noarch BuildRequires: sox Requires: freeswitch Requires: freeswitch-sounds-en-us-callie-48000 - -%if %{is_rhel5}0 -%BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -%endif +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %description FreeSWITCH 48kHz en-us Callie prompts plus, during the installation, @@ -111,9 +108,24 @@ FreeSWITCH Callie prompts package that pulls in the 8KHz, 16KHz, %prep %setup -b0 -q -n en +mkdir -p ./usr/callie +# create buildsounds-callie.sh script in working dir +echo '#!/bin/bash -# copy buildsounds-callie.sh script to working dir -%{__install} -m 0750 build/buildsounds-callie.sh ./us/callie +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 @@ -179,6 +191,7 @@ cd %{_prefix}/sounds/en/us/callie %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 @@ -190,6 +203,7 @@ cd %{_prefix}/sounds/en/us/callie %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 @@ -204,6 +218,7 @@ cd %{_prefix}/sounds/en/us/callie %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 @@ -215,6 +230,7 @@ cd %{_prefix}/sounds/en/us/callie %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 @@ -229,6 +245,7 @@ cd %{_prefix}/sounds/en/us/callie %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 @@ -240,6 +257,7 @@ cd %{_prefix}/sounds/en/us/callie %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 @@ -254,6 +272,7 @@ cd %{_prefix}/sounds/en/us/callie %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 @@ -265,6 +284,7 @@ cd %{_prefix}/sounds/en/us/callie %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 From 190bd61d8a74678135396f28940655114d9b6513 Mon Sep 17 00:00:00 2001 From: Michal Bielicki <michal.bielicki@seventhsignal.de> Date: Tue, 18 Jan 2011 17:58:53 +0300 Subject: [PATCH 09/54] typo in freeswitch.spec --- freeswitch.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freeswitch.spec b/freeswitch.spec index c434af6728..7fb9f80d8e 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -89,7 +89,7 @@ BuildRequires: libtool >= 1.5.17 BuildRequires: ncurses-devel BuildRequires: openssl-devel BuildRequires: perl -% 0%{?fedora_version} >= 8 +%if 0%{?fedora_version} >= 8 BuildRequires: perl-ExtUtils-Embed %endif BuildRequires: pkgconfig From 1db40e60e4675ce363855ba429ceadd90e800f1c Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Tue, 18 Jan 2011 11:28:37 -0500 Subject: [PATCH 10/54] freetdm: improved logic to enable/disable EC on call start/stop - MFC-R2 requires tone signaling that gets screwed sometimes if the EC is enabled during call setup. - EC is now enabled only when switching to a state requiring media (UP and PROGRESS_MEDIA) - The logic is aware of EC persist option in Wanpipe - Improved logging in ftmod_wanpipe to print EC state on startup --- libs/freetdm/src/ftdm_io.c | 69 ++++++++++++------- libs/freetdm/src/ftdm_state.c | 10 +-- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 3 - .../src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 9 ++- libs/freetdm/src/include/private/ftdm_core.h | 11 +++ libs/freetdm/src/include/private/ftdm_types.h | 9 +-- 6 files changed, 70 insertions(+), 41 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index c13fe76447..b5f9fab93d 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -404,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, @@ -5548,25 +5548,44 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t case FTDM_SIGEVENT_PROGRESS_MEDIA: { - ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Enabling echo cancellation on progress media\n"); - ftdm_set_echocancel_call_begin(sigmsg->channel); + /* 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; diff --git a/libs/freetdm/src/ftdm_state.c b/libs/freetdm/src/ftdm_state.c index 574d85845b..de62c0f0e7 100644 --- a/libs/freetdm/src/ftdm_state.c +++ b/libs/freetdm/src/ftdm_state.c @@ -70,13 +70,13 @@ 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)); diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 434417726b..6e2b292ce7 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -647,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)); diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 1f2ad84d72..7bcb69cd9e 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,7 +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 fd:%d DTMF: %s\n", 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); diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 4fd8ec64ea..fbe42d33da 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -622,6 +622,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span); /*! \brief clear the tone detector state */ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); +/* start/stop echo cancelling at the beginning/end of a call */ +FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan); +FT_DECLARE(void) ftdm_set_echocancel_call_end(ftdm_channel_t *chan); /*! \brief Assert condition @@ -677,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_types.h b/libs/freetdm/src/include/private/ftdm_types.h index 3bc986d7f6..9e8df1f5f2 100644 --- a/libs/freetdm/src/include/private/ftdm_types.h +++ b/libs/freetdm/src/include/private/ftdm_types.h @@ -227,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) From 0a38d7761e1099b4e369da8948f22ac7c0c8d184 Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Tue, 18 Jan 2011 12:44:41 -0500 Subject: [PATCH 11/54] freetdm: set explicit numbers for channel commands to aid debugging --- libs/freetdm/src/include/freetdm.h | 114 ++++++++++++++--------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 2666a26df2..142dff888a 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -574,84 +574,84 @@ typedef struct ftdm_iterator ftdm_iterator_t; /*! \brief Channel commands that can be executed through ftdm_channel_command() */ typedef enum { - FTDM_COMMAND_NOOP, - FTDM_COMMAND_SET_INTERVAL, - FTDM_COMMAND_GET_INTERVAL, - FTDM_COMMAND_SET_CODEC, - FTDM_COMMAND_GET_CODEC, - FTDM_COMMAND_SET_NATIVE_CODEC, - FTDM_COMMAND_GET_NATIVE_CODEC, - FTDM_COMMAND_ENABLE_DTMF_DETECT, - FTDM_COMMAND_DISABLE_DTMF_DETECT, - FTDM_COMMAND_SEND_DTMF, - FTDM_COMMAND_SET_DTMF_ON_PERIOD, - FTDM_COMMAND_GET_DTMF_ON_PERIOD, - FTDM_COMMAND_SET_DTMF_OFF_PERIOD, - FTDM_COMMAND_GET_DTMF_OFF_PERIOD, - FTDM_COMMAND_GENERATE_RING_ON, - FTDM_COMMAND_GENERATE_RING_OFF, - FTDM_COMMAND_OFFHOOK, - FTDM_COMMAND_ONHOOK, - FTDM_COMMAND_FLASH, - FTDM_COMMAND_WINK, - FTDM_COMMAND_ENABLE_PROGRESS_DETECT, - FTDM_COMMAND_DISABLE_PROGRESS_DETECT, + FTDM_COMMAND_NOOP = 0, + FTDM_COMMAND_SET_INTERVAL = 1, + FTDM_COMMAND_GET_INTERVAL = 2, + FTDM_COMMAND_SET_CODEC = 3, + FTDM_COMMAND_GET_CODEC = 4, + FTDM_COMMAND_SET_NATIVE_CODEC = 5, + FTDM_COMMAND_GET_NATIVE_CODEC = 6, + FTDM_COMMAND_ENABLE_DTMF_DETECT = 7, + FTDM_COMMAND_DISABLE_DTMF_DETECT = 8, + FTDM_COMMAND_SEND_DTMF = 9, + FTDM_COMMAND_SET_DTMF_ON_PERIOD = 10, + FTDM_COMMAND_GET_DTMF_ON_PERIOD = 11, + FTDM_COMMAND_SET_DTMF_OFF_PERIOD = 12, + FTDM_COMMAND_GET_DTMF_OFF_PERIOD = 13, + FTDM_COMMAND_GENERATE_RING_ON = 14, + FTDM_COMMAND_GENERATE_RING_OFF = 15, + FTDM_COMMAND_OFFHOOK = 16, + FTDM_COMMAND_ONHOOK = 17, + FTDM_COMMAND_FLASH = 18, + FTDM_COMMAND_WINK = 19, + FTDM_COMMAND_ENABLE_PROGRESS_DETECT = 20, + FTDM_COMMAND_DISABLE_PROGRESS_DETECT = 21, /*!< Start tracing input and output from channel to the given file */ - FTDM_COMMAND_TRACE_INPUT, - FTDM_COMMAND_TRACE_OUTPUT, + FTDM_COMMAND_TRACE_INPUT = 22, + FTDM_COMMAND_TRACE_OUTPUT = 23, /*!< Stop both Input and Output trace, closing the files */ - FTDM_COMMAND_TRACE_END_ALL, + FTDM_COMMAND_TRACE_END_ALL = 24, /*!< Enable DTMF debugging */ - FTDM_COMMAND_ENABLE_DEBUG_DTMF, + FTDM_COMMAND_ENABLE_DEBUG_DTMF = 25, /*!< Disable DTMF debugging (if not disabled explicitly, it is disabled automatically when calls hangup) */ - FTDM_COMMAND_DISABLE_DEBUG_DTMF, + FTDM_COMMAND_DISABLE_DEBUG_DTMF = 26, /*!< Start dumping all input to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ - FTDM_COMMAND_ENABLE_INPUT_DUMP, + FTDM_COMMAND_ENABLE_INPUT_DUMP = 27, /*!< Stop dumping all input to a circular buffer. */ - FTDM_COMMAND_DISABLE_INPUT_DUMP, + FTDM_COMMAND_DISABLE_INPUT_DUMP = 28, /*!< Start dumping all output to a circular buffer. The size of the circular buffer can be specified, default used otherwise */ - FTDM_COMMAND_ENABLE_OUTPUT_DUMP, + FTDM_COMMAND_ENABLE_OUTPUT_DUMP = 29, /*!< Stop dumping all output to a circular buffer. */ - FTDM_COMMAND_DISABLE_OUTPUT_DUMP, + FTDM_COMMAND_DISABLE_OUTPUT_DUMP = 30, /*!< Dump the current input circular buffer to the specified FILE* structure */ - FTDM_COMMAND_DUMP_INPUT, + FTDM_COMMAND_DUMP_INPUT = 31, /*!< Dump the current output circular buffer to the specified FILE* structure */ - FTDM_COMMAND_DUMP_OUTPUT, + FTDM_COMMAND_DUMP_OUTPUT = 32, - FTDM_COMMAND_ENABLE_CALLERID_DETECT, - FTDM_COMMAND_DISABLE_CALLERID_DETECT, - FTDM_COMMAND_ENABLE_ECHOCANCEL, - FTDM_COMMAND_DISABLE_ECHOCANCEL, - FTDM_COMMAND_ENABLE_ECHOTRAIN, - FTDM_COMMAND_DISABLE_ECHOTRAIN, - FTDM_COMMAND_SET_CAS_BITS, - FTDM_COMMAND_GET_CAS_BITS, - FTDM_COMMAND_SET_RX_GAIN, - FTDM_COMMAND_GET_RX_GAIN, - FTDM_COMMAND_SET_TX_GAIN, - FTDM_COMMAND_GET_TX_GAIN, - FTDM_COMMAND_FLUSH_TX_BUFFERS, - FTDM_COMMAND_FLUSH_RX_BUFFERS, - FTDM_COMMAND_FLUSH_BUFFERS, - FTDM_COMMAND_FLUSH_IOSTATS, - FTDM_COMMAND_SET_PRE_BUFFER_SIZE, - FTDM_COMMAND_SET_LINK_STATUS, - FTDM_COMMAND_GET_LINK_STATUS, - FTDM_COMMAND_ENABLE_LOOP, - FTDM_COMMAND_DISABLE_LOOP, - FTDM_COMMAND_SET_RX_QUEUE_SIZE, - FTDM_COMMAND_SET_TX_QUEUE_SIZE, - FTDM_COMMAND_SET_POLARITY, + FTDM_COMMAND_ENABLE_CALLERID_DETECT = 33, + FTDM_COMMAND_DISABLE_CALLERID_DETECT = 34, + FTDM_COMMAND_ENABLE_ECHOCANCEL = 35, + FTDM_COMMAND_DISABLE_ECHOCANCEL = 36, + FTDM_COMMAND_ENABLE_ECHOTRAIN = 37, + FTDM_COMMAND_DISABLE_ECHOTRAIN = 38, + FTDM_COMMAND_SET_CAS_BITS = 39, + FTDM_COMMAND_GET_CAS_BITS = 40, + FTDM_COMMAND_SET_RX_GAIN = 41, + FTDM_COMMAND_GET_RX_GAIN = 42, + FTDM_COMMAND_SET_TX_GAIN = 43, + FTDM_COMMAND_GET_TX_GAIN = 44, + FTDM_COMMAND_FLUSH_TX_BUFFERS = 45, + FTDM_COMMAND_FLUSH_RX_BUFFERS = 46, + FTDM_COMMAND_FLUSH_BUFFERS = 47, + FTDM_COMMAND_FLUSH_IOSTATS = 48, + FTDM_COMMAND_SET_PRE_BUFFER_SIZE = 49, + FTDM_COMMAND_SET_LINK_STATUS = 50, + FTDM_COMMAND_GET_LINK_STATUS = 51, + FTDM_COMMAND_ENABLE_LOOP = 52, + FTDM_COMMAND_DISABLE_LOOP = 53, + FTDM_COMMAND_SET_RX_QUEUE_SIZE = 54, + FTDM_COMMAND_SET_TX_QUEUE_SIZE = 55, + FTDM_COMMAND_SET_POLARITY = 56, FTDM_COMMAND_COUNT, } ftdm_command_t; From 07fa8a4a72460bf77eac238de0b634896f8d90ca Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Tue, 18 Jan 2011 13:13:30 -0500 Subject: [PATCH 12/54] freetdm: fix windows ftmod_wanpipe bug on link connect/disconnect --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 1f2ad84d72..d3e2116413 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -1257,20 +1257,18 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type) { case WP_API_EVENT_LINK_STATUS: { -#if 0 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(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(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link disconnected event\n"); break; }; -#else /* The WP_API_EVENT_ALARM event should be used to clear alarms */ - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link status event\n", ftdm_oob_event2str(*event_id)); *event_id = FTDM_OOB_NOOP; -#endif } break; From 51985ca69a1f050b3c724043e01582500882882c Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Tue, 18 Jan 2011 13:15:04 -0500 Subject: [PATCH 13/54] freetdm: fix FTDM_IS_DCHAN macro --- libs/freetdm/src/include/freetdm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 142dff888a..517d6b931d 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -171,7 +171,7 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t) #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) ((fchan)->type == FTDM_CHAN_TYPE_DQ921 || (fchan)->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 || \ From 9a545bd0c9534eb6e6f7579a1b5f0e57d0a7ee6c Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Tue, 18 Jan 2011 13:21:31 -0500 Subject: [PATCH 14/54] freetdm: doh --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index be4e37047f..e2b08255ac 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -1267,11 +1267,11 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) { case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED: /* *event_id = FTDM_OOB_ALARM_CLEAR; */ - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link connected event\n"); + ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link connected event\n"); break; default: /* *event_id = FTDM_OOB_ALARM_TRAP; */ - ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link disconnected event\n"); + 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 */ From 137de401218c834262b0941e8b47de600a2c9052 Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Tue, 18 Jan 2011 14:09:42 -0500 Subject: [PATCH 15/54] freetdm: ftmod_r2 - change warning to notice for hangup cause mapping --- libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index 6e2b292ce7..0217a5172a 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -295,7 +295,7 @@ static ftdm_call_cause_t ftdm_r2_cause_to_ftdm_cause(ftdm_channel_t *fchan, open 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; } From c64f4753b3003a1b091678850f272669926ff12c Mon Sep 17 00:00:00 2001 From: David Yat Sin <dyatsin@sangoma.com> Date: Tue, 18 Jan 2011 14:36:30 -0500 Subject: [PATCH 16/54] freetdm: added missing cause enums from Q.850 --- libs/freetdm/src/include/freetdm.h | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 517d6b931d..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, From 163dd056605065b2f8221e95a75e422c0f034f05 Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Tue, 18 Jan 2011 16:10:14 -0500 Subject: [PATCH 17/54] freetdm: add ftdm_call_utils.h to the installed headers --- libs/freetdm/Makefile.am | 1 + 1 file changed, 1 insertion(+) 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 From 54c0d6f7c41d3bc882ff339af8c01545e03606a9 Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Wed, 19 Jan 2011 11:38:27 -0500 Subject: [PATCH 18/54] freetdm: workaround for Visual C++ 9.0 failing to compile ftdm feature macros --- libs/freetdm/src/include/private/ftdm_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index fbe42d33da..7cf0934f57 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -132,8 +132,8 @@ extern "C" { #define ftdm_channel_test_feature(obj, flag) ((obj)->features & flag) -#define ftdm_channel_set_feature(obj, flag) (obj)->features |= (flag) -#define ftdm_channel_clear_feature(obj, flag) (obj)->features &= ~(flag) +#define ftdm_channel_set_feature(obj, flag) (obj)->features = (ftdm_channel_feature_t)((obj)->features | flag) +#define ftdm_channel_clear_feature(obj, flag) (obj)->features = (ftdm_channel_feature_t)((obj)->features & ( ~(flag) )) #define ftdm_channel_set_member_locked(obj, _m, _v) ftdm_mutex_lock(obj->mutex); obj->_m = _v; ftdm_mutex_unlock(obj->mutex) /*! From bd39ad2269d302748fd55e96431b221ba6c7be6b Mon Sep 17 00:00:00 2001 From: Brian West <brian@freeswitch.org> Date: Wed, 19 Jan 2011 11:33:01 -0600 Subject: [PATCH 19/54] FS-2995: sigh... mr collins you said you fixed this --- conf/lang/en/dir/sounds.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/lang/en/dir/sounds.xml b/conf/lang/en/dir/sounds.xml index 2bdc1492ec..15ecec304a 100644 --- a/conf/lang/en/dir/sounds.xml +++ b/conf/lang/en/dir/sounds.xml @@ -16,7 +16,7 @@ <match> <action function="play-file" data="directory/dir-to_search_by.wav"/> <action function="play-file" data="directory/dir-first_name.wav"/> - <action function="play-file" data="directory/dir-press.wav"/> + <action function="play-file" data="voicemail/vm-press.wav"/> <action function="say" data="$2" method="pronounced" type="name_spelled"/> </match> </input> @@ -24,7 +24,7 @@ <match> <action function="play-file" data="directory/dir-to_search_by.wav"/> <action function="play-file" data="directory/dir-last_name.wav"/> - <action function="play-file" data="directory/dir-press.wav"/> + <action function="play-file" data="voicemail/vm-press.wav"/> <action function="say" data="$2" method="pronounced" type="name_spelled"/> </match> </input> From afc027473f7fc8a3ec233fb1848f728fc94f56b6 Mon Sep 17 00:00:00 2001 From: Brian West <brian@freeswitch.org> Date: Wed, 19 Jan 2011 11:35:48 -0600 Subject: [PATCH 20/54] FS-2989: Places ;fs_path= within the contact string <...> when using NDLB-connectile-dysfunction-2.0, instead of just appending to the end of the contact string. --- src/mod/endpoints/mod_sofia/sofia_reg.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index f644ff772b..631cbdb14b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1139,7 +1139,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_url_encode(my_contact_str, path_encoded + 20, path_encoded_len - 20); reg_desc = "Registered(AUTO-NAT-2.0)"; exptime = 30; - switch_snprintf(contact_str + strlen(contact_str), sizeof(contact_str) - strlen(contact_str), "%s", path_encoded); + + /* place fs_path (the encoded path) inside the <...> of the contact string, if possible */ + if (contact_str[strlen(contact_str) - 1] == '>') { + switch_snprintf(contact_str + strlen(contact_str) - 1, sizeof(contact_str) - strlen(contact_str) + 1, "%s>", path_encoded); + } else { + switch_snprintf(contact_str + strlen(contact_str), sizeof(contact_str) - strlen(contact_str), "%s", path_encoded); + } free(path_encoded); } else { if (*received_data && sofia_test_pflag(profile, PFLAG_RECIEVED_IN_NAT_REG_CONTACT)) { From ea9021a24a6ce0606a2c12f3cab8f2bf0fc12db3 Mon Sep 17 00:00:00 2001 From: Brian West <brian@freeswitch.org> Date: Wed, 19 Jan 2011 11:38:36 -0600 Subject: [PATCH 21/54] FS-2998: prefix-a-leg not respected for url submission --- src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c index a439ab8203..78d97ce259 100644 --- a/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c +++ b/src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c @@ -340,7 +340,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session) switch_yield(globals.delay * 1000000); } - destUrl = switch_mprintf("%s?uuid=%s", globals.urls[globals.url_index], switch_core_session_get_uuid(session)); + destUrl = switch_mprintf("%s?uuid=%s%s", globals.urls[globals.url_index], a_prefix, switch_core_session_get_uuid(session)); curl_easy_setopt(curl_handle, CURLOPT_URL, destUrl); if (!strncasecmp(destUrl, "https", 5)) { From 1fcffcfbc3fe6c2f21e5767fc760fdbc0c89aa68 Mon Sep 17 00:00:00 2001 From: David Yat Sin <dyatsin@sangoma.com> Date: Wed, 19 Jan 2011 14:18:23 -0500 Subject: [PATCH 22/54] added documentation --- libs/freetdm/docs/io_modules.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 libs/freetdm/docs/io_modules.txt diff --git a/libs/freetdm/docs/io_modules.txt b/libs/freetdm/docs/io_modules.txt new file mode 100644 index 0000000000..a164bbb249 --- /dev/null +++ b/libs/freetdm/docs/io_modules.txt @@ -0,0 +1,13 @@ +Last Updated: Jan 19, 2011 + +== BACKGROUND == + +The IO module provides an abstracted IO interface to FreeTDM. + +== SHUTDOWN == +Upon global shutdown, for each channel FIO_CLOSE_FUNCTION will be called. +When FIO_CLOSE_FUNCTION is called, all waiters on this channel shall be signalled. +If FIO_WAIT_FUNCTION is called on a function that has already been closed, this function shall return FTDM_TIMEOUT without blocking. +FIO_CHANNEL_DESTROY will eventually be called, and IO module is responsible for clearing all internal states and free allocated memory upon channel destroy. + + From 6fd468043b284ee30085cf86be16ba99725d6462 Mon Sep 17 00:00:00 2001 From: David Yat Sin <dyatsin@sangoma.com> Date: Wed, 19 Jan 2011 14:46:28 -0500 Subject: [PATCH 23/54] freetdm: fix for closing d-channel when channel is already closed by freetdm core --- libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 f2afd1cf9c..e7053c1d43 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 @@ -394,8 +394,7 @@ static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj) default: ftdm_log_chan_msg(dchan, FTDM_LOG_CRIT, "Unhandled IO event\n"); } - } - ftdm_channel_close(&dchan); + } return NULL; } From 0fdc272b25c7918359ae5b0f27277ff1926bcb75 Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Wed, 19 Jan 2011 15:53:01 -0500 Subject: [PATCH 24/54] freetdm: open wanpipe devices as non-exclusive if possible --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index e2b08255ac..3b384cdf32 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -239,7 +239,11 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start ftdm_log(FTDM_LOG_ERROR, "span %d channel %d cannot be configured as smg_prid_nfas, you need to compile freetdm with newer libsangoma\n", spanno, x); #endif } else { +#ifdef LIBSANGOMA_VERSION + sockfd = __tdmv_api_open_span_chan(spanno, x); +#else sockfd = tdmv_api_open_span_chan(spanno, x); +#endif } if (sockfd == FTDM_INVALID_SOCKET) { From 9bb344783d39da5dc3e57d48b59f551ba9a2fa4d Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Wed, 19 Jan 2011 16:25:33 -0500 Subject: [PATCH 25/54] freetdm: remove collision event string --- libs/freetdm/src/include/freetdm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 8d67df3edc..aed40541a3 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -430,7 +430,7 @@ typedef enum { } ftdm_signal_event_t; #define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \ "PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \ - "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "FACILITY", \ + "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "FACILITY", \ "TRACE", "TRACE_RAW", "INDICATION_COMPLETED", "DIALING", "INVALID" /*! \brief Move from string to ftdm_signal_event_t and viceversa */ FTDM_STR2ENUM_P(ftdm_str2ftdm_signal_event, ftdm_signal_event2str, ftdm_signal_event_t) From 978cb111e7971eceb238d396124e10424b148a6c Mon Sep 17 00:00:00 2001 From: David Yat Sin <dyatsin@sangoma.com> Date: Wed, 19 Jan 2011 16:35:55 -0500 Subject: [PATCH 26/54] freetdm - improved default bearer-cap code --- .../ftmod_sangoma_isdn_support.c | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) 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 9c1b7baf79..64147b7d75 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 @@ -881,18 +881,27 @@ ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap) bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN && - bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { - - /* We are bridging a call from T1 */ - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; - - } else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { - - /* We are bridging a call from E1 */ - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; + switch (signal_data->switchtype) { + case SNGISDN_SWITCH_NI2: + case SNGISDN_SWITCH_4ESS: + case SNGISDN_SWITCH_5ESS: + case SNGISDN_SWITCH_DMS100: + case SNGISDN_SWITCH_INSNET: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to u-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; + } + break; + case SNGISDN_SWITCH_EUROISDN: + case SNGISDN_SWITCH_QSIG: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to a-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; + } + break; } + bearCap->lyr1Ident.pres = PRSNT_NODEF; bearCap->lyr1Ident.val = IN_L1_IDENT; } From 1da8339ffb5719ba92ececeb27b6c335f3e6b4aa Mon Sep 17 00:00:00 2001 From: David Yat Sin <dyatsin@sangoma.com> Date: Thu, 20 Jan 2011 10:42:28 -0500 Subject: [PATCH 27/54] freetdm: added support for early-media-override --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.c | 3 ++ .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.h | 14 +++++--- .../ftmod_sangoma_isdn_cfg.c | 25 +++++++++++++- .../ftmod_sangoma_isdn_stack_hndl.c | 33 +++++++++++++++---- 4 files changed, 63 insertions(+), 12 deletions(-) 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 e7053c1d43..df528ae9c1 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 @@ -676,6 +676,9 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm /*OUTBOUND...so we were told by the line of this so noifiy the user*/ sigev.event_id = FTDM_SIGEVENT_PROCEED; ftdm_span_send_signal(ftdmchan->span, &sigev); + if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } } else { if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { /* By default, we do not send a progress indicator in the proceed */ 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 58fcc07040..80dc73f0fa 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 @@ -112,6 +112,11 @@ typedef enum { SNGISDN_OPT_FALSE = 2, } sngisdn_opt_t; +typedef enum { + SNGISDN_EARLY_MEDIA_ON_PROCEED = (1 << 0), + SNGISDN_EARLY_MEDIA_ON_PROGRESS = (1 << 1), + SNGISDN_EARLY_MEDIA_ON_ALERT= (1 << 2), +} sngisdn_early_media_opt_t; typedef enum { SNGISDN_AVAIL_DOWN = 1, @@ -188,7 +193,8 @@ typedef struct sngisdn_span_data { uint8_t span_id; uint8_t tei; uint8_t min_digits; - uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */ + uint8_t trace_flags; /* TODO change to bit map of sngisdn_tracetype_t */ + uint8_t early_media_flags; /* bit map of ftdm_sngisdn_early_media_opt_t */ uint8_t overlap_dial; uint8_t setup_arb; uint8_t facility_ie_decode; @@ -196,10 +202,10 @@ typedef struct sngisdn_span_data { int8_t facility_timeout; uint8_t num_local_numbers; uint8_t ignore_cause_value; - uint8_t raw_trace_q931; - uint8_t raw_trace_q921; + uint8_t raw_trace_q931; /* TODO: combine with trace_flags */ + uint8_t raw_trace_q921; /* TODO: combine with trace_flags */ uint8_t timer_t3; - uint8_t restart_opt; + uint8_t restart_opt; char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; ftdm_sched_t *sched; ftdm_queue_t *event_queue; 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 aad68e15d1..afba96accc 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 @@ -192,6 +192,24 @@ static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) return FTDM_SUCCESS; } +static ftdm_status_t parse_early_media(const char* opt, ftdm_span_t *span) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + if (!strcasecmp(opt, "on-proceed")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROCEED; + } else if (!strcasecmp(opt, "on-progress")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROGRESS; + } else if (!strcasecmp(opt, "on-alert")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_ALERT; + } else { + ftdm_log(FTDM_LOG_ERROR, "Unsupported early-media option %s\n", opt); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "Early media opt:0x%x\n", signal_data->early_media_flags); + 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; @@ -249,6 +267,7 @@ static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span) return FTDM_SUCCESS; } + ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) { unsigned paramindex; @@ -351,10 +370,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ parse_yesno(var, val, &signal_data->raw_trace_q931); } else if (!strcasecmp(var, "q921-raw-trace")) { parse_yesno(var, val, &signal_data->raw_trace_q921); + } else if (!strcasecmp(var, "early-media-override")) { + if (parse_early_media(val, span) != FTDM_SUCCESS) { + return FTDM_FAIL; + } } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } - } + } /* for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) */ if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) { ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name); 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 7b7c748c7a..0b52011d42 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 @@ -167,12 +167,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) char retrieved_str[255]; ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); - /* - return values for "sng_isdn_retrieve_facility_information_following": - If there will be no information following, or fails to decode IE, returns -1 - If there will be no information following, but current FACILITY IE contains a caller name, returns 0 - If there will be information following, returns 1 - */ + /* + return values for "sng_isdn_retrieve_facility_information_following": + If there will be no information following, or fails to decode IE, returns -1 + If there will be no information following, but current FACILITY IE contains a caller name, returns 0 + If there will be information following, returns 1 + */ if (ret_val == 1) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); @@ -346,6 +346,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; @@ -384,7 +385,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_RINGING: + 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); @@ -393,16 +394,34 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) } switch (evntType) { case MI_CALLPROC: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROCEED)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on proceed\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED); } break; case MI_ALERTING: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_ALERT)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on alert\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING); } break; case MI_PROGRESS: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROGRESS)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on progress\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } 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) { From d743baefedfbe679a647013adc2718defef90718 Mon Sep 17 00:00:00 2001 From: David Yat Sin <dyatsin@sangoma.com> Date: Thu, 20 Jan 2011 11:03:13 -0500 Subject: [PATCH 28/54] freetdm: Fix for defaulting to wrong codec --- .../src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 afba96accc..bd5b13bfec 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 @@ -389,10 +389,11 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ } if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) { - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { - span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; - } else { + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || + signal_data->switchtype == SNGISDN_SWITCH_QSIG) { span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW; + } else { + span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; } } return FTDM_SUCCESS; From 70700617d3d6bd45904a81be443fe28aa7fd0387 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Thu, 20 Jan 2011 13:52:00 -0600 Subject: [PATCH 29/54] add execute_on_originate var '<app> <arg>' to run in origination thread or '<app>::<arg>' to run async. also originating_leg_uuid variable to show the uuid of the originating leg on an outbound channel --- src/switch_ivr_originate.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index d156c700fd..78743e6420 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2755,6 +2755,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } } + + if (session) { + switch_channel_set_variable(originate_status[i].peer_channel, "originating_leg_uuid", switch_core_session_get_uuid(session)); + } + + if ((vvar = switch_channel_get_variable_dup(originate_status[i].peer_channel, "execute_on_originate", SWITCH_FALSE))) { + char *app = switch_core_session_strdup(originate_status[i].peer_session, vvar); + char *arg = NULL; + + if (strstr(app, "::")) { + switch_core_session_execute_application_async(originate_status[i].peer_session, app, arg); + } else { + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + switch_core_session_execute_application(originate_status[i].peer_session, app, arg); + } + + } } if (table) { @@ -2773,7 +2793,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess *cause = SWITCH_CAUSE_SUCCESS; goto outer_for; } - + if (!switch_core_session_running(originate_status[i].peer_session)) { if (originate_status[i].per_channel_delay_start) { switch_channel_set_flag(originate_status[i].peer_channel, CF_BLOCK_STATE); From fd984d03bb629d08ac4192c5a1d3432e94ceb3d5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Thu, 20 Jan 2011 17:52:54 -0600 Subject: [PATCH 30/54] D'oh Over zealous packet eating --- src/switch_rtp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4e5450d7e8..3ce7a07e60 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2494,7 +2494,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - if (rtp_session->recv_msg.header.pt != 13 && + if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && + rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && rtp_session->recv_msg.header.pt != rtp_session->payload) { From 1c95ad98cd1c0e966b738796e74923db8919b754 Mon Sep 17 00:00:00 2001 From: Joao Mesquita <jmesquita@freeswitch.org> Date: Thu, 20 Jan 2011 22:43:50 -0300 Subject: [PATCH 31/54] Export the variables to the b leg as well --- src/mod/applications/mod_dptools/mod_dptools.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 41417255bb..5a3be0328d 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2982,6 +2982,8 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, } } } + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", user); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); if (!dest) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n"); From 7fbc47f83a5bf455b6ece49deb7771d144bbce4c Mon Sep 17 00:00:00 2001 From: Jeff Lenk <jeff@jefflenk.com> Date: Fri, 21 Jan 2011 09:09:53 -0600 Subject: [PATCH 32/54] FS-2973 Fix possible segfaults and memory leak during unload, and add new setting odbc-retries --- conf/autoload_configs/easyroute.conf.xml | 3 +++ src/mod/applications/mod_easyroute/mod_easyroute.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/conf/autoload_configs/easyroute.conf.xml b/conf/autoload_configs/easyroute.conf.xml index 7cd490942f..350a50989b 100644 --- a/conf/autoload_configs/easyroute.conf.xml +++ b/conf/autoload_configs/easyroute.conf.xml @@ -11,6 +11,9 @@ <!-- IP or Hostname of Default Route --> <param name="default-gateway" value="192.168.66.6"/> + <!-- Number of times to retry ODBC connection on connection problems, default is 120 --> + <param name="odbc-retries" value="120"/> + <!-- Customer Query. Use this with Care!!! We are not responsible if you mess This up!!! Query *MUST* return columns in the following order! gateway varchar(128) - contains destination gateway host:port pair (ex: 192.168.1.1:5060 ) diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c index 481df958cf..75b4712f2d 100644 --- a/src/mod/applications/mod_easyroute/mod_easyroute.c +++ b/src/mod/applications/mod_easyroute/mod_easyroute.c @@ -65,6 +65,7 @@ static struct { switch_mutex_t *mutex; char *custom_query; switch_odbc_handle_t *master_odbc; + int odbc_num_retries; } globals; SWITCH_MODULE_LOAD_FUNCTION(mod_easyroute_load); @@ -120,6 +121,8 @@ static switch_status_t load_config(void) set_global_default_gateway(val); } else if (!strcasecmp(var, "custom-query")) { set_global_custom_query(val); + } else if (!strcasecmp(var, "odbc-retries")) { + globals.odbc_num_retries = atoi(val); } } } @@ -143,6 +146,9 @@ static switch_status_t load_config(void) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened ODBC Database!\n"); } + if (globals.odbc_num_retries) { + switch_odbc_set_num_retries(globals.master_odbc, globals.odbc_num_retries); + } if (switch_odbc_handle_connect(globals.master_odbc) != SWITCH_ODBC_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); status = SWITCH_STATUS_FALSE; @@ -205,7 +211,7 @@ static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int switch_mutex_lock(globals.mutex); } /* Do the Query */ - if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS) { + if (globals.master_odbc && switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS) { char tmp_profile[129]; char tmp_gateway[129]; @@ -418,7 +424,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_easyroute_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_easyroute_shutdown) { - switch_odbc_handle_disconnect(globals.master_odbc); + if (globals.master_odbc) { + switch_odbc_handle_disconnect(globals.master_odbc); + switch_odbc_handle_destroy(&globals.master_odbc); + } switch_safe_free(globals.db_username); switch_safe_free(globals.db_password); switch_safe_free(globals.db_dsn); From 2e18c5b4d9fc583b76b4c8e4470579b1a21845ae Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Fri, 21 Jan 2011 10:51:34 -0500 Subject: [PATCH 33/54] freetdm: added threaded media to the TODO --- libs/freetdm/TODO | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libs/freetdm/TODO b/libs/freetdm/TODO index 6b8ef8f826..6b4cf71f5f 100644 --- a/libs/freetdm/TODO +++ b/libs/freetdm/TODO @@ -11,3 +11,12 @@ cannot be shown to end users, we already provide extensive logging for problem troubleshooting. +- Implement threaded IO. + Currently IO modules only work on-demand, where the user (ie, FreeSWITCH) drives the read/write + of media. If the user stops reading, some functions are not possible + (DTMF detection or Hangup tone detection). It would be useful to implement a FreeTDM mode + where the media is driven by a group of threads that are always reading (and possibly writing) + then when the user does ftdm_channel_read(), the media would be read from the buffers filled + by the media thread and not from the underlying IO device, this gives a chance to FreeTDM to + still perform hangup detection or other media services even if the application is not reading. + From 74de704973086d5cf360578ad9eac5977cfa4770 Mon Sep 17 00:00:00 2001 From: Mathieu Rene <mrene@avgs.ca> Date: Fri, 21 Jan 2011 11:32:14 -0500 Subject: [PATCH 34/54] FS-2942 - At least display __FILE__ and __LINE__ properly so we can have more data --- src/mod/formats/mod_shout/mod_shout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index a4965c4d67..1542be485c 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -584,7 +584,8 @@ static void launch_write_stream_thread(shout_context_t *context) } #define TC_BUFFER_SIZE 1024 * 32 -#define MPGERROR() {err = "MPG123 Error at __FILE__:__LINE__."; mpg123err = mpg123_strerror(context->mh); goto error; } +#define STR(_x) #_x +#define MPGERROR() {err = "MPG123 Error at " __FILE__ " : " STR(__LINE__) "."; mpg123err = mpg123_strerror(context->mh); goto error; } static switch_status_t shout_file_open(switch_file_handle_t *handle, const char *path) { shout_context_t *context; From 1561ad2ca695058c79183c07c59fe1dab825deff Mon Sep 17 00:00:00 2001 From: Mathieu Rene <mrene@avgs.ca> Date: Fri, 21 Jan 2011 11:38:56 -0500 Subject: [PATCH 35/54] extra spaces </ocd> --- src/mod/formats/mod_shout/mod_shout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 1542be485c..0b73c66b4f 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -585,7 +585,7 @@ static void launch_write_stream_thread(shout_context_t *context) #define TC_BUFFER_SIZE 1024 * 32 #define STR(_x) #_x -#define MPGERROR() {err = "MPG123 Error at " __FILE__ " : " STR(__LINE__) "."; mpg123err = mpg123_strerror(context->mh); goto error; } +#define MPGERROR() {err = "MPG123 Error at " __FILE__ ":" STR(__LINE__) "."; mpg123err = mpg123_strerror(context->mh); goto error; } static switch_status_t shout_file_open(switch_file_handle_t *handle, const char *path) { shout_context_t *context; From c91b409caa37a115a46f60f7b3725d7dd1b3c50e Mon Sep 17 00:00:00 2001 From: Mathieu Rene <mrene@avgs.ca> Date: Fri, 21 Jan 2011 11:53:20 -0500 Subject: [PATCH 36/54] Tricky preprocessor... try again --- src/mod/formats/mod_shout/mod_shout.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 0b73c66b4f..377cfe520c 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -584,8 +584,11 @@ static void launch_write_stream_thread(shout_context_t *context) } #define TC_BUFFER_SIZE 1024 * 32 -#define STR(_x) #_x -#define MPGERROR() {err = "MPG123 Error at " __FILE__ ":" STR(__LINE__) "."; mpg123err = mpg123_strerror(context->mh); goto error; } + +#define CONCAT_LOCATION(_x,_y) _x ":" #_y +#define MAKE_LOCATION(_x,_y) CONCAT_LOCATION(_x,_y) +#define HERE MAKE_LOCATION(__FILE__, __LINE__) +#define MPGERROR() {err = "MPG123 Error at " HERE "."; mpg123err = mpg123_strerror(context->mh); goto error; } static switch_status_t shout_file_open(switch_file_handle_t *handle, const char *path) { shout_context_t *context; From 6e2b1bd328607b2f0d5175b57389dfd2c3c62066 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick <daniel@seventhsignal.de> Date: Fri, 21 Jan 2011 21:05:01 +0100 Subject: [PATCH 37/54] initial checkin of mod_snmp --- .../event_handlers/mod_snmp/FREESWITCH-MIB | 110 ++++++++++ src/mod/event_handlers/mod_snmp/Makefile | 7 + src/mod/event_handlers/mod_snmp/mod_snmp.c | 138 +++++++++++++ src/mod/event_handlers/mod_snmp/subagent.c | 189 ++++++++++++++++++ src/mod/event_handlers/mod_snmp/subagent.h | 8 + 5 files changed, 452 insertions(+) create mode 100644 src/mod/event_handlers/mod_snmp/FREESWITCH-MIB create mode 100644 src/mod/event_handlers/mod_snmp/Makefile create mode 100644 src/mod/event_handlers/mod_snmp/mod_snmp.c create mode 100644 src/mod/event_handlers/mod_snmp/subagent.c create mode 100644 src/mod/event_handlers/mod_snmp/subagent.h diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB new file mode 100644 index 0000000000..9584c8bac3 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB @@ -0,0 +1,110 @@ +FREESWITCH-MIB DEFINITIONS ::= BEGIN + +IMPORTS + OBJECT-TYPE, MODULE-IDENTITY, + Integer32, Gauge32, Counter32, Counter64, TimeTicks, + enterprises, + FROM SNMPv2-SMI + + DisplayString + FROM SNMPv2-TC +; + + +freeswitch MODULE-IDENTITY + LAST-UPDATED "201101170000Z" + ORGANIZATION "www.freeswitch.org" + CONTACT-INFO + "Primary contact: Anthony Minessale II + Email: anthm@freeswitch.org" + DESCRIPTION + "This file defines the private FreeSWITCH SNMP MIB extensions." + REVISION "201101170000Z" + DESCRIPTION + "First draft by daniel.swarbrick@seventhsignal.de" + ::= { enterprises 27880 } + + +core OBJECT IDENTIFIER ::= { freeswitch 1 } +mod-sofia OBJECT IDENTIFIER ::= { freeswitch 1001 } +mod-skinny OBJECT IDENTIFIER ::= { freeswitch 1002 } + + +identity OBJECT IDENTIFIER ::= { core 1 } + +versionString OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "FreeSWITCH version as a string" + ::= { identity 1 } + +uuid OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "FreeSWITCH core UUID" + ::= { identity 2 } + + +systemStats OBJECT IDENTIFIER ::= { core 2 } + +uptime OBJECT-TYPE + SYNTAX TimeTicks + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "FreeSWITCH process uptime in hundredths of seconds" + ::= { systemStats 1 } + +sessionsSinceStartup OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of sessions since FreeSWITCH process was started" + ::= { systemStats 2 } + +currentSessions OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Currently active sessions" + ::= { systemStats 3 } + +maxSessions OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum permissible active sessions" + ::= { systemStats 4 } + +currentCalls OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Currently active calls" + ::= { systemStats 5 } + +sessionsPerSecond OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Current sessions per second" + ::= { systemStats 6 } + +maxSessionsPerSecond OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum permissible sessions per second" + ::= { systemStats 7 } + +END diff --git a/src/mod/event_handlers/mod_snmp/Makefile b/src/mod/event_handlers/mod_snmp/Makefile new file mode 100644 index 0000000000..1d8827daf1 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/Makefile @@ -0,0 +1,7 @@ +include ../../../../build/modmake.rules + +LOCAL_CFLAGS=-I `net-snmp-config --cflags` +LOCAL_LDFLAGS=`net-snmp-config --agent-libs` +LOCAL_OBJS=subagent.o + +local_depend: $(LOCAL_OBJS) diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c new file mode 100644 index 0000000000..040e82b602 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -0,0 +1,138 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org> + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II <anthm@freeswitch.org> + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Daniel Swarbrick <daniel.swarbrick@seventhsignal.de> + * Stefan Knoblich <s.knoblich@axsentis.de> + * + * mod_snmp.c -- SNMP AgentX Subagent Module + * + */ +#include <switch.h> + +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "subagent.h" + +static struct { + switch_memory_pool_t *pool; + int shutdown; +} globals; + +SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown); +SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime); +SWITCH_MODULE_DEFINITION(mod_snmp, mod_snmp_load, mod_snmp_shutdown, mod_snmp_runtime); + + +static int snmp_callback_log(int major, int minor, void *serverarg, void *clientarg) +{ + struct snmp_log_message *slm = (struct snmp_log_message *) serverarg; + switch_log_printf(SWITCH_CHANNEL_LOG, slm->priority, "%s", slm->msg); + return SNMP_ERR_NOERROR; +} + + +static switch_state_handler_table_t state_handlers = { + /*.on_init */ NULL, + /*.on_routing */ NULL, + /*.on_execute */ NULL, + /*.on_hangup */ NULL, + /*.on_exchange_media */ NULL, + /*.on_soft_execute */ NULL, + /*.on_consume_media */ NULL, + /*.on_hibernate */ NULL, + /*.on_reset */ NULL, + /*.on_park */ NULL, + /*.on_reporting */ NULL +}; + + +static switch_status_t load_config(switch_memory_pool_t *pool) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + memset(&globals, 0, sizeof(globals)); + globals.pool = pool; + + return status; +} + + +SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + load_config(pool); + + switch_core_add_state_handler(&state_handlers); + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + /* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */ + snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, snmp_callback_log, NULL); + snmp_enable_calllog(); + + netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1); + netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); + + init_agent("mod_snmp"); + init_subagent(); + init_snmp("mod_snmp"); + + return status; +} + + +SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) +{ + /* block on select() */ + agent_check_and_process(1); + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown) +{ + globals.shutdown = 1; + switch_core_remove_state_handler(&state_handlers); + + snmp_shutdown("mod_snmp"); + + return SWITCH_STATUS_SUCCESS; +} + + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c new file mode 100644 index 0000000000..8a9f2dac21 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -0,0 +1,189 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org> + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II <anthm@freeswitch.org> + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Daniel Swarbrick <daniel.swarbrick@seventhsignal.de> + * Stefan Knoblich <s.knoblich@axsentis.de> + * + * mod_snmp.c -- SNMP AgentX Subagent Module + * + */ +#include <switch.h> +#include <switch_version.h> + +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> +#include "subagent.h" + + +static oid identity_oid[] = { 1,3,6,1,4,1,27880,1,1 }; +static oid systemStats_oid[] = { 1,3,6,1,4,1,27880,1,2 }; + +/* identity sub-IDs - these must match MIB */ +enum { + versionString_oid = 1, + uuid_oid +}; + + +/* systemStats sub-IDs - these must match MIB */ +enum { + uptime_oid = 1, + sessionsSinceStartup_oid, + currentSessions_oid, + maxSessions_oid, + currentCalls_oid, + sessionsPerSecond_oid, + maxSessionsPerSecond_oid +}; + + +void init_subagent(void) +{ + DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n")); + + netsnmp_register_handler(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY)); + netsnmp_register_handler(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY)); +} + + +int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) +{ + static char const version[] = SWITCH_VERSION_FULL; + char uuid[40] = ""; + netsnmp_request_info *request = NULL; + oid subid; + + switch(reqinfo->mode) { + case MODE_GET: + for (request = requests; request; request = request->next) { + subid = request->requestvb->name[OID_LENGTH(systemStats_oid)]; + + switch (subid) { + case versionString_oid: + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); + break; + case uuid_oid: + strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); + } + } + break; + + case MODE_GETNEXT: + snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n"); + break; + + default: + /* we should never get here, so this is a really bad error */ + snmp_log(LOG_ERR, "Unknown mode (%d) in handle_versionString\n", reqinfo->mode ); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + + +int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) +{ + netsnmp_request_info *request = NULL; + oid subid; + switch_time_t uptime; + uint32_t int_val; + + switch(reqinfo->mode) { + case MODE_GET: + for (request = requests; request; request = request->next) { + subid = request->requestvb->name[OID_LENGTH(systemStats_oid)]; + + switch (subid) { + case uptime_oid: + uptime = switch_core_uptime() / 10000; + snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime)); + break; + case sessionsSinceStartup_oid: + int_val = switch_core_session_id() - 1; + snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val)); + break; + case currentSessions_oid: + int_val = switch_core_session_count(); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case maxSessions_oid: + switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);; + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case currentCalls_oid: + /* + * This is zero for now, since there is no convenient way to get total call + * count (not to be confused with session count), without touching the + * database. + */ + int_val = 0; + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case sessionsPerSecond_oid: + switch_core_session_ctl(SCSC_LAST_SPS, &int_val); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case maxSessionsPerSecond_oid: + switch_core_session_ctl(SCSC_SPS, &int_val); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); + } + } + break; + + case MODE_GETNEXT: + snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n"); + break; + + default: + /* we should never get here, so this is a really bad error */ + snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h new file mode 100644 index 0000000000..8a57d8a9f7 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/subagent.h @@ -0,0 +1,8 @@ +#ifndef subagent_H +#define subagent_H + +void init_subagent(void); +Netsnmp_Node_Handler handle_identity; +Netsnmp_Node_Handler handle_systemStats; + +#endif /* subagent_H */ From accc28528009361b4b1e268431d6e2b94112020a Mon Sep 17 00:00:00 2001 From: Moises Silva <moy@sangoma.com> Date: Fri, 21 Jan 2011 15:29:07 -0500 Subject: [PATCH 38/54] freetdm: ftmod_wanpipe dummy for disabling echotrain --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 3b384cdf32..e08fd61f3b 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -664,6 +664,8 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) } } break; + case FTDM_COMMAND_DISABLE_ECHOTRAIN: { err = 0; } + break; case FTDM_COMMAND_ENABLE_DTMF_DETECT: { #ifdef WP_API_FEATURE_DTMF_EVENTS From 1cf79386c80712311c656a166b9dec5847857266 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Fri, 21 Jan 2011 14:27:51 -0600 Subject: [PATCH 39/54] FS-2917 --- src/switch_core.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/switch_core.c b/src/switch_core.c index b531111a6d..43fb36d705 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -151,13 +151,21 @@ static void check_ip(void) SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback) { send_heartbeat(); - check_ip(); /* reschedule this task */ task->runtime = switch_epoch_time_now(NULL) + 20; } +SWITCH_STANDARD_SCHED_FUNC(check_ip_callback) +{ + check_ip(); + + /* reschedule this task */ + task->runtime = switch_epoch_time_now(NULL) + 60; +} + + SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console) { if ((runtime.console = fopen(console, "a")) == 0) { @@ -1357,6 +1365,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL); + switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD); + switch_uuid_get(&uuid); switch_uuid_format(runtime.uuid_str, &uuid); From 3dd9d5c0a399757059c60d9d8c751b97383da676 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Fri, 21 Jan 2011 14:35:23 -0600 Subject: [PATCH 40/54] FS-3007 --- src/mod/endpoints/mod_sofia/sofia_presence.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 94fef61181..19125c600b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -630,6 +630,11 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) char *probe_user = NULL, *probe_euser, *probe_host, *p; struct dialog_helper dh = { { 0 } }; + if (strcasecmp(proto, SOFIA_CHAT_PROTO) != 0) { + goto done; + } + + if (!to || !(probe_user = strdup(to))) { goto done; } @@ -2405,6 +2410,20 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_event_fire(&sevent); } + } else if (to_user && (strcasecmp(proto, SOFIA_CHAT_PROTO) != 0)) { + if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", proto); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "long", profile->name); + switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); + switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s%s%s@%s", proto, "+", to_user, to_host); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str); + switch_event_fire(&sevent); + + } } else { if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); From 3fa3e11ca23f788841e00aef8342e1718675477d Mon Sep 17 00:00:00 2001 From: Michael Jerris <mike@jerris.com> Date: Fri, 21 Jan 2011 16:03:19 -0500 Subject: [PATCH 41/54] FS-3002: handle 2833 in do_flush instead of dropping valid dtmf --- src/switch_apr.c | 2 +- src/switch_rtp.c | 409 ++++++++++++++++++++++++++++------------------- 2 files changed, 245 insertions(+), 166 deletions(-) diff --git a/src/switch_apr.c b/src/switch_apr.c index 4c99662f45..3798d6e2dc 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -833,7 +833,7 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recvfrom(switch_sockaddr_t *from, */ } - if (r == 35) { + if (r == 35 || r == 730035) { r = SWITCH_STATUS_BREAK; } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 3ce7a07e60..faf2868f48 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -32,6 +32,7 @@ */ //#define DEBUG_2833 //#define RTP_DEBUG_WRITE_DELTA +//#define DEBUG_MISSED_SEQ #include <switch.h> #include <switch_stun.h> #undef PACKAGE_NAME @@ -245,6 +246,9 @@ struct switch_rtp { switch_time_t send_time; switch_byte_t auto_adj_used; uint8_t pause_jb; + uint16_t last_seq; + switch_time_t last_read_time; + switch_size_t last_flush_packet_count; }; struct switch_rtcp_senderinfo { @@ -256,6 +260,180 @@ struct switch_rtcp_senderinfo { unsigned oc:32; }; +typedef enum { + RESULT_CONTINUE, + RESULT_GOTO_END, + RESULT_GOTO_RECVFROM, + RESULT_GOTO_TIMERCHECK +} handle_rfc2833_result_t; + +static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_size_t bytes, int *do_cng) +{ +#ifdef DEBUG_2833 + if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); + } +#endif + + if (rtp_session->dtmf_data.in_digit_sanity && !--rtp_session->dtmf_data.in_digit_sanity) { + rtp_session->dtmf_data.last_digit = 0; + rtp_session->dtmf_data.in_digit_ts = 0; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF sanity check.\n"); + } + + /* RFC2833 ... like all RFC RE: VoIP, guaranteed to drive you to insanity! + We know the real rules here, but if we enforce them, it's an interop nightmare so, + we put up with as much as we can so we don't have to deal with being punished for + doing it right. Nice guys finish last! + */ + if (bytes > rtp_header_len && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && + !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + switch_size_t len = bytes - rtp_header_len; + unsigned char *packet = (unsigned char *) rtp_session->recv_msg.body; + int end; + uint16_t duration; + char key; + uint16_t in_digit_seq; + uint32_t ts; + + if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) { + packet += 4; + len -= 4; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF payload offset by 4 bytes.\n"); + } + + if (!(packet[0] || packet[1] || packet[2] || packet[3])) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF payload check.\n"); + rtp_session->dtmf_data.last_digit = 0; + rtp_session->dtmf_data.in_digit_ts = 0; + } + + end = packet[1] & 0x80 ? 1 : 0; + duration = (packet[2] << 8) + packet[3]; + key = switch_rfc2833_to_char(packet[0]); + in_digit_seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); + ts = htonl(rtp_session->recv_msg.header.ts); + + if (in_digit_seq < rtp_session->dtmf_data.in_digit_seq) { + if (rtp_session->dtmf_data.in_digit_seq - in_digit_seq > 100) { + rtp_session->dtmf_data.in_digit_seq = 0; + } + } +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) + packet[1], (unsigned) packet[2], (unsigned) packet[3]); +#endif + + if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) { + + rtp_session->dtmf_data.in_digit_seq = in_digit_seq; +#ifdef DEBUG_2833 + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", + key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, + ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : ""); +#endif + + if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && + rtp_session->dtmf_data.in_digit_ts) { + switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0) }; +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); +#endif + switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); + rtp_session->dtmf_data.in_digit_queued = 1; + } + + /* only set sanity if we do NOT ignore the packet */ + if (rtp_session->dtmf_data.in_digit_ts) { + rtp_session->dtmf_data.in_digit_sanity = 2000; + } + + if (rtp_session->dtmf_data.last_duration > duration && + rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) { + rtp_session->dtmf_data.flip++; + } + + if (end) { + if (rtp_session->dtmf_data.in_digit_ts) { + switch_dtmf_t dtmf = { key, duration }; + + if (ts > rtp_session->dtmf_data.in_digit_ts) { + dtmf.duration += (ts - rtp_session->dtmf_data.in_digit_ts); + } + if (rtp_session->dtmf_data.flip) { + dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF; + rtp_session->dtmf_data.flip = 0; +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n"); +#endif + } +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", + dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration); +#endif + + if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) { +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); +#endif + switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); + } + + rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit; + + rtp_session->dtmf_data.in_digit_ts = 0; + rtp_session->dtmf_data.in_digit_sanity = 0; + rtp_session->dtmf_data.in_digit_queued = 0; + *do_cng = 1; + } else { + if (!switch_rtp_ready(rtp_session)) { + return RESULT_GOTO_END; + } + switch_cond_next(); + return RESULT_GOTO_RECVFROM; + } + + } else if (!rtp_session->dtmf_data.in_digit_ts) { + rtp_session->dtmf_data.in_digit_ts = ts; + rtp_session->dtmf_data.first_digit = key; + rtp_session->dtmf_data.in_digit_sanity = 2000; + } + + rtp_session->dtmf_data.last_duration = duration; + } else { +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n", + key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end); +#endif + switch_cond_next(); + return RESULT_GOTO_RECVFROM; + } + } + + if (bytes && rtp_session->dtmf_data.in_digit_ts) { + if (!switch_rtp_ready(rtp_session)) { + return RESULT_GOTO_END; + } + + if (!rtp_session->dtmf_data.in_interleaved && rtp_session->recv_msg.header.pt != rtp_session->recv_te) { + /* Drat, they are sending audio still as well as DTMF ok fine..... *sigh* */ + rtp_session->dtmf_data.in_interleaved = 1; + } + + if (rtp_session->dtmf_data.in_interleaved || (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION)) { + if (rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + return RESULT_GOTO_RECVFROM; + } + } else { + *do_cng = 1; + return RESULT_GOTO_TIMERCHECK; + } + } + + return RESULT_CONTINUE; +} + static int global_init = 0; static int rtp_common_write(switch_rtp_t *rtp_session, rtp_msg_t *send_msg, void *data, uint32_t datalen, switch_payload_t payload, uint32_t timestamp, switch_frame_flag_t *flags); @@ -2157,6 +2335,15 @@ static void do_flush(switch_rtp_t *rtp_session) bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes); if (bytes) { + int do_cng = 0; + + /* Make sure to handle RFC2833 packets, even if we're flushing the packets */ + if (bytes > rtp_header_len && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + handle_rfc2833(rtp_session, bytes, &do_cng); +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "*** RTP packet handled in flush loop ***\n"); +#endif + } flushed++; @@ -2195,7 +2382,52 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes); ts = ntohl(rtp_session->recv_msg.header.ts); - + + if (*bytes ) { + uint16_t seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); + + if (rtp_session->last_seq && rtp_session->last_seq+1 != seq) { +#ifdef DEBUG_MISSED_SEQ + switch_size_t flushed_packets_diff = rtp_session->stats.inbound.flush_packet_count - rtp_session->last_flush_packet_count; + switch_size_t num_missed = (switch_size_t)seq - (rtp_session->last_seq+1); + + if (num_missed == 1) { /* We missed one packet */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missed one RTP frame with sequence [%d]%s. Time since last read [%d]\n", + rtp_session->last_seq+1, (flushed_packets_diff == 1) ? " (flushed by FS)" : " (missed)", + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else { /* We missed multiple packets */ + if (flushed_packets_diff == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (missed). Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else if (flushed_packets_diff == num_missed) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (flushed by FS). Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else if (num_missed > flushed_packets_diff) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (%d packets flushed by FS, %d packets missed)." + " Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + flushed_packets_diff, num_missed-flushed_packets_diff, + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (%d packets flushed by FS). Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + flushed_packets_diff, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } + } +#endif + } + rtp_session->last_seq = seq; + } + + rtp_session->last_flush_packet_count = rtp_session->stats.inbound.flush_packet_count; + rtp_session->last_read_time = switch_micro_time_now(); + if (*bytes && (!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) && ts && !rtp_session->jb && !rtp_session->pause_jb && ts == rtp_session->last_cng_ts) { /* we already sent this frame..... */ @@ -2836,173 +3068,20 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ bytes = sbytes; } -#ifdef DEBUG_2833 - if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); - } -#endif - if (rtp_session->dtmf_data.in_digit_sanity && !--rtp_session->dtmf_data.in_digit_sanity) { - rtp_session->dtmf_data.last_digit = 0; - rtp_session->dtmf_data.in_digit_ts = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF sanity check.\n"); - } - - /* RFC2833 ... like all RFC RE: VoIP, guaranteed to drive you to insanity! - We know the real rules here, but if we enforce them, it's an interop nightmare so, - we put up with as much as we can so we don't have to deal with being punished for - doing it right. Nice guys finish last! - */ - if (bytes > rtp_header_len && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && - !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { - switch_size_t len = bytes - rtp_header_len; - unsigned char *packet = (unsigned char *) rtp_session->recv_msg.body; - int end; - uint16_t duration; - char key; - uint16_t in_digit_seq; - uint32_t ts; - - - if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) { - packet += 4; - len -= 4; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF payload offset by 4 bytes.\n"); - } - - if (!(packet[0] || packet[1] || packet[2] || packet[3])) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF payload check.\n"); - rtp_session->dtmf_data.last_digit = 0; - rtp_session->dtmf_data.in_digit_ts = 0; - } - - end = packet[1] & 0x80 ? 1 : 0; - duration = (packet[2] << 8) + packet[3]; - key = switch_rfc2833_to_char(packet[0]); - in_digit_seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); - ts = htonl(rtp_session->recv_msg.header.ts); - - if (in_digit_seq < rtp_session->dtmf_data.in_digit_seq) { - if (rtp_session->dtmf_data.in_digit_seq - in_digit_seq > 100) { - rtp_session->dtmf_data.in_digit_seq = 0; - } - } -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) - packet[1], (unsigned) packet[2], (unsigned) packet[3]); -#endif - - if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) { - - rtp_session->dtmf_data.in_digit_seq = in_digit_seq; -#ifdef DEBUG_2833 - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", - key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, - ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : ""); -#endif - - if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && - rtp_session->dtmf_data.in_digit_ts) { - switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0) }; -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); -#endif - switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); - rtp_session->dtmf_data.in_digit_queued = 1; - } - - /* only set sanity if we do NOT ignore the packet */ - if (rtp_session->dtmf_data.in_digit_ts) { - rtp_session->dtmf_data.in_digit_sanity = 2000; - } - - if (rtp_session->dtmf_data.last_duration > duration && - rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) { - rtp_session->dtmf_data.flip++; - } - - if (end) { - if (rtp_session->dtmf_data.in_digit_ts) { - switch_dtmf_t dtmf = { key, duration }; - - if (ts > rtp_session->dtmf_data.in_digit_ts) { - dtmf.duration += (ts - rtp_session->dtmf_data.in_digit_ts); - } - if (rtp_session->dtmf_data.flip) { - dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF; - rtp_session->dtmf_data.flip = 0; -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n"); -#endif - } -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", - dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration); -#endif - - if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) { -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); -#endif - switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); - } - - rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit; - - rtp_session->dtmf_data.in_digit_ts = 0; - rtp_session->dtmf_data.in_digit_sanity = 0; - rtp_session->dtmf_data.in_digit_queued = 0; - do_cng = 1; - } else { - if (!switch_rtp_ready(rtp_session)) { - goto end; - } - switch_cond_next(); - goto recvfrom; - } - - } else if (!rtp_session->dtmf_data.in_digit_ts) { - rtp_session->dtmf_data.in_digit_ts = ts; - rtp_session->dtmf_data.first_digit = key; - rtp_session->dtmf_data.in_digit_sanity = 2000; - } - - rtp_session->dtmf_data.last_duration = duration; - } else { -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n", - key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end); -#endif - switch_cond_next(); - goto recvfrom; - } - } - - if (rtp_session->dtmf_data.in_digit_ts) { - - } - - - if (bytes && rtp_session->dtmf_data.in_digit_ts) { - if (!switch_rtp_ready(rtp_session)) { - goto end; - } - - if (!rtp_session->dtmf_data.in_interleaved && rtp_session->recv_msg.header.pt != rtp_session->recv_te) { - /* Drat, they are sending audio still as well as DTMF ok fine..... *sigh* */ - rtp_session->dtmf_data.in_interleaved = 1; - } - - if (rtp_session->dtmf_data.in_interleaved || (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION)) { - if (rtp_session->recv_msg.header.pt == rtp_session->recv_te) { - goto recvfrom; - } - } else { - return_cng_frame(); - } + /* Handle incoming RFC2833 packets */ + switch (handle_rfc2833(rtp_session, bytes, &do_cng)) { + case RESULT_GOTO_END: + goto end; + case RESULT_GOTO_RECVFROM: + goto recvfrom; + case RESULT_GOTO_TIMERCHECK: + goto timer_check; + case RESULT_CONTINUE: + goto result_continue; } + result_continue: timer_check: if (do_cng) { From e0ed0008b1712d00f21d8fedce32eeb531e5da82 Mon Sep 17 00:00:00 2001 From: Brian West <brian@freeswitch.org> Date: Fri, 21 Jan 2011 15:08:26 -0600 Subject: [PATCH 42/54] Fix ZRTP --- src/switch_rtp.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index faf2868f48..4acadfe2ff 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2726,14 +2726,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && - rtp_session->recv_msg.header.pt != 13 && - rtp_session->recv_msg.header.pt != rtp_session->recv_te && - (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && - rtp_session->recv_msg.header.pt != rtp_session->payload) { - /* drop frames of incorrect payload number and return CNG frame instead */ - return_cng_frame(); - } if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_read_pollfd) { rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0); @@ -2812,6 +2804,15 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ goto end; } + if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && + rtp_session->recv_msg.header.pt != 13 && + rtp_session->recv_msg.header.pt != rtp_session->recv_te && + (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && + rtp_session->recv_msg.header.pt != rtp_session->payload) { + /* drop frames of incorrect payload number and return CNG frame instead */ + return_cng_frame(); + } + if (!bytes && (io_flags & SWITCH_IO_FLAG_NOBLOCK)) { rtp_session->missed_count = 0; ret = 0; From f5dafc9911eb892e0ac557bc892638cc9fb67014 Mon Sep 17 00:00:00 2001 From: Daniel Swarbrick <daniel@seventhsignal.de> Date: Fri, 21 Jan 2011 23:42:30 +0100 Subject: [PATCH 43/54] add mod_snmp to modules.conf.in and modules.conf.xml (commented out) --- build/modules.conf.in | 1 + conf/autoload_configs/modules.conf.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/build/modules.conf.in b/build/modules.conf.in index 2be000f6b3..84a9e9a74d 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -78,6 +78,7 @@ event_handlers/mod_cdr_sqlite #event_handlers/mod_cdr_pg_csv #event_handlers/mod_radius_cdr #event_handlers/mod_erlang_event +#event_handlers/mod_snmp formats/mod_native_file formats/mod_sndfile #formats/mod_shout diff --git a/conf/autoload_configs/modules.conf.xml b/conf/autoload_configs/modules.conf.xml index b7100bd304..2e7ebfabe5 100644 --- a/conf/autoload_configs/modules.conf.xml +++ b/conf/autoload_configs/modules.conf.xml @@ -24,6 +24,7 @@ <load module="mod_event_socket"/> <!-- <load module="mod_zeroconf"/> --> <!-- <load module="mod_erlang_event"/> --> + <!-- <load module="mod_snmp"/> --> <!-- Directory Interfaces --> <!-- <load module="mod_ldap"/> --> From 4eccdfef58a64652ae2a1f0a7a1f11ae55346420 Mon Sep 17 00:00:00 2001 From: Andrew Thompson <andrew@hijacked.us> Date: Fri, 21 Jan 2011 21:47:46 -0500 Subject: [PATCH 44/54] mod_erlang_event: Don't urlencode events (and destroy an event after use) --- src/mod/event_handlers/mod_erlang_event/ei_helpers.c | 1 + src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c index a99b52074c..db4f7780e0 100644 --- a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c +++ b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c @@ -111,6 +111,7 @@ void ei_encode_switch_event_headers(ei_x_buff * ebuf, switch_event_t *event) for (hp = event->headers; hp; hp = hp->next) { ei_x_encode_tuple_header(ebuf, 2); _ei_x_encode_string(ebuf, hp->name); + switch_url_decode(hp->value); _ei_x_encode_string(ebuf, hp->value); } diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 8d3c594b75..1a8bd00790 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -532,6 +532,7 @@ static switch_status_t notify_new_session(listener_t *listener, session_elem_t * session_element->uuid_str); } + switch_event_destroy(&call_event); ei_x_free(&lbuf); return SWITCH_STATUS_SUCCESS; } From 8d6d52e015411649e0591eb7ad667885523b99c3 Mon Sep 17 00:00:00 2001 From: Andrew Thompson <andrew@hijacked.us> Date: Fri, 21 Jan 2011 21:50:02 -0500 Subject: [PATCH 45/54] mod_conference Add energy level to conference_add_event_member_data This is useful when you want to find the energy a member joined with without having to pull the XML list --- src/mod/applications/mod_conference/mod_conference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 2d9341a598..7f7ee83795 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -477,6 +477,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false" ); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", switch_test_flag(member, MFLAG_MOD) ? "moderator" : "member"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Energy-Level", "%d", member->energy_level); return status; } From 9fe440b2fe63935331b148ffc1d3c7a5ddffa20b Mon Sep 17 00:00:00 2001 From: Andrew Thompson <andrew@hijacked.us> Date: Fri, 21 Jan 2011 21:53:03 -0500 Subject: [PATCH 46/54] mod_erlang_event Add proper locking for the list of XML bindings --- .../event_handlers/mod_erlang_event/handle_msg.c | 4 ++-- .../mod_erlang_event/mod_erlang_event.c | 13 +++++++++---- .../mod_erlang_event/mod_erlang_event.h | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/mod/event_handlers/mod_erlang_event/handle_msg.c b/src/mod/event_handlers/mod_erlang_event/handle_msg.c index 9ae15277fd..87f91fc51b 100644 --- a/src/mod/event_handlers/mod_erlang_event/handle_msg.c +++ b/src/mod/event_handlers/mod_erlang_event/handle_msg.c @@ -778,7 +778,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, e binding->process.pid = msg->from; binding->listener = listener; - switch_thread_rwlock_wrlock(globals.listener_rwlock); + switch_thread_rwlock_wrlock(globals.bindings_rwlock); for (ptr = bindings.head; ptr && ptr->next; ptr = ptr->next); @@ -789,7 +789,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, e } switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | section); - switch_thread_rwlock_unlock(globals.listener_rwlock); + switch_thread_rwlock_unlock(globals.bindings_rwlock); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sections %d\n", switch_xml_get_binding_sections(bindings.search_binding)); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 1a8bd00790..900b9655ff 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -90,7 +90,7 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) { struct erlang_binding *ptr, *lst = NULL; - switch_thread_rwlock_wrlock(globals.listener_rwlock); + switch_thread_rwlock_wrlock(globals.bindings_rwlock); switch_xml_set_binding_sections(bindings.search_binding, SWITCH_XML_SECTION_MAX); @@ -100,7 +100,7 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) if (ptr->next) { bindings.head = ptr->next; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed all (only?) listeners\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed all (only?) binding\n"); bindings.head = NULL; break; } @@ -111,13 +111,13 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) lst->next = NULL; } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed listener\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed binding\n"); } else { switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | ptr->section); } } - switch_thread_rwlock_unlock(globals.listener_rwlock); + switch_thread_rwlock_unlock(globals.bindings_rwlock); } @@ -381,6 +381,8 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c section = switch_xml_parse_section_string((char *) sectionstr); + switch_thread_rwlock_rdlock(globals.bindings_rwlock); + for (ptr = bindings.head; ptr; ptr = ptr->next) { if (ptr->section != section) continue; @@ -417,6 +419,8 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c switch_mutex_unlock(ptr->listener->sock_mutex); } + switch_thread_rwlock_unlock(globals.bindings_rwlock); + ei_x_free(&buf); if (!p) { @@ -1638,6 +1642,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_erlang_event_load) memset(&prefs, 0, sizeof(prefs)); switch_thread_rwlock_create(&globals.listener_rwlock, pool); + switch_thread_rwlock_create(&globals.bindings_rwlock, pool); switch_mutex_init(&globals.fetch_reply_mutex, SWITCH_MUTEX_DEFAULT, pool); switch_mutex_init(&globals.listener_count_mutex, SWITCH_MUTEX_UNNESTED, pool); switch_core_hash_init(&globals.fetch_reply_hash, pool); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h index dacfbd661b..121e7b4f95 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h @@ -161,6 +161,7 @@ struct api_command_struct { struct globals_struct { switch_thread_rwlock_t *listener_rwlock; + switch_thread_rwlock_t *bindings_rwlock; switch_event_node_t *node; switch_mutex_t *ref_mutex; switch_mutex_t *fetch_reply_mutex; From 5316bcd9dc648b3874ebddea75ed6f34431c7f35 Mon Sep 17 00:00:00 2001 From: Steve Underwood <steveu@coppice.org> Date: Sat, 22 Jan 2011 13:36:16 +0800 Subject: [PATCH 47/54] Typo in the spandsp .pc.in file fixed --- libs/spandsp/spandsp.pc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/spandsp/spandsp.pc.in b/libs/spandsp/spandsp.pc.in index 86a50ff62a..1a91ba04e1 100644 --- a/libs/spandsp/spandsp.pc.in +++ b/libs/spandsp/spandsp.pc.in @@ -1,5 +1,5 @@ prefix=@prefix@ -exec_prefix=@exec_prefix@ +exec_prefix=@prefix@ libdir=@libdir@ includedir=@includedir@ From 9adac7c6988df8436c634edaaa13ae39067f8df7 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich <s.knoblich@axsentis.de> Date: Sun, 23 Jan 2011 01:42:39 +0100 Subject: [PATCH 48/54] [fsxs] Remove APR and APR-UTIL libraries from fsxs LIBS variable. "LIBS" in the final fsxs script will be empty now. We still link against libfreeswitch when building a module, but we don't explicitly list (some of) its dependency libs anymore (this list was not complete anyway). This fixes a bogus /path_to_source/expat.la entry in LIBS that came from "apu-config --libs". Tested on Gentoo x86_64 (binutils 2.20.1) and Centos 5.5 (binutils 2.17.50). Tested-by: Stefan Knoblich <s.knoblich@axsentis.de> Signed-off-by: Stefan Knoblich <s.knoblich@axsentis.de> --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 8d35068c35..37a01d27fb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -349,7 +349,7 @@ scripts/fsxs: scripts/fsxs.in -e "s|@INCLUDES\@|-I$(prefix)/include|" \ -e "s|@SOLINK\@|$(SOLINK)|" \ -e "s|@LDFLAGS\@|-L$(prefix)/lib|" \ - -e "s|@LIBS\@|`./libs/apr/apr-1-config --libs` `./libs/apr-util/apu-1-config --libs`|" \ + -e "s|@LIBS\@||" \ $(top_srcdir)/scripts/fsxs.in > scripts/fsxs ## From b88cd3457a847cf05564df51bd8a60036b15bfd8 Mon Sep 17 00:00:00 2001 From: Jeff Lenk <jeff@jefflenk.com> Date: Sat, 22 Jan 2011 22:51:48 -0600 Subject: [PATCH 49/54] FS-3000 mod_conference: if more digits than the length of the correct pin the remaining digits are accounted for next retry --- .../mod_conference/mod_conference.c | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 7f7ee83795..e6a47bf1ec 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -5597,6 +5597,7 @@ SWITCH_STANDARD_APP(conference_function) char pin_buf[80] = ""; int pin_retries = 3; /* XXX - this should be configurable - i'm too lazy to do it right now... */ int pin_valid = 0; + int be_friendly = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; char *supplied_pin_value; @@ -5631,19 +5632,23 @@ SWITCH_STANDARD_APP(conference_function) switch_status_t pstatus = SWITCH_STATUS_FALSE; /* be friendly */ - if (conference->pin_sound) { - pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf)); - } else if (conference->tts_engine && conference->tts_voice) { - pstatus = - switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL); - } else { - pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL); + if (!be_friendly) { + if (conference->pin_sound) { + pstatus = conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf)); + } else if (conference->tts_engine && conference->tts_voice) { + pstatus = + switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, "please enter the conference pin number", NULL); + } else { + pstatus = switch_ivr_speak_text(session, "flite", "slt", "please enter the conference pin number", NULL); + } + + if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call"); + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + } } - if (pstatus != SWITCH_STATUS_SUCCESS && pstatus != SWITCH_STATUS_BREAK) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot ask the user for a pin, ending call"); - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - } + be_friendly = 1; /* wait for them if neccessary */ if (strlen(pin_buf) < strlen(dpin)) { @@ -5660,13 +5665,12 @@ SWITCH_STANDARD_APP(conference_function) pin_valid = (status == SWITCH_STATUS_SUCCESS && strcmp(pin_buf, dpin) == 0); if (!pin_valid) { - /* zero the collected pin */ - memset(pin_buf, 0, sizeof(pin_buf)); - /* more friendliness */ if (conference->bad_pin_sound) { conference_local_play_file(conference, session, conference->bad_pin_sound, 20, pin_buf, sizeof(pin_buf)); } + /* zero the collected pin */ + memset(pin_buf, 0, sizeof(pin_buf)); } pin_retries--; } From 0e37dcb5db19592d28eb771edb4a0d394f5275ac Mon Sep 17 00:00:00 2001 From: Jeff Lenk <jeff@jefflenk.com> Date: Sun, 23 Jan 2011 17:43:38 -0600 Subject: [PATCH 50/54] windows - tweak installer permissions --- w32/Setup/Product.wxs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/w32/Setup/Product.wxs b/w32/Setup/Product.wxs index 2f072aa8ca..1de2ec204d 100644 --- a/w32/Setup/Product.wxs +++ b/w32/Setup/Product.wxs @@ -57,6 +57,9 @@ WorkingDirectory="INSTALLLOCATION"/> <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/> <RegistryValue Root="HKCU" Key="Software\FreeSWITCH\FreeSWITCH" Name="installed" Type="integer" Value="1" KeyPath="yes"/> + <CreateFolder Directory="INSTALLLOCATION"> + <Permission User="Authenticated Users" GenericAll="yes" /> + </CreateFolder> </Component> <Component Id="FSCliShortcut" Guid="D209546C-C728-4d8f-BDB2-29AED8824282"> <Shortcut Id="FSCliStartMenuShortcut" @@ -65,6 +68,9 @@ Target="[INSTALLLOCATION]fs_cli.exe" WorkingDirectory="INSTALLLOCATION"/> <RegistryValue Root="HKCU" Key="Software\FreeSWITCH\FS_CLI" Name="installed" Type="integer" Value="1" KeyPath="yes"/> + <CreateFolder Directory="INSTALLLOCATION"> + <Permission User="Authenticated Users" GenericAll="yes" /> + </CreateFolder> </Component> </DirectoryRef> From 6294bc1620c94785f23bf6ae6966aaa67cf34c7f Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Mon, 24 Jan 2011 09:41:53 -0600 Subject: [PATCH 51/54] have samples_out reflect what was written to the FH not the file even with buffering --- src/switch_core_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_file.c b/src/switch_core_file.c index c00756ffc6..19f23546f0 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -391,10 +391,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) { *len = 0; } - fh->samples_out += blen; } } + fh->samples_out += orig_len; return status; } else { switch_status_t status; From 7a1dcb69581ba593f3dc3868c94c1124c41e64f3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Mon, 24 Jan 2011 09:43:16 -0600 Subject: [PATCH 52/54] add record_restart_time_limit_on_dtmf var --- src/switch_ivr_play_say.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 523dfdeb02..4e9e7b95ca 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -372,6 +372,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se switch_event_t *event; int divisor = 0; int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; + int restart_limit_on_dtmf = 0; const char *prefix; prefix = switch_channel_get_variable(channel, "sound_prefix"); @@ -528,6 +529,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) { asis = 1; } + + restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf")); if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) { vval = switch_core_session_strdup(session, p); @@ -637,6 +640,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { + + if (limit && restart_limit_on_dtmf) { + start = switch_epoch_time_now(NULL); + } + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; break; From 6e4c30ea377728107e0747d614565eca964fa1d3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Mon, 24 Jan 2011 09:49:27 -0600 Subject: [PATCH 53/54] update code in mod_celt to match API of 0.10.0 --- src/mod/codecs/mod_celt/mod_celt.c | 34 +++++++++++------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/mod/codecs/mod_celt/mod_celt.c b/src/mod/codecs/mod_celt/mod_celt.c index 37983f3683..8d36b6af12 100644 --- a/src/mod/codecs/mod_celt/mod_celt.c +++ b/src/mod/codecs/mod_celt/mod_celt.c @@ -53,8 +53,8 @@ static switch_status_t switch_celt_init(switch_codec_t *codec, switch_codec_flag return SWITCH_STATUS_FALSE; } - context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL); - + context->frame_size = codec->implementation->samples_per_packet; + context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, context->frame_size, NULL); context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size / codec->implementation->actual_samples_per_second + 4) / 8; /* @@ -106,15 +106,22 @@ static switch_status_t switch_celt_encode(switch_codec_t *codec, unsigned int *flag) { struct celt_context *context = codec->private_info; + int bytes = 0; if (!context) { return SWITCH_STATUS_FALSE; } - *encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, - (unsigned char *) encoded_data, context->bytes_per_packet); + bytes = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, + (unsigned char *) encoded_data, context->bytes_per_packet); - return SWITCH_STATUS_SUCCESS; + if (bytes > 0) { + *encoded_data_len = (uint32_t) bytes; + return SWITCH_STATUS_SUCCESS; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error!\n"); + return SWITCH_STATUS_GENERR; } static switch_status_t switch_celt_decode(switch_codec_t *codec, @@ -152,23 +159,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_celt_load) SWITCH_ADD_CODEC(codec_interface, "CELT ultra-low delay"); - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 114, /* the IANA code number */ - "CELT", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 32000, /* samples transferred per second */ - 32000, /* actual samples transferred per second */ - 32000, /* bits transferred per second */ - 10000, /* number of microseconds per frame */ - 320, /* number of samples per frame */ - 640, /* number of bytes per frame decompressed */ - 0, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet */ - switch_celt_init, /* function to initialize a codec handle using this implementation */ - switch_celt_encode, /* function to encode raw data into encoded data */ - switch_celt_decode, /* function to decode encoded data into raw data */ - switch_celt_destroy); /* deinitalize a codec handle using this implementation */ ms_per_frame = 2000; samples_per_frame = 96; bytes_per_frame = 192; From a8f5bf60a87fb27420846bd9d9af5e61f1f947d6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Mon, 24 Jan 2011 12:18:02 -0600 Subject: [PATCH 54/54] fix proper display of meta digit in log lines --- src/include/switch_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 2c4de14334..a1a93c6ac8 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -192,7 +192,7 @@ static inline char switch_itodtmf(char i) r = i + 55; } - return r; + return r + 48; } static inline int switch_dtmftoi(char *s)