Merge branch 'master' of git://git.freeswitch.org/freeswitch
This commit is contained in:
commit
d6cfc2f1e9
|
@ -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
|
||||
|
||||
##
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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"/> -->
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
##############################################################################
|
||||
# Copyright and license
|
||||
##############################################################################
|
||||
#
|
||||
# Spec file for package freeswitch-sounds-en-us-callie (version 1.0.12-8)
|
||||
#
|
||||
# Copyright (c) 2009 Patrick Laimbock
|
||||
# Some fixes and additions (c) 2011 Michal Bielicki
|
||||
# This file and all modifications and additions to the pristine
|
||||
# package are under the same license as the package itself.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
# Determine distribution
|
||||
##############################################################################
|
||||
|
||||
%define is_rhel5 %(test -f /etc/redhat-release && egrep -q 'release 5' /etc/redhat-release && echo 1 || echo 0)
|
||||
|
||||
##############################################################################
|
||||
# Set variables
|
||||
##############################################################################
|
||||
|
||||
%define version 1.0.14
|
||||
%define release 1
|
||||
|
||||
%define fsname freeswitch
|
||||
# you could add a version number to be more strict
|
||||
|
||||
%define prefix /opt/freeswitch
|
||||
%define _prefix %{prefix}
|
||||
|
||||
##############################################################################
|
||||
# General
|
||||
##############################################################################
|
||||
|
||||
Summary: FreeSWITCH en-us Callie prompts
|
||||
Name: freeswitch-sounds-en-us-callie
|
||||
Version: %{version}
|
||||
Release: %{release}%{?dist}
|
||||
License: MPL
|
||||
Group: Applications/Communications
|
||||
Packager: Patrick Laimbock <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
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
%description
|
||||
FreeSWITCH 48kHz en-us Callie prompts plus, during the installation,
|
||||
it will also install locally generated 8KHz, 16KHz and 32KHz prompts
|
||||
|
||||
%package -n freeswitch-sounds-en-us-callie-8000
|
||||
Summary: FreeSWITCH 8kHz en-us Callie prompts
|
||||
Group: Applications/Communications
|
||||
BuildArch: noarch
|
||||
Requires: %{fsname}
|
||||
|
||||
%description -n freeswitch-sounds-en-us-callie-8000
|
||||
FreeSWITCH 8kHz en-us Callie prompts
|
||||
|
||||
%package -n freeswitch-sounds-en-us-callie-16000
|
||||
Summary: FreeSWITCH 16kHz en-us Callie prompts
|
||||
Group: Applications/Communications
|
||||
BuildArch: noarch
|
||||
Requires: %{fsname}
|
||||
|
||||
%description -n freeswitch-sounds-en-us-callie-16000
|
||||
FreeSWITCH 16kHz en-us Callie prompts
|
||||
|
||||
%package -n freeswitch-sounds-en-us-callie-32000
|
||||
Summary: FreeSWITCH 32kHz en-us Callie prompts
|
||||
Group: Applications/Communications
|
||||
BuildArch: noarch
|
||||
Requires: %{fsname}
|
||||
|
||||
%description -n freeswitch-sounds-en-us-callie-32000
|
||||
FreeSWITCH 32kHz en-us Callie prompts
|
||||
|
||||
%package -n freeswitch-sounds-en-us-callie-48000
|
||||
Summary: FreeSWITCH 48kHz en-us Callie prompts
|
||||
Group: Applications/Communications
|
||||
BuildArch: noarch
|
||||
Requires: %{fsname}
|
||||
|
||||
%description -n freeswitch-sounds-en-us-callie-48000
|
||||
FreeSWITCH 48kHz en-us Callie prompts
|
||||
|
||||
%package -n freeswitch-sounds-en-us-callie-all
|
||||
Summary: FreeSWITCH en-us Callie prompts
|
||||
Group: Applications/Communications
|
||||
BuildArch: noarch
|
||||
Requires: %{fsname}
|
||||
Requires: freeswitch-sounds-en-us-callie-8000 = %{version}
|
||||
Requires: freeswitch-sounds-en-us-callie-16000 = %{version}
|
||||
Requires: freeswitch-sounds-en-us-callie-32000 = %{version}
|
||||
Requires: freeswitch-sounds-en-us-callie-48000 = %{version}
|
||||
|
||||
%description -n freeswitch-sounds-en-us-callie-all
|
||||
FreeSWITCH Callie prompts package that pulls in the 8KHz, 16KHz,
|
||||
32KHz and 48KHz RPMs
|
||||
|
||||
##############################################################################
|
||||
# Prep
|
||||
##############################################################################
|
||||
|
||||
%prep
|
||||
%setup -b0 -q -n en
|
||||
mkdir -p ./usr/callie
|
||||
# create buildsounds-callie.sh script in working dir
|
||||
echo '#!/bin/bash
|
||||
|
||||
sounds_location=$1
|
||||
for rate in 32000 16000 8000
|
||||
do
|
||||
for i in ascii base256 conference currency digits directory ivr misc phonetic-ascii time voicemail zrtp
|
||||
do
|
||||
mkdir -p $sounds_location/$i/$rate
|
||||
for f in `find $sounds_location/$i/48000 -name \*.wav`
|
||||
do
|
||||
echo "generating" $sounds_location/$i/$rate/`basename $f`
|
||||
sox $f -r $rate $sounds_location/$i/$rate/`basename $f`
|
||||
done
|
||||
done
|
||||
done' > ./us/callie/buildsounds-callie.sh
|
||||
%{__chmod} 0750 ./us/callie/buildsounds-callie.sh
|
||||
|
||||
##############################################################################
|
||||
# Build
|
||||
##############################################################################
|
||||
|
||||
%build
|
||||
# nothing to do here
|
||||
|
||||
##############################################################################
|
||||
# Install
|
||||
##############################################################################
|
||||
|
||||
%install
|
||||
[ "%{buildroot}" != '/' ] && rm -rf %{buildroot}
|
||||
|
||||
# create the sounds directories
|
||||
%{__install} -d -m 0750 %{buildroot}%{_prefix}/sounds/en/us/callie
|
||||
|
||||
pushd us/callie
|
||||
# first install the 48KHz sounds
|
||||
%{__cp} -prv ./* %{buildroot}%{_prefix}/sounds/en/us/callie
|
||||
# now resample the 48KHz ones to 8KHz, 16KHz and 32KHz
|
||||
./buildsounds-callie.sh %{buildroot}%{_prefix}/sounds/en/us/callie
|
||||
popd
|
||||
|
||||
##############################################################################
|
||||
# Clean
|
||||
##############################################################################
|
||||
|
||||
%clean
|
||||
[ "%{buildroot}" != '/' ] && rm -rf %{buildroot}
|
||||
|
||||
##############################################################################
|
||||
# Post
|
||||
##############################################################################
|
||||
|
||||
%post
|
||||
# generate the 8KHz, 16KHz and 32KHz prompts from the 48KHz ones
|
||||
cd %{_prefix}/sounds/en/us/callie
|
||||
./buildsounds-callie.sh %{_prefix}/sounds/en/us/callie
|
||||
|
||||
##############################################################################
|
||||
# Postun
|
||||
##############################################################################
|
||||
|
||||
%postun
|
||||
# you could check if there are sound files in 8000/ or
|
||||
# 16000/ or 32000/ and remove them *only* if the files
|
||||
# do not belong to an rpm
|
||||
|
||||
##############################################################################
|
||||
# Files
|
||||
##############################################################################
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%attr(0750,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/buildsounds-callie.sh
|
||||
|
||||
%files -n freeswitch-sounds-en-us-callie-8000
|
||||
%defattr(-,root,root,-)
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/8000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/8000
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/8000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/8000/*.wav
|
||||
|
||||
%files -n freeswitch-sounds-en-us-callie-16000
|
||||
%defattr(-,root,root,-)
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/16000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/16000
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/16000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/16000/*.wav
|
||||
|
||||
%files -n freeswitch-sounds-en-us-callie-32000
|
||||
%defattr(-,root,root,-)
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/32000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/32000
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/32000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/32000/*.wav
|
||||
|
||||
%files -n freeswitch-sounds-en-us-callie-48000
|
||||
%defattr(-,root,root,-)
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ascii/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/base256/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/conference/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/currency/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/digits/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/directory/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/ivr/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/misc/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/phonetic-ascii/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/time/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/voicemail/48000
|
||||
%attr(0750,freeswitch,daemon) %dir %{_prefix}/sounds/en/us/callie/zrtp/48000
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ascii/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/base256/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/conference/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/currency/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/digits/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/directory/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/ivr/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/misc/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/phonetic-ascii/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/time/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/voicemail/48000/*.wav
|
||||
%attr(0640,freeswitch,daemon) %{_prefix}/sounds/en/us/callie/zrtp/48000/*.wav
|
||||
|
||||
%files -n freeswitch-sounds-en-us-callie-all
|
||||
|
||||
##############################################################################
|
||||
# Changelog
|
||||
##############################################################################
|
||||
|
||||
%changelog
|
||||
* Tue Jan 18 2011 Michal Bielicki <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
|
||||
|
|
@ -53,7 +53,7 @@ Vendor: http://www.freeswitch.org/
|
|||
# Source files and where to get them
|
||||
#
|
||||
######################################################################################################################
|
||||
Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2
|
||||
Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2
|
||||
Source1: http://files.freeswitch.org/downloads/libs/celt-0.7.1.tar.gz
|
||||
Source2: http://files.freeswitch.org/downloads/libs/flite-1.3.99-latest.tar.gz
|
||||
Source3: http://files.freeswitch.org/downloads/libs/lame-3.97.tar.gz
|
||||
|
@ -89,8 +89,13 @@ BuildRequires: libtool >= 1.5.17
|
|||
BuildRequires: ncurses-devel
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: perl
|
||||
%if 0%{?fedora_version} >= 8
|
||||
BuildRequires: perl-ExtUtils-Embed
|
||||
%endif
|
||||
BuildRequires: pkgconfig
|
||||
%if %{_vendor} == redhat && 0%{?fedora} <= 6
|
||||
BuildRequires: termcap
|
||||
%endif
|
||||
BuildRequires: unixODBC-devel
|
||||
BuildRequires: gdbm-devel
|
||||
BuildRequires: db4-devel
|
||||
|
@ -893,7 +898,7 @@ fi
|
|||
%files python
|
||||
%defattr(-,freeswitch,daemon)
|
||||
%{prefix}/mod/mod_python*.so*
|
||||
%attr(0644, root, bin) /usr/lib/python2.4/site-packages/freeswitch.py*
|
||||
%attr(0644, root, bin) /usr/lib/python*/site-packages/freeswitch.py*
|
||||
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/python.conf.xml
|
||||
|
||||
|
@ -951,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
@ -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,
|
||||
|
@ -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,20 +5546,46 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_PROGRESS_MEDIA:
|
||||
{
|
||||
/* test signaling module compliance */
|
||||
if (sigmsg->channel->state != FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
|
||||
ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_PROGRESS_MEDIA sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_UP:
|
||||
{
|
||||
/* test signaling module compliance */
|
||||
if (sigmsg->channel->state != FTDM_CHANNEL_STATE_UP) {
|
||||
ftdm_log_chan(sigmsg->channel, FTDM_LOG_WARNING, "FTDM_SIGEVENT_UP sent in state %s\n", ftdm_channel_state2str(sigmsg->channel->state));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FTDM_SIGEVENT_STOP:
|
||||
if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) {
|
||||
/* this happens for FXS devices which blindly send SIGEVENT_STOP, we should fix it there ... */
|
||||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n");
|
||||
goto done;
|
||||
}
|
||||
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) {
|
||||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
|
||||
goto done;
|
||||
}
|
||||
if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n");
|
||||
/* if the user does not move us to hangup in 2 seconds, we will do it ourselves */
|
||||
ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer);
|
||||
{
|
||||
/* TODO: we could test for compliance here and check the state is FTDM_CHANNEL_STATE_TERMINATING
|
||||
* but several modules need to be updated first */
|
||||
|
||||
/* if the call was never started, do not send SIGEVENT_STOP
|
||||
this happens for FXS devices in ftmod_analog which blindly send SIGEVENT_STOP, we should fix it there ... */
|
||||
if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) {
|
||||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) {
|
||||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (sigmsg->channel->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Scheduling safety hangup timer\n");
|
||||
/* if the user does not move us to hangup in 2 seconds, we will do it ourselves */
|
||||
ftdm_sched_timer(globals.timingsched, "safety-hangup", FORCE_HANGUP_TIMER, execute_safety_hangup, sigmsg->channel, &sigmsg->channel->hangup_timer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -677,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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
@ -366,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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -237,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) {
|
||||
|
@ -271,6 +277,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 +297,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 +305,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 +375,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);
|
||||
|
@ -653,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
|
||||
|
@ -1257,20 +1270,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_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link connected event\n");
|
||||
break;
|
||||
default:
|
||||
*event_id = FTDM_OOB_ALARM_TRAP;
|
||||
/* *event_id = FTDM_OOB_ALARM_TRAP; */
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Ignoring wanpipe link disconnected event\n");
|
||||
break;
|
||||
};
|
||||
#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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -171,7 +191,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 || \
|
||||
|
@ -410,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)
|
||||
|
@ -574,84 +594,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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
/*!
|
||||
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
exec_prefix=@prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -5596,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;
|
||||
|
||||
|
@ -5630,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)) {
|
||||
|
@ -5659,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--;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
@ -532,6 +536,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;
|
||||
}
|
||||
|
@ -1637,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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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)
|
|
@ -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:
|
||||
*/
|
|
@ -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:
|
||||
*/
|
|
@ -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 */
|
|
@ -584,7 +584,11 @@ 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 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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
425
src/switch_rtp.c
425
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..... */
|
||||
|
@ -2494,13 +2726,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
}
|
||||
|
||||
if (rtp_session->recv_msg.header.pt != 13 &&
|
||||
rtp_session->recv_msg.header.pt != rtp_session->recv_te &&
|
||||
(!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) &&
|
||||
rtp_session->recv_msg.header.pt != rtp_session->payload) {
|
||||
/* drop frames of incorrect payload number and return CNG frame instead */
|
||||
return_cng_frame();
|
||||
}
|
||||
|
||||
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_read_pollfd) {
|
||||
rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0);
|
||||
|
@ -2579,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;
|
||||
|
@ -2835,173 +3069,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) {
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue