Merge branch 'master' into v1.4
This commit is contained in:
commit
dfd91879c4
|
@ -11,7 +11,7 @@ CURL=@CURL@
|
|||
if [ -f "$WGET" ]; then
|
||||
DOWNLOAD_CMD=$WGET
|
||||
elif [ -f "$CURL" ]; then
|
||||
DOWNLOAD_CMD="$CURL -O"
|
||||
DOWNLOAD_CMD="$CURL -L -O"
|
||||
fi
|
||||
|
||||
if [ -n "`echo $1 | grep '://'`" ]; then
|
||||
|
|
|
@ -94,6 +94,7 @@ endpoints/mod_skinny
|
|||
#endpoints/mod_skypopen
|
||||
endpoints/mod_sofia
|
||||
#endpoints/mod_unicall
|
||||
#event_handlers/mod_amqp
|
||||
event_handlers/mod_cdr_csv
|
||||
#event_handlers/mod_cdr_mongodb
|
||||
#event_handlers/mod_cdr_pg_csv
|
||||
|
|
1650
conf/curl/mime.types
1650
conf/curl/mime.types
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1650
conf/rayo/mime.types
1650
conf/rayo/mime.types
File diff suppressed because it is too large
Load Diff
1650
conf/sbc/mime.types
1650
conf/sbc/mime.types
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,63 @@
|
|||
<configuration name="amqp.conf" description="mod_amqp">
|
||||
<producers>
|
||||
<profile name="default">
|
||||
<connections>
|
||||
<connection name="primary">
|
||||
<param name="hostname" value="localhost"/>
|
||||
<param name="virtualhost" value="/"/>
|
||||
<param name="username" value="guest"/>
|
||||
<param name="password" value="guest"/>
|
||||
<param name="port" value="5673"/>
|
||||
<param name="heartbeat" value="0"/>
|
||||
</connection>
|
||||
<connection name="secondary">
|
||||
<param name="hostname" value="localhost"/>
|
||||
<param name="virtualhost" value="/"/>
|
||||
<param name="username" value="guest"/>
|
||||
<param name="password" value="guest"/>
|
||||
<param name="port" value="5672"/>
|
||||
<param name="heartbeat" value="0"/>
|
||||
</connection>
|
||||
</connections>
|
||||
<params>
|
||||
<param name="exchange" value="TAP.Events"/>
|
||||
<param name="exchange_type" value="topic"/>
|
||||
<param name="circuit_breaker_ms" value="10000"/>
|
||||
<param name="reconnect_interval_ms" value="1000"/>
|
||||
<param name="send_queue_size" value="5000"/>
|
||||
<param name="enable_fallback_format_fields" value="1"/>
|
||||
|
||||
<!-- The routing key is made from the format string, using the header values in the event specified in the format_fields.-->
|
||||
<!-- Fields that are prefixed with a # are treated as literals rather than doing a header lookup -->
|
||||
<param name="format_fields" value="#FreeSWITCH,FreeSWITCH-Hostname,Event-Name,Event-Subclass,Unique-ID"/>
|
||||
|
||||
<!-- If enable_fallback_format_fields is enabled, then you can | separate event headers, and if the first does not exist
|
||||
then the system will check additional configured header values.
|
||||
-->
|
||||
<!-- <param name="format_fields" value="#FreeSWITCH,FreeSWITCH-Hostname|#Unknown,Event-Name,Event-Subclass,Unique-ID"/> -->
|
||||
|
||||
<!-- <param name="eventFilter" value="SWITCH_EVENT_ALL"/> -->
|
||||
<param name="event_filter" value="SWITCH_EVENT_CHANNEL_CREATE,SWITCH_EVENT_CHANNEL_DESTROY,SWITCH_EVENT_HEARTBEAT,SWITCH_EVENT_DTMF"/>
|
||||
</params>
|
||||
</profile>
|
||||
</producers>
|
||||
<commands>
|
||||
<profile name="default">
|
||||
<connections>
|
||||
<connection name="primary">
|
||||
<param name="hostname" value="localhost"/>
|
||||
<param name="virtualhost" value="/"/>
|
||||
<param name="username" value="guest"/>
|
||||
<param name="password" value="guest"/>
|
||||
<param name="port" value="5672"/>
|
||||
<param name="heartbeat" value="0"/>
|
||||
</connection>
|
||||
</connections>
|
||||
<params>
|
||||
<param name="exchange" value="TAP.Commands"/>
|
||||
<param name="binding_key" value="commandBindingKey"/>
|
||||
<param name="reconnect_interval_ms" value="1000"/>
|
||||
</params>
|
||||
</profile>
|
||||
</commands>
|
||||
</configuration>
|
File diff suppressed because it is too large
Load Diff
|
@ -335,6 +335,7 @@
|
|||
if true, the destination number is not included -->
|
||||
<X-PRE-PROCESS cmd="set" data="presence_privacy=false"/>
|
||||
|
||||
<X-PRE-PROCESS cmd="set" data="au-ring=%(400,200,383,417);%(400,2000,383,417)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="be-ring=%(1000,3000,425)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="ca-ring=%(2000,4000,440,480)"/>
|
||||
<X-PRE-PROCESS cmd="set" data="cn-ring=%(1000,4000,450)"/>
|
||||
|
|
|
@ -1227,6 +1227,10 @@ PKG_CHECK_MODULES([MEMCACHED], [libmemcached >= 0.31],[
|
|||
AM_CONDITIONAL([HAVE_MEMCACHED],[false])
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([AMQP], [librabbitmq >= 0.5.2],[
|
||||
AM_CONDITIONAL([HAVE_AMQP],[true])],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_AMQP],[false])])
|
||||
|
||||
AC_ARG_ENABLE(core-libedit-support,
|
||||
[AS_HELP_STRING([--disable-core-libedit-support], [Compile without libedit Support])])
|
||||
|
||||
|
@ -1572,6 +1576,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/mod/endpoints/mod_unicall/Makefile
|
||||
src/mod/endpoints/mod_rtc/Makefile
|
||||
src/mod/endpoints/mod_verto/Makefile
|
||||
src/mod/event_handlers/mod_amqp/Makefile
|
||||
src/mod/event_handlers/mod_cdr_csv/Makefile
|
||||
src/mod/event_handlers/mod_cdr_mongodb/Makefile
|
||||
src/mod/event_handlers/mod_cdr_pg_csv/Makefile
|
||||
|
|
|
@ -30,6 +30,7 @@ avoid_mods=(
|
|||
endpoints/mod_opal
|
||||
endpoints/mod_reference
|
||||
endpoints/mod_unicall
|
||||
event_handlers/mod_amqp
|
||||
languages/mod_managed
|
||||
sdk/autotools
|
||||
xml_int/mod_xml_ldap
|
||||
|
@ -46,9 +47,11 @@ avoid_mods_jessie=(
|
|||
formats/mod_shout
|
||||
)
|
||||
avoid_mods_wheezy=(
|
||||
event_handlers/mod_amqp
|
||||
languages/mod_java
|
||||
)
|
||||
avoid_mods_squeeze=(
|
||||
event_handlers/mod_amqp
|
||||
formats/mod_vlc
|
||||
languages/mod_managed
|
||||
)
|
||||
|
|
|
@ -453,6 +453,11 @@ Build-Depends: libperl-dev
|
|||
|
||||
## mod/event_handlers
|
||||
|
||||
Module: event_handlers/mod_amqp
|
||||
Description: Event handler to send events to an amqp server
|
||||
AMQP event handler
|
||||
Build-Depends: librabbitmq-dev
|
||||
|
||||
Module: event_handlers/mod_cdr_csv
|
||||
Description: mod_cdr_csv
|
||||
Adds mod_cdr_csv.
|
||||
|
|
|
@ -274,26 +274,30 @@ get_sources () {
|
|||
while read type path distro components; do
|
||||
test "$type" = deb || continue
|
||||
printf "$type $path $tgt_distro $components\n"
|
||||
done < /etc/apt/sources.list
|
||||
done < "$2"
|
||||
}
|
||||
|
||||
get_mirrors () {
|
||||
get_sources "$1" | tr '\n' '|' | head -c-1; echo
|
||||
file=${2-/etc/apt/sources.list}
|
||||
announce "Using apt sources file: $file"
|
||||
get_sources "$1" "$file" | tr '\n' '|' | head -c-1; echo
|
||||
}
|
||||
|
||||
build_debs () {
|
||||
{
|
||||
set -e
|
||||
local OPTIND OPTARG debug_hook=false hookdir="" cow_build_opts=""
|
||||
local keep_pbuilder_config=false
|
||||
local keep_pbuilder_config=false keyring="" custom_keyring=""
|
||||
local use_system_sources=false
|
||||
while getopts 'Bbdkt' o "$@"; do
|
||||
while getopts 'BbdK:kT:t' o "$@"; do
|
||||
case "$o" in
|
||||
B) cow_build_opts="--debbuildopts '-B'";;
|
||||
b) cow_build_opts="--debbuildopts '-b'";;
|
||||
d) debug_hook=true;;
|
||||
k) keep_pbuilder_config=true;;
|
||||
t) use_system_sources=true;;
|
||||
K) custom_keyring="$OPTARG";;
|
||||
t) use_system_sources=true; custom_sources_file="/etc/apt/sources.list";;
|
||||
T) use_custom_sources=true; custom_sources_file="$OPTARG";;
|
||||
esac
|
||||
done
|
||||
shift $(($OPTIND-1))
|
||||
|
@ -309,6 +313,12 @@ build_debs () {
|
|||
[ -x "$(which cowbuilder)" ] \
|
||||
|| err "package cowbuilder isn't installed"
|
||||
local cow_img=/var/cache/pbuilder/base-$distro-$arch.cow
|
||||
if [ -e "$custom_keyring" ]; then
|
||||
keyring="$custom_keyring"
|
||||
else
|
||||
keyring="$(mktemp /tmp/keyringXXXXXXXX.asc)"
|
||||
apt-key exportall > "$keyring"
|
||||
fi
|
||||
cow () {
|
||||
if ! $use_system_sources; then
|
||||
cowbuilder "$@" \
|
||||
|
@ -316,17 +326,18 @@ build_debs () {
|
|||
--architecture $arch \
|
||||
--basepath $cow_img
|
||||
else
|
||||
local keyring="$(mktemp /tmp/keyringXXXXXXXX.asc)"
|
||||
apt-key exportall > "$keyring"
|
||||
cowbuilder "$@" \
|
||||
--distribution $distro \
|
||||
--architecture $arch \
|
||||
--basepath $cow_img \
|
||||
--keyring "$keyring" \
|
||||
--othermirror "$(get_mirrors $distro)"
|
||||
rm -f $keyring
|
||||
--othermirror "$(get_mirrors $distro $custom_sources_file)"
|
||||
fi
|
||||
}
|
||||
if [ ! -e "$custom_keyring" ]; then
|
||||
# Cleanup script created temporary file
|
||||
rm -f $keyring
|
||||
fi
|
||||
if ! [ -d $cow_img ]; then
|
||||
announce "Creating base $distro-$arch image..."
|
||||
local x=30
|
||||
|
@ -466,6 +477,9 @@ commands:
|
|||
-i Auto install build deps on host system
|
||||
-j Build debs in parallel
|
||||
-k Don't override pbuilder image configurations
|
||||
-K [/path/to/keyring.asc]
|
||||
Use custom keyring file for sources.list in build environment
|
||||
in the format of: apt-key exportall > /path/to/file.asc
|
||||
-l <modules>
|
||||
-m [ quicktest | non-dfsg ]
|
||||
Choose custom list of modules to build
|
||||
|
@ -477,6 +491,8 @@ commands:
|
|||
-s [ paranoid | reckless ]
|
||||
Set FS bootstrap/build -j flags
|
||||
-t Use system /etc/apt/sources.list in build environment
|
||||
-T [/path/to/sources.list]
|
||||
Use custom /etc/apt/sources.list in build environment
|
||||
-u <suite-postfix>
|
||||
Specify a custom suite postfix
|
||||
-v Set version
|
||||
|
@ -490,7 +506,12 @@ commands:
|
|||
-b Binary-only build
|
||||
-d Enable cowbuilder debug hook
|
||||
-k Don't override pbuilder image configurations
|
||||
-K [/path/to/keyring.asc]
|
||||
Use custom keyring file for sources.list in build environment
|
||||
in the format of: apt-key exportall > /path/to/file.asc
|
||||
-t Use system /etc/apt/sources.list in build environment
|
||||
-T [/path/to/sources.list]
|
||||
Use custom /etc/apt/sources.list in build environment
|
||||
|
||||
create-dbg-pkgs
|
||||
|
||||
|
|
|
@ -30,4 +30,4 @@ company receives priority support.
|
|||
|
||||
Encourage your company to sponsor ClueCon; in addition to helping out
|
||||
the project, you'll be exposed to a great pool of people to partner
|
||||
with, sell to, and recruit from.
|
||||
with, sell to, and recruit from. ( https://ClueCon.com )
|
||||
|
|
|
@ -69,10 +69,10 @@ License: MPL
|
|||
Group: Applications/Communications
|
||||
Packager: Ken Rice <krice@freeswitch.org>
|
||||
URL: http://www.freeswitch.org
|
||||
Source0:http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source0:http://files.freeswitch.org/releases/sounds/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/releases/sounds/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/releases/sounds/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/releases/sounds/%{name}-8000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: sox
|
||||
Requires: freeswitch
|
||||
|
|
|
@ -72,10 +72,10 @@ 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
|
||||
Source1:http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source0:http://files.freeswitch.org/releases/sounds/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/releases/sounds/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/releases/sounds/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/releases/sounds/%{name}-8000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: sox
|
||||
Requires: freeswitch
|
||||
|
|
|
@ -69,10 +69,10 @@ License: MPL
|
|||
Group: Applications/Communications
|
||||
Packager: Ken Rice <krice@freeswitch.org>
|
||||
URL: http://www.freeswitch.org
|
||||
Source0:http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source0:http://files.freeswitch.org/releases/sounds/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/releases/sounds/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/releases/sounds/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/releases/sounds/%{name}-8000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: sox
|
||||
Requires: freeswitch
|
||||
|
|
|
@ -41,10 +41,10 @@ License: MPL
|
|||
Group: Productivity/Telephony/Servers
|
||||
Packager: Joseph L. Casale <jcasale@activenetwerx.com>
|
||||
URL: http://www.freeswitch.org
|
||||
Source0: http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source1: http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source2: http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source3: http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz
|
||||
Source0: http://files.freeswitch.org/releases/sounds/%{name}-8000-%{version}.tar.gz
|
||||
Source1: http://files.freeswitch.org/releases/sounds/%{name}-16000-%{version}.tar.gz
|
||||
Source2: http://files.freeswitch.org/releases/sounds/%{name}-32000-%{version}.tar.gz
|
||||
Source3: http://files.freeswitch.org/releases/sounds/%{name}-48000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: bash
|
||||
Requires: freeswitch
|
||||
|
|
|
@ -69,10 +69,10 @@ License: MPL
|
|||
Group: Applications/Communications
|
||||
Packager: Ken Rice <krice@freeswitch.org>
|
||||
URL: http://www.freeswitch.org
|
||||
Source0:http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source0:http://files.freeswitch.org/releases/sounds/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/releases/sounds/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/releases/sounds/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/releases/sounds/%{name}-8000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: sox
|
||||
Requires: freeswitch
|
||||
|
|
|
@ -75,10 +75,10 @@ License: MPL
|
|||
Group: Applications/Communications
|
||||
Packager: Michal Bielicki <michal.bielicki@seventhsignal.de>
|
||||
URL: http://www.freeswitch.org
|
||||
Source0:http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source0:http://files.freeswitch.org/releases/sounds/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/releases/sounds/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/releases/sounds/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/releases/sounds/%{name}-8000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: sox
|
||||
Requires: freeswitch
|
||||
|
|
|
@ -67,10 +67,10 @@ License: MPL
|
|||
Group: Applications/Communications
|
||||
Packager: Ken Rice <krice@freeswitch.org>
|
||||
URL: http://www.freeswitch.org
|
||||
Source0:http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source0:http://files.freeswitch.org/releases/sounds/%{name}-48000-%{version}.tar.gz
|
||||
Source1:http://files.freeswitch.org/releases/sounds/%{name}-32000-%{version}.tar.gz
|
||||
Source2:http://files.freeswitch.org/releases/sounds/%{name}-16000-%{version}.tar.gz
|
||||
Source3:http://files.freeswitch.org/releases/sounds/%{name}-8000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: sox
|
||||
Requires: freeswitch
|
||||
|
|
|
@ -1352,6 +1352,7 @@ cp %{SOURCE9} libs/
|
|||
cp %{SOURCE10} libs/
|
||||
cp %{SOURCE11} libs/
|
||||
cp %{SOURCE12} libs/
|
||||
cp %{SOURCE13} libs/
|
||||
|
||||
######################################################################################################################
|
||||
#
|
||||
|
@ -1804,6 +1805,7 @@ fi
|
|||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/abstraction.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/acl.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/alsa.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/amqp.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/blacklist.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/callcenter.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/cdr_csv.conf.xml
|
||||
|
|
|
@ -6,16 +6,16 @@ function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\
|
|||
function setDefaultCodec(mLine,payload){var elements=mLine.split(' ');var newLine=[];var index=0;for(var i=0;i<elements.length;i++){if(index===3){newLine[index++]=payload;}
|
||||
if(elements[i]!==payload)newLine[index++]=elements[i];}
|
||||
return newLine.join(' ');}
|
||||
$.FSRTC=function(options){this.options=$.extend({useVideo:null,useStereo:false,userData:null,iceServers:false,videoParams:{},audioParams:{},callbacks:{onICEComplete:function(){},onICE:function(){},onOfferSDP:function(){}}},options);this.mediaData={SDP:null,profile:{},candidateList:[]};if(moz){this.constraints={offerToReceiveAudio:true,offerToReceiveVideo:this.options.useVideo?true:false,};}else{this.constraints={optional:[{'DtlsSrtpKeyAgreement':'true'}],mandatory:{OfferToReceiveAudio:true,OfferToReceiveVideo:this.options.useVideo?true:false,}};}
|
||||
$.FSRTC=function(options){this.options=$.extend({useVideo:null,useStereo:false,userData:null,localVideo:null,screenShare:false,useCamera:"any",iceServers:false,videoParams:{},audioParams:{},callbacks:{onICEComplete:function(){},onICE:function(){},onOfferSDP:function(){}},},options);this.enabled=true;this.mediaData={SDP:null,profile:{},candidateList:[]};if(moz){this.constraints={offerToReceiveAudio:true,offerToReceiveVideo:this.options.useVideo?true:false,};}else{this.constraints={optional:[{'DtlsSrtpKeyAgreement':'true'}],mandatory:{OfferToReceiveAudio:true,OfferToReceiveVideo:this.options.useVideo?true:false,}};}
|
||||
if(self.options.useVideo){self.options.useVideo.style.display='none';}
|
||||
setCompat();checkCompat();};$.FSRTC.prototype.useVideo=function(obj){var self=this;if(obj){self.options.useVideo=obj;if(moz){self.constraints.offerToReceiveVideo=true;}else{self.constraints.mandatory.OfferToReceiveVideo=true;}}else{self.options.useVideo=null;if(moz){self.constraints.offerToReceiveVideo=false;}else{self.constraints.mandatory.OfferToReceiveVideo=false;}}
|
||||
setCompat();checkCompat();};$.FSRTC.prototype.useVideo=function(obj,local){var self=this;if(obj){self.options.useVideo=obj;self.options.localVideo=local;if(moz){self.constraints.offerToReceiveVideo=true;}else{self.constraints.mandatory.OfferToReceiveVideo=true;}}else{self.options.useVideo=null;self.options.localVideo=null;if(moz){self.constraints.offerToReceiveVideo=false;}else{self.constraints.mandatory.OfferToReceiveVideo=false;}}
|
||||
if(self.options.useVideo){self.options.useVideo.style.display='none';}};$.FSRTC.prototype.useStereo=function(on){var self=this;self.options.useStereo=on;};$.FSRTC.prototype.stereoHack=function(sdp){var self=this;if(!self.options.useStereo){return sdp;}
|
||||
var sdpLines=sdp.split('\r\n');var opusIndex=findLine(sdpLines,'a=rtpmap','opus/48000'),opusPayload;if(opusIndex){opusPayload=getCodecPayloadType(sdpLines[opusIndex]);}
|
||||
var fmtpLineIndex=findLine(sdpLines,'a=fmtp:'+opusPayload.toString());if(fmtpLineIndex===null)return sdp;sdpLines[fmtpLineIndex]=sdpLines[fmtpLineIndex].concat('; stereo=1');sdp=sdpLines.join('\r\n');return sdp;};function setCompat(){$.FSRTC.moz=!!navigator.mozGetUserMedia;if(!navigator.getUserMedia){navigator.getUserMedia=navigator.mozGetUserMedia||navigator.webkitGetUserMedia||navigator.msGetUserMedia;}}
|
||||
function checkCompat(){if(!navigator.getUserMedia){alert('This application cannot function in this browser.');return false;}
|
||||
return true;}
|
||||
function onStreamError(self,e){console.log('There has been a problem retrieving the streams - did you allow access?',e);}
|
||||
function onStreamSuccess(self){console.log("Stream Success");}
|
||||
function onStreamError(self,e){console.log('There has been a problem retrieving the streams - did you allow access? Check Device Resolution',e);doCallback(self,"onError",e);}
|
||||
function onStreamSuccess(self,stream){console.log("Stream Success");doCallback(self,"onStream",stream);}
|
||||
function onICE(self,candidate){self.mediaData.candidate=candidate;self.mediaData.candidateList.push(self.mediaData.candidate);doCallback(self,"onICE");}
|
||||
function doCallback(self,func,arg){if(func in self.options.callbacks){self.options.callbacks[func](self,arg);}}
|
||||
function onICEComplete(self,candidate){console.log("ICE Complete");doCallback(self,"onICEComplete");}
|
||||
|
@ -27,15 +27,26 @@ function onRemoteStream(self,stream){if(self.options.useVideo){self.options.useV
|
|||
var element=self.options.useAudio;console.log("REMOTE STREAM",stream,element);if(typeof element.srcObject!=='undefined'){element.srcObject=stream;}else if(typeof element.mozSrcObject!=='undefined'){element.mozSrcObject=stream;}else if(typeof element.src!=='undefined'){element.src=URL.createObjectURL(stream);}else{console.error('Error attaching stream to element.');}
|
||||
self.options.useAudio.play();self.remoteStream=stream;}
|
||||
function onOfferSDP(self,sdp){self.mediaData.SDP=self.stereoHack(sdp.sdp);console.log("Offer SDP");doCallback(self,"onOfferSDP");}
|
||||
$.FSRTC.prototype.answer=function(sdp,onSuccess,onError){this.peer.addAnswerSDP({type:"answer",sdp:sdp},onSuccess,onError);};$.FSRTC.prototype.stop=function(){var self=this;if(self.options.useVideo){self.options.useVideo.style.display='none';}
|
||||
$.FSRTC.prototype.answer=function(sdp,onSuccess,onError){this.peer.addAnswerSDP({type:"answer",sdp:sdp},onSuccess,onError);};$.FSRTC.prototype.stop=function(){var self=this;if(self.options.useVideo){self.options.useVideo.style.display='none';self.options.useVideo[moz?'mozSrcObject':'src']="";}
|
||||
if(self.localStream){self.localStream.stop();self.localStream=null;}
|
||||
if(self.peer){console.log("stopping peer");self.peer.stop();}};$.FSRTC.prototype.createAnswer=function(sdp){var self=this;self.type="answer";self.remoteSDP=sdp;console.debug("inbound sdp: ",sdp);function onSuccess(stream){self.localStream=stream;self.peer=RTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:function(stream){return onRemoteStream(self,stream);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,offerSDP:{type:"offer",sdp:self.remoteSDP}});onStreamSuccess(self);}
|
||||
if(self.options.localVideo){self.options.localVideo.style.display='none';self.options.localVideo[moz?'mozSrcObject':'src']="";}
|
||||
if(self.options.localVideoStream){self.options.localVideoStream.stop();}
|
||||
if(self.peer){console.log("stopping peer");self.peer.stop();}};$.FSRTC.prototype.getMute=function(){var self=this;return self.enabled;}
|
||||
$.FSRTC.prototype.setMute=function(what){var self=this;var audioTracks=self.localStream.getAudioTracks();for(var i=0,len=audioTracks.length;i<len;i++){switch(what){case"on":audioTracks[i].enabled=true;break;case"off":audioTracks[i].enabled=false;break;case"toggle":audioTracks[i].enabled=!audioTracks[i].enabled;default:break;}
|
||||
self.enabled=audioTracks[i].enabled;}
|
||||
return!self.enabled;}
|
||||
$.FSRTC.prototype.createAnswer=function(params){var self=this;self.type="answer";self.remoteSDP=params.sdp;console.debug("inbound sdp: ",params.sdp);self.options.useCamera=params.useCamera||"any";self.options.useMic=params.useMic||"any";function onSuccess(stream){self.localStream=stream;self.peer=RTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:function(stream){return onRemoteStream(self,stream);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,offerSDP:{type:"offer",sdp:self.remoteSDP}});onStreamSuccess(self);}
|
||||
function onError(e){onStreamError(self,e);}
|
||||
var audio;if(this.options.videoParams&&this.options.videoParams.chromeMediaSource=='screen'){this.options.videoParams={chromeMediaSource:'screen',maxWidth:screen.width,maxHeight:screen.height};console.error("SCREEN SHARE");audio=false;}else{audio={mandatory:this.options.audioParams,optional:[]};}
|
||||
console.log("Mandatory audio constraints",this.options.audioParams);console.log("Mandatory video constraints",this.options.videoParams);getUserMedia({constraints:{audio:audio,video:this.options.useVideo?{mandatory:this.options.videoParams,optional:[]}:null},video:this.options.useVideo?true:false,onsuccess:onSuccess,onerror:onError});};$.FSRTC.prototype.call=function(profile){checkCompat();var self=this;self.type="offer";function onSuccess(stream){self.localStream=stream;self.peer=RTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:function(stream){return onRemoteStream(self,stream);},onOfferSDP:function(sdp){return onOfferSDP(self,sdp);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,});onStreamSuccess(self);}
|
||||
var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);if(self.options.useVideo&&self.options.localVideo){getUserMedia({constraints:{audio:false,video:{mandatory:self.options.videoParams,optional:[]},},localVideo:self.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});}
|
||||
getUserMedia({constraints:{audio:mediaParams.audio,video:mediaParams.video},video:mediaParams.useVideo,onsuccess:onSuccess,onerror:onError});};function getMediaParams(obj){var audio;if(obj.options.videoParams&&obj.options.screenShare){console.error("SCREEN SHARE");audio=false;}else{audio={mandatory:obj.options.audioParams,optional:[]};if(obj.options.useMic!=="any"){audio.optional=[{sourceId:obj.options.useMic}]}}
|
||||
if(obj.options.useVideo&&obj.options.localVideo){getUserMedia({constraints:{audio:false,video:{mandatory:obj.options.videoParams,optional:[]},},localVideo:obj.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});}
|
||||
var video={mandatory:obj.options.videoParams,optional:[]}
|
||||
var useVideo=obj.options.useVideo;if(useVideo&&obj.options.useCamera&&obj.options.useCamera!=="none"){if(obj.options.useCamera!=="any"){video.optional=[{sourceId:obj.options.useCamera}]}}else{video=null;useVideo=null;}
|
||||
return{audio:audio,video:video,useVideo:useVideo};}
|
||||
$.FSRTC.prototype.call=function(profile){checkCompat();var self=this;var screen=false;self.type="offer";if(self.options.videoParams&&self.options.screenShare){screen=true;}
|
||||
function onSuccess(stream){self.localStream=stream;self.peer=RTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:screen?function(stream){console.error("SKIP");}:function(stream){return onRemoteStream(self,stream);},onOfferSDP:function(sdp){return onOfferSDP(self,sdp);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,});onStreamSuccess(self,stream);}
|
||||
function onError(e){onStreamError(self,e);}
|
||||
var audio;if(this.options.videoParams&&this.options.videoParams.chromeMediaSource=='screen'){this.options.videoParams={chromeMediaSource:'screen',maxWidth:screen.width,maxHeight:screen.height};console.error("SCREEN SHARE");audio=false;}else{audio={mandatory:this.options.audioParams,optional:[]};}
|
||||
console.log("Mandatory audio constraints",this.options.audioParams);console.log("Mandatory video constraints",this.options.videoParams);getUserMedia({constraints:{audio:audio,video:this.options.useVideo?{mandatory:this.options.videoParams,optional:[]}:null},video:this.options.useVideo?true:false,onsuccess:onSuccess,onerror:onError});};window.moz=!!navigator.mozGetUserMedia;function RTCPeerConnection(options){var w=window,PeerConnection=w.mozRTCPeerConnection||w.webkitRTCPeerConnection,SessionDescription=w.mozRTCSessionDescription||w.RTCSessionDescription,IceCandidate=w.mozRTCIceCandidate||w.RTCIceCandidate;var STUN={url:!moz?'stun:stun.l.google.com:19302':'stun:23.21.150.121'};var TURN={url:'turn:homeo@turn.bistri.com:80',credential:'homeo'};var iceServers=null;if(options.iceServers){var tmp=options.iceServers;if(typeof(tmp)==="boolean"){tmp=null;}
|
||||
var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);getUserMedia({constraints:{audio:mediaParams.audio,video:mediaParams.video},video:mediaParams.useVideo,onsuccess:onSuccess,onerror:onError});};window.moz=!!navigator.mozGetUserMedia;function RTCPeerConnection(options){var w=window,PeerConnection=w.mozRTCPeerConnection||w.webkitRTCPeerConnection,SessionDescription=w.mozRTCSessionDescription||w.RTCSessionDescription,IceCandidate=w.mozRTCIceCandidate||w.RTCIceCandidate;var STUN={url:!moz?'stun:stun.l.google.com:19302':'stun:23.21.150.121'};var TURN={url:'turn:homeo@turn.bistri.com:80',credential:'homeo'};var iceServers=null;if(options.iceServers){var tmp=options.iceServers;if(typeof(tmp)==="boolean"){tmp=null;}
|
||||
if(tmp&&!(typeof(tmp)=="object"&&tmp.constructor===Array)){console.warn("iceServers must be an array, reverting to default ice servers");tmp=null;}
|
||||
iceServers={iceServers:tmp||[STUN]};if(!moz&&!tmp){if(parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2])>=28)TURN={url:'turn:turn.bistri.com:80',credential:'homeo',username:'homeo'};iceServers.iceServers=[STUN];}}
|
||||
var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];}
|
||||
|
@ -57,7 +68,7 @@ function onSdpSuccess(){}
|
|||
function onSdpError(e){if(options.onChannelError){options.onChannelError(e);}
|
||||
console.error('sdp error:',e);}
|
||||
return{addAnswerSDP:function(sdp,cbSuccess,cbError){peer.setRemoteDescription(new SessionDescription(sdp),cbSuccess?cbSuccess:onSdpSuccess,cbError?cbError:onSdpError);},addICE:function(candidate){peer.addIceCandidate(new IceCandidate({sdpMLineIndex:candidate.sdpMLineIndex,candidate:candidate.candidate}));},peer:peer,channel:channel,sendData:function(message){if(channel){channel.send(message);}},stop:function(){peer.close();if(options.attachStream){options.attachStream.stop();}}};}
|
||||
var video_constraints={mandatory:{},optional:[]};function getUserMedia(options){var n=navigator,media;n.getMedia=n.webkitGetUserMedia||n.mozGetUserMedia;n.getMedia(options.constraints||{audio:true,video:video_constraints},streaming,options.onerror||function(e){console.error(e);});function streaming(stream){var video=options.video;if(video){video[moz?'mozSrcObject':'src']=moz?stream:window.webkitURL.createObjectURL(stream);}
|
||||
var video_constraints={mandatory:{},optional:[]};function getUserMedia(options){var n=navigator,media;n.getMedia=n.webkitGetUserMedia||n.mozGetUserMedia;n.getMedia(options.constraints||{audio:true,video:video_constraints},streaming,options.onerror||function(e){console.error(e);});function streaming(stream){if(options.localVideo){options.localVideo[moz?'mozSrcObject':'src']=moz?stream:window.webkitURL.createObjectURL(stream);options.localVideo.style.display='block';}
|
||||
if(options.onsuccess){options.onsuccess(stream);}
|
||||
media=stream;}
|
||||
return media;}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};}
|
||||
|
@ -92,8 +103,8 @@ if(typeof all_done_cb==='function')all_done_cb(result);return;}
|
|||
for(i=0;i<this._requests.length;i++){call=this._requests[i];batch_request.push(call.request);if('id'in call.request){handlers[call.request.id]={success_cb:call.success_cb,error_cb:call.error_cb};}}
|
||||
success_cb=function(data){self._batchCb(data,handlers,self.all_done_cb);};if(self.jsonrpcclient.options.ajaxUrl===null){throw"$.JsonRpcClient.batch used with no websocket and no http endpoint.";}
|
||||
$.ajax({url:self.jsonrpcclient.options.ajaxUrl,data:$.toJSON(batch_request),dataType:'json',cache:false,type:'POST',error:function(jqXHR,textStatus,errorThrown){self.error_cb(jqXHR,textStatus,errorThrown);},success:success_cb});};$.JsonRpcClient._batchObject.prototype._batchCb=function(result,handlers,all_done_cb){for(var i=0;i<result.length;i++){var response=result[i];if('error'in response){if(response.id===null||!(response.id in handlers)){if('console'in window)console.log(response);}else{handlers[response.id].error_cb(response.error,this);}}else{if(!(response.id in handlers)&&'console'in window){console.log(response);}else{handlers[response.id].success_cb(response.result,this);}}}
|
||||
if(typeof all_done_cb==='function')all_done_cb(result);};})(jQuery);(function($){var generateGUID=(typeof(window.crypto)!=='undefined'&&typeof(window.crypto.getRandomValues)!=='undefined')?function(){var buf=new Uint16Array(8);window.crypto.getRandomValues(buf);var S4=function(num){var ret=num.toString(16);while(ret.length<4){ret="0"+ret;}
|
||||
return ret;};return(S4(buf[0])+S4(buf[1])+"-"+S4(buf[2])+"-"+S4(buf[3])+"-"+S4(buf[4])+"-"+S4(buf[5])+S4(buf[6])+S4(buf[7]));}:function(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c){var r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);return v.toString(16);});};$.verto=function(options,callbacks){var verto=this;$.verto.saved.push(verto);verto.options=$.extend({login:null,passwd:null,socketUrl:null,tag:null,videoParams:{},audioParams:{},loginParams:{},iceServers:false,ringSleep:6000},options);verto.sessid=$.cookie('verto_session_uuid')||generateGUID();$.cookie('verto_session_uuid',verto.sessid,{expires:1});verto.dialogs={};verto.callbacks=callbacks||{};verto.eventSUBS={};verto.rpcClient=new $.JsonRpcClient({login:verto.options.login,passwd:verto.options.passwd,socketUrl:verto.options.socketUrl,loginParams:verto.options.loginParams,sessid:verto.sessid,onmessage:function(e){return verto.handleMessage(e.eventData);},onWSConnect:function(o){o.call('login',{});},onWSLogin:function(success){if(verto.callbacks.onWSLogin){verto.callbacks.onWSLogin(verto,success);}},onWSClose:function(success){if(verto.callbacks.onWSClose){verto.callbacks.onWSClose(verto,success);}
|
||||
if(typeof all_done_cb==='function')all_done_cb(result);};})(jQuery);(function($){var sources=[];var generateGUID=(typeof(window.crypto)!=='undefined'&&typeof(window.crypto.getRandomValues)!=='undefined')?function(){var buf=new Uint16Array(8);window.crypto.getRandomValues(buf);var S4=function(num){var ret=num.toString(16);while(ret.length<4){ret="0"+ret;}
|
||||
return ret;};return(S4(buf[0])+S4(buf[1])+"-"+S4(buf[2])+"-"+S4(buf[3])+"-"+S4(buf[4])+"-"+S4(buf[5])+S4(buf[6])+S4(buf[7]));}:function(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c){var r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);return v.toString(16);});};$.verto=function(options,callbacks){var verto=this;$.verto.saved.push(verto);verto.options=$.extend({login:null,passwd:null,socketUrl:null,tag:null,localTag:null,videoParams:{},audioParams:{},loginParams:{},iceServers:false,ringSleep:6000},options);verto.sessid=$.cookie('verto_session_uuid')||generateGUID();$.cookie('verto_session_uuid',verto.sessid,{expires:1});verto.dialogs={};verto.callbacks=callbacks||{};verto.eventSUBS={};verto.rpcClient=new $.JsonRpcClient({login:verto.options.login,passwd:verto.options.passwd,socketUrl:verto.options.socketUrl,loginParams:verto.options.loginParams,sessid:verto.sessid,onmessage:function(e){return verto.handleMessage(e.eventData);},onWSConnect:function(o){o.call('login',{});},onWSLogin:function(success){if(verto.callbacks.onWSLogin){verto.callbacks.onWSLogin(verto,success);}},onWSClose:function(success){if(verto.callbacks.onWSClose){verto.callbacks.onWSClose(verto,success);}
|
||||
verto.purge();}});if(verto.options.ringFile&&verto.options.tag){verto.ringer=$("#"+verto.options.tag);}
|
||||
verto.rpcClient.call('login',{});};$.verto.prototype.videoParams=function(on){var verto=this;verto.options.videoParams=on;};$.verto.prototype.iceServers=function(on){var verto=this;verto.options.iceServers=on;};$.verto.prototype.loginData=function(params){verto.options.login=params.login;verto.options.passwd=params.passwd;verto.rpcClient.loginData(params);};$.verto.prototype.logout=function(msg){var verto=this;verto.rpcClient.closeSocket();if(verto.callbacks.onWSClose){verto.callbacks.onWSClose(verto,false);}
|
||||
verto.purge();};$.verto.prototype.login=function(msg){var verto=this;verto.logout();verto.rpcClient.call('login',{});};$.verto.prototype.message=function(msg){var verto=this;var err=0;if(!msg.to){console.error("Missing To");err++;}
|
||||
|
@ -119,7 +130,8 @@ x++;verto.dialogs[i].setState($.verto.enum.state.purge);}
|
|||
for(i in verto.eventSUBS){if(verto.eventSUBS[i]){console.log("purging subscription: "+i);delete verto.eventSUBS[i];}}};$.verto.prototype.hangup=function(callID){var verto=this;if(callID){var dialog=verto.dialogs[callID];if(dialog){dialog.hangup();}}else{for(var i in verto.dialogs){verto.dialogs[i].hangup();}}};$.verto.prototype.newCall=function(args,callbacks){var verto=this;if(!verto.rpcClient.socketReady()){console.error("Not Connected...");return;}
|
||||
var dialog=new $.verto.dialog($.verto.enum.direction.outbound,this,args);dialog.invite();if(callbacks){dialog.callbacks=callbacks;}
|
||||
return dialog;};$.verto.prototype.handleMessage=function(data){var verto=this;if(!(data&&data.method)){console.error("Invalid Data",data);return;}
|
||||
if(data.params.callID){var dialog=verto.dialogs[data.params.callID];if(dialog){switch(data.method){case'verto.bye':dialog.hangup(data.params);break;case'verto.answer':dialog.handleAnswer(data.params);break;case'verto.media':dialog.handleMedia(data.params);break;case'verto.display':dialog.handleDisplay(data.params);break;case'verto.info':dialog.handleInfo(data.params);break;default:console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED",dialog,data.method);break;}}else{switch(data.method){case'verto.attach':data.params.attach=true;if(data.params.sdp&&data.params.sdp.indexOf("m=video")>0){data.params.useVideo=true;}
|
||||
if(data.params.callID){var dialog=verto.dialogs[data.params.callID];if(data.method==="verto.attach"&&dialog){delete dialog.verto.dialogs[dialog.callID];dialog.rtc.stop();dialog=null;}
|
||||
if(dialog){switch(data.method){case'verto.bye':dialog.hangup(data.params);break;case'verto.answer':dialog.handleAnswer(data.params);break;case'verto.media':dialog.handleMedia(data.params);break;case'verto.display':dialog.handleDisplay(data.params);break;case'verto.info':dialog.handleInfo(data.params);break;default:console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED",dialog,data.method);break;}}else{switch(data.method){case'verto.attach':data.params.attach=true;if(data.params.sdp&&data.params.sdp.indexOf("m=video")>0){data.params.useVideo=true;}
|
||||
if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;}
|
||||
dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);dialog.setState($.verto.enum.state.recovering);break;case'verto.invite':if(data.params.sdp&&data.params.sdp.indexOf("m=video")>0){data.params.wantVideo=true;}
|
||||
if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;}
|
||||
|
@ -163,23 +175,32 @@ dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;ca
|
|||
if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);}
|
||||
dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;}
|
||||
dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;}
|
||||
if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.confMan=function(verto,params){var confMan=this;confMan.params=$.extend({tableID:null,statusID:null,mainModID:null,dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);confMan.verto=verto;confMan.serno=CONFMAN_SERNO++;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="<div id='"+div_id+"'><br>"+"<button class='ctlbtn' id='"+play_id+"'>Play</button>"+"<button class='ctlbtn' id='"+stop_id+"'>Stop</button>"+"<button class='ctlbtn' id='"+recording_id+"'>Record</button>"+"<button class='ctlbtn' id='"+rec_stop_id+"'>Record Stop</button>"+"<br><br></div>";jq.html(html);$("#"+play_id).click(function(){var file=prompt("Please enter file name","");confMan.modCommand("play",null,file);});$("#"+stop_id).click(function(){confMan.modCommand("stop",null,"all");});$("#"+recording_id).click(function(){var file=prompt("Please enter file name","");confMan.modCommand("recording",null,["start",file]);});$("#"+rec_stop_id).click(function(){confMan.modCommand("recording",null,["stop","all"]);});}
|
||||
function genControls(jq,rowid){var x=parseInt(rowid);var kick_id="kick_"+x;var tmute_id="tmute_"+x;var box_id="box_"+x;var volup_id="volume_in_up"+x;var voldn_id="volume_in_dn"+x;var transfer_id="transfer"+x;var html="<div id='"+box_id+"'>"+"<button class='ctlbtn' id='"+kick_id+"'>Kick</button>"+"<button class='ctlbtn' id='"+tmute_id+"'>Mute</button>"+"<button class='ctlbtn' id='"+voldn_id+"'>Vol -</button>"+"<button class='ctlbtn' id='"+volup_id+"'>Vol +</button>"+"<button class='ctlbtn' id='"+transfer_id+"'>Transfer</button>"+"</div>";jq.html(html);if(!jq.data("mouse")){$("#"+box_id).hide();}
|
||||
jq.mouseover(function(e){jq.data({"mouse":true});$("#"+box_id).show();});jq.mouseout(function(e){jq.data({"mouse":false});$("#"+box_id).hide();});$("#"+transfer_id).click(function(){var xten=prompt("Enter Extension");confMan.modCommand("transfer",x,xten);});$("#"+kick_id).click(function(){confMan.modCommand("kick",x);});$("#"+tmute_id).click(function(){confMan.modCommand("tmute",x);});$("#"+volup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_in",x,"down");});return html;}
|
||||
var atitle="";var awidth=0;if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=200;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready<br><br>");}else{$(confMan.params.mainModID).html("");}
|
||||
if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.confMan=function(verto,params){var confMan=this;confMan.params=$.extend({tableID:null,statusID:null,mainModID:null,dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);confMan.verto=verto;confMan.serno=CONFMAN_SERNO++;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var snapshot_id="snapshot_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="<div id='"+div_id+"'><br>"+"<button class='ctlbtn' id='"+play_id+"'>Play</button>"+"<button class='ctlbtn' id='"+stop_id+"'>Stop</button>"+"<button class='ctlbtn' id='"+recording_id+"'>Record</button>"+"<button class='ctlbtn' id='"+rec_stop_id+"'>Record Stop</button>"+
|
||||
(confMan.params.hasVid?"<button class='ctlbtn' id='"+snapshot_id+"'>PNG Snapshot</button>":"")+"<br><br></div>";jq.html(html);if(confMan.params.hasVid){var vlayout_id="confman_vid_layout_"+confMan.serno;var vlselect_id="confman_vl_select_"+confMan.serno;var vlhtml="<div id='"+vlayout_id+"'><br>"+"<b>Video Layout</b> <select id='"+vlselect_id+"'></select> "+"<br><br></div>";jq.append(vlhtml);$("#"+vlselect_id).change(function(){var val=$("#"+vlselect_id).find(":selected").val();if(val!=="none"){confMan.modCommand("vid-layout",null,val);}});$("#"+snapshot_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("vid-write-png",null,file);}});}
|
||||
$("#"+play_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("play",null,file);}});$("#"+stop_id).click(function(){confMan.modCommand("stop",null,"all");});$("#"+recording_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("recording",null,["start",file]);}});$("#"+rec_stop_id).click(function(){confMan.modCommand("recording",null,["stop","all"]);});}
|
||||
function genControls(jq,rowid){var x=parseInt(rowid);var kick_id="kick_"+x;var tmute_id="tmute_"+x;var tvmute_id="tvmute_"+x;var vbanner_id="vbanner_"+x;var tvpresenter_id="tvpresenter_"+x;var tvfloor_id="tvfloor_"+x;var box_id="box_"+x;var volup_id="volume_in_up"+x;var voldn_id="volume_in_dn"+x;var transfer_id="transfer"+x;var html="<div id='"+box_id+"'>"+"<button class='ctlbtn' id='"+kick_id+"'>Kick</button>"+"<button class='ctlbtn' id='"+tmute_id+"'>Mute</button>"+
|
||||
(confMan.params.hasVid?"<button class='ctlbtn' id='"+tvmute_id+"'>VMute</button>":"")+
|
||||
(confMan.params.hasVid?"<button class='ctlbtn' id='"+tvpresenter_id+"'>Presenter</button>":"")+
|
||||
(confMan.params.hasVid?"<button class='ctlbtn' id='"+tvfloor_id+"'>Vid Floor</button>":"")+
|
||||
(confMan.params.hasVid?"<button class='ctlbtn' id='"+vbanner_id+"'>Banner</button>":"")+"<button class='ctlbtn' id='"+voldn_id+"'>Vol -</button>"+"<button class='ctlbtn' id='"+volup_id+"'>Vol +</button>"+"<button class='ctlbtn' id='"+transfer_id+"'>Transfer</button>"+"</div>";jq.html(html);if(!jq.data("mouse")){$("#"+box_id).hide();}
|
||||
jq.mouseover(function(e){jq.data({"mouse":true});$("#"+box_id).show();});jq.mouseout(function(e){jq.data({"mouse":false});$("#"+box_id).hide();});$("#"+transfer_id).click(function(){var xten=prompt("Enter Extension");if(xten){confMan.modCommand("transfer",x,xten);}});$("#"+kick_id).click(function(){confMan.modCommand("kick",x);});$("#"+tmute_id).click(function(){confMan.modCommand("tmute",x);});if(confMan.params.hasVid){$("#"+tvmute_id).click(function(){confMan.modCommand("tvmute",x);});$("#"+tvpresenter_id).click(function(){confMan.modCommand("vid-res-id",x,"presenter");});$("#"+tvfloor_id).click(function(){confMan.modCommand("vid-floor",x,"force");});$("#"+vbanner_id).click(function(){var text=prompt("Please enter text","");if(text){confMan.modCommand("vid-banner",x,escape(text));}});}
|
||||
$("#"+volup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_in",x,"down");});return html;}
|
||||
var atitle="";var awidth=0;if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=300;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready<br><br>");}else{$(confMan.params.mainModID).html("");}
|
||||
verto.subscribe(confMan.params.laData.modChannel,{handler:function(v,e){console.error("MODDATA:",e.data);if(confMan.params.onBroadcast){confMan.params.onBroadcast(verto,confMan,e.data);}
|
||||
if(!confMan.destroyed&&confMan.params.displayID){$(confMan.params.displayID).html(e.data.response+"<br><br>");if(confMan.lastTimeout){clearTimeout(confMan.lastTimeout);confMan.lastTimeout=0;}
|
||||
confMan.lastTimeout=setTimeout(function(){$(confMan.params.displayID).html(confMan.destroyed?"":"Moderator Controls Ready<br><br>");},4000);}}});}
|
||||
if(e.data["conf-command"]==="list-videoLayouts"){var vlselect_id="#confman_vl_select_"+confMan.serno;var vlayout_id="#confman_vid_layout_"+confMan.serno;var x=0;var options;$(vlselect_id).append(new Option("Choose a Layout","none"));if(e.data.responseData){options=e.data.responseData.sort();for(var i in options){$(vlselect_id).append(new Option(options[i],options[i]));x++;}}
|
||||
if(x){$(vlselect_id).selectmenu('refresh',true);}else{$(vlayout_id).hide();}}else{if(!confMan.destroyed&&confMan.params.displayID){$(confMan.params.displayID).html(e.data.response+"<br><br>");if(confMan.lastTimeout){clearTimeout(confMan.lastTimeout);confMan.lastTimeout=0;}
|
||||
confMan.lastTimeout=setTimeout(function(){$(confMan.params.displayID).html(confMan.destroyed?"":"Moderator Controls Ready<br><br>");},4000);}}}});if(confMan.params.hasVid){confMan.modCommand("list-videoLayouts",null,null);}}
|
||||
var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback=function(nRow,aData,iDisplayIndex,iDisplayIndexFull){if(!aData[5]){var $row=$('td:eq(5)',nRow);genControls($row,aData);if(confMan.params.onLaRow){confMan.params.onLaRow(verto,confMan,$row,aData);}}};}
|
||||
confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID"},{"sTitle":"Number"},{"sTitle":"Name"},{"sTitle":"Codec"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"300px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1000,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});};$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.sendMethod("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();}
|
||||
confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID"},{"sTitle":"Number"},{"sTitle":"Name"},{"sTitle":"Codec"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"200px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1000,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});};$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();}
|
||||
if(confMan.params.laData.modChannel){confMan.verto.unsubscribe(confMan.params.laData.modChannel);}
|
||||
if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,tag:verto.options.tag,login:verto.options.login},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();}
|
||||
if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:"any",useMic:"any",tag:verto.options.tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=params.useCamera;dialog.useMic=params.useMic;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();}
|
||||
if(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}}
|
||||
if(dialog.params.localTag){dialog.localVideo=document.getElementById(dialog.params.localTag);}
|
||||
dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.params.display_direction==="outbound"){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_id_number;}else{dialog.params.remote_caller_id_name=dialog.params.callee_id_name;dialog.params.remote_caller_id_number=dialog.params.callee_id_number;}
|
||||
if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="Nobody";}
|
||||
if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number="UNKNOWN";}
|
||||
RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;}
|
||||
RTCcallbacks.onICESDP=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.SDP);dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup();};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,useVideo:dialog.videoStream,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:verto.options.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;}
|
||||
RTCcallbacks.onICESDP=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.SDP);dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){console.log("stream started");};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.localVideo,useVideo:dialog.videoStream,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;}
|
||||
obj.dialogParams[i]=dialog.params[i];}
|
||||
dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;}
|
||||
return false;}
|
||||
|
@ -189,22 +210,25 @@ console.info("Dialog "+dialog.callID+": state change from "+dialog.state.name+"
|
|||
if(!dialog.cause){dialog.cause="NORMAL CLEARING";}
|
||||
if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);}
|
||||
switch(dialog.state){case $.verto.enum.state.trying:setTimeout(function(){if(dialog.state==$.verto.enum.state.trying){dialog.setState($.verto.enum.state.hangup);}},30000);break;case $.verto.enum.state.purge:dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.hangup:if(dialog.lastState.val>$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});}
|
||||
dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];dialog.rtc.stop();break;}
|
||||
dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];if(!dialog.params.screenShare){dialog.rtc.stop();}
|
||||
break;}
|
||||
return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();}
|
||||
break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);}
|
||||
break;case"verto.bye":dialog.hangup();break;case"verto.modify":if(e.holdState){if(e.holdState=="held"){if(dialog.state!=$.verto.enum.state.held){dialog.setState($.verto.enum.state.held);}}else if(e.holdState=="active"){if(dialog.state!=$.verto.enum.state.active){dialog.setState($.verto.enum.state.active);}}}
|
||||
if(success){}
|
||||
break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;}
|
||||
if(params.cause){dialog.cause=params.cause;}}
|
||||
if(dialog.state.val>$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;}
|
||||
dialog.rtc.useVideo(dialog.videoStream);};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
|
||||
if(dialog.state.val>=$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;}
|
||||
dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(what){var dialog=this;return dialog.rtc.getMute(what);};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
|
||||
if(!msg.body){console.error("Missing Body");err++;}
|
||||
if(err){return false;}
|
||||
dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(params){if(params.useVideo){dialog.useVideo(true);}
|
||||
dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(!params){params={};}
|
||||
params.sdp=dialog.params.sdp;if(params){if(params.useVideo){dialog.useVideo(true);}
|
||||
dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;}
|
||||
dialog.rtc.createAnswer(dialog.params.sdp);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;}
|
||||
if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+"Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+"Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;}
|
||||
dialog.rtc.createAnswer(params);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;}
|
||||
if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;}
|
||||
if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;}
|
||||
dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;}
|
||||
dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.logout();verto.purge();}}
|
||||
return $.verto.warnOnUnload;});})(jQuery);
|
||||
dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1,hangup:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.purge();verto.logout();}}
|
||||
return $.verto.warnOnUnload;});$.verto.videoDevices=[];$.verto.audioDevices=[];$.verto.findDevices=function(runtime){var aud=[],vid=[];MediaStreamTrack.getSources(function(media_sources){for(var i=0;i<media_sources.length;i++){if(media_sources[i].kind=='video'){vid.push(media_sources[i]);}else{aud.push(media_sources[i]);}}
|
||||
$.verto.videoDevices=vid;$.verto.audioDevices=aud;console.info("Audio Devices",$.verto.audioDevices);console.info("Video Devices",$.verto.videoDevices);runtime();});}})(jQuery);
|
|
@ -469,7 +469,8 @@ function init() {
|
|||
ringFile: "sounds/bell_ring2.wav",
|
||||
videoParams: {
|
||||
"minWidth": "1280",
|
||||
"minHeight": "720"
|
||||
"minHeight": "720",
|
||||
"minFrameRate": 30
|
||||
},
|
||||
audioParams: {
|
||||
googAutoGainControl: false,
|
||||
|
|
|
@ -19,3 +19,9 @@ install-demo: all
|
|||
|
||||
install-maxdemo: all verto-max.js
|
||||
cp verto-max.js ../demo/js/verto-min.js
|
||||
|
||||
install-video_demo: all
|
||||
cp verto-min.js ../video_demo/js
|
||||
|
||||
install-video_maxdemo: all verto-max.js
|
||||
cp verto-max.js ../video_demo/js/verto-min.js
|
||||
|
|
|
@ -77,6 +77,9 @@
|
|||
useVideo: null,
|
||||
useStereo: false,
|
||||
userData: null,
|
||||
localVideo: null,
|
||||
screenShare: false,
|
||||
useCamera: "any",
|
||||
iceServers: false,
|
||||
videoParams: {},
|
||||
audioParams: {},
|
||||
|
@ -84,9 +87,11 @@
|
|||
onICEComplete: function() {},
|
||||
onICE: function() {},
|
||||
onOfferSDP: function() {}
|
||||
}
|
||||
},
|
||||
}, options);
|
||||
|
||||
this.enabled = true;
|
||||
|
||||
this.mediaData = {
|
||||
SDP: null,
|
||||
profile: {},
|
||||
|
@ -118,11 +123,12 @@
|
|||
checkCompat();
|
||||
};
|
||||
|
||||
$.FSRTC.prototype.useVideo = function(obj) {
|
||||
$.FSRTC.prototype.useVideo = function(obj, local) {
|
||||
var self = this;
|
||||
|
||||
if (obj) {
|
||||
self.options.useVideo = obj;
|
||||
self.options.localVideo = local;
|
||||
if (moz) {
|
||||
self.constraints.offerToReceiveVideo = true;
|
||||
} else {
|
||||
|
@ -130,6 +136,7 @@
|
|||
}
|
||||
} else {
|
||||
self.options.useVideo = null;
|
||||
self.options.localVideo = null;
|
||||
if (moz) {
|
||||
self.constraints.offerToReceiveVideo = false;
|
||||
} else {
|
||||
|
@ -192,12 +199,13 @@
|
|||
}
|
||||
|
||||
function onStreamError(self, e) {
|
||||
console.log('There has been a problem retrieving the streams - did you allow access?', e);
|
||||
|
||||
console.log('There has been a problem retrieving the streams - did you allow access? Check Device Resolution', e);
|
||||
doCallback(self, "onError", e);
|
||||
}
|
||||
|
||||
function onStreamSuccess(self) {
|
||||
function onStreamSuccess(self, stream) {
|
||||
console.log("Stream Success");
|
||||
doCallback(self, "onStream", stream);
|
||||
}
|
||||
|
||||
function onICE(self, candidate) {
|
||||
|
@ -281,6 +289,7 @@
|
|||
|
||||
if (self.options.useVideo) {
|
||||
self.options.useVideo.style.display = 'none';
|
||||
self.options.useVideo[moz ? 'mozSrcObject' : 'src'] = "";
|
||||
}
|
||||
|
||||
if (self.localStream) {
|
||||
|
@ -288,17 +297,58 @@
|
|||
self.localStream = null;
|
||||
}
|
||||
|
||||
if (self.options.localVideo) {
|
||||
self.options.localVideo.style.display = 'none';
|
||||
self.options.localVideo[moz ? 'mozSrcObject' : 'src'] = "";
|
||||
}
|
||||
|
||||
if (self.options.localVideoStream) {
|
||||
self.options.localVideoStream.stop();
|
||||
}
|
||||
|
||||
if (self.peer) {
|
||||
console.log("stopping peer");
|
||||
self.peer.stop();
|
||||
}
|
||||
};
|
||||
|
||||
$.FSRTC.prototype.createAnswer = function(sdp) {
|
||||
$.FSRTC.prototype.getMute = function() {
|
||||
var self = this;
|
||||
return self.enabled;
|
||||
}
|
||||
|
||||
$.FSRTC.prototype.setMute = function(what) {
|
||||
var self = this;
|
||||
var audioTracks = self.localStream.getAudioTracks();
|
||||
|
||||
for (var i = 0, len = audioTracks.length; i < len; i++ ) {
|
||||
switch(what) {
|
||||
case "on":
|
||||
audioTracks[i].enabled = true;
|
||||
break;
|
||||
case "off":
|
||||
audioTracks[i].enabled = false;
|
||||
break;
|
||||
case "toggle":
|
||||
audioTracks[i].enabled = !audioTracks[i].enabled;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
self.enabled = audioTracks[i].enabled;
|
||||
}
|
||||
|
||||
return !self.enabled;
|
||||
}
|
||||
|
||||
$.FSRTC.prototype.createAnswer = function(params) {
|
||||
var self = this;
|
||||
self.type = "answer";
|
||||
self.remoteSDP = sdp;
|
||||
console.debug("inbound sdp: ", sdp);
|
||||
self.remoteSDP = params.sdp;
|
||||
console.debug("inbound sdp: ", params.sdp);
|
||||
|
||||
self.options.useCamera = params.useCamera || "any";
|
||||
self.options.useMic = params.useMic || "any";
|
||||
|
||||
function onSuccess(stream) {
|
||||
self.localStream = stream;
|
||||
|
@ -336,53 +386,117 @@
|
|||
onStreamError(self, e);
|
||||
}
|
||||
|
||||
var mediaParams = getMediaParams(self);
|
||||
|
||||
console.log("Audio constraints", mediaParams.audio);
|
||||
console.log("Video constraints", mediaParams.video);
|
||||
|
||||
if (self.options.useVideo && self.options.localVideo) {
|
||||
getUserMedia({
|
||||
constraints: {
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: self.options.videoParams,
|
||||
optional: []
|
||||
},
|
||||
},
|
||||
localVideo: self.options.localVideo,
|
||||
onsuccess: function(e) {self.options.localVideoStream = e; console.log("local video ready");},
|
||||
onerror: function(e) {console.error("local video error!");}
|
||||
});
|
||||
}
|
||||
|
||||
getUserMedia({
|
||||
constraints: {
|
||||
audio: mediaParams.audio,
|
||||
video: mediaParams.video
|
||||
},
|
||||
video: mediaParams.useVideo,
|
||||
onsuccess: onSuccess,
|
||||
onerror: onError
|
||||
});
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
function getMediaParams(obj) {
|
||||
|
||||
var audio;
|
||||
|
||||
if (this.options.videoParams && this.options.videoParams.chromeMediaSource == 'screen') {
|
||||
if (obj.options.videoParams && obj.options.screenShare) {//obj.options.videoParams.chromeMediaSource == 'desktop') {
|
||||
|
||||
this.options.videoParams = {
|
||||
chromeMediaSource: 'screen',
|
||||
maxWidth:screen.width,
|
||||
maxHeight:screen.height
|
||||
};
|
||||
//obj.options.videoParams = {
|
||||
// chromeMediaSource: 'screen',
|
||||
// maxWidth:screen.width,
|
||||
// maxHeight:screen.height
|
||||
// chromeMediaSourceId = sourceId;
|
||||
// };
|
||||
|
||||
console.error("SCREEN SHARE");
|
||||
audio = false;
|
||||
} else {
|
||||
audio = {
|
||||
mandatory: this.options.audioParams,
|
||||
mandatory: obj.options.audioParams,
|
||||
optional: []
|
||||
};
|
||||
|
||||
if (obj.options.useMic !== "any") {
|
||||
audio.optional = [{sourceId: obj.options.useMic}]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.log("Mandatory audio constraints", this.options.audioParams);
|
||||
console.log("Mandatory video constraints", this.options.videoParams);
|
||||
if (obj.options.useVideo && obj.options.localVideo) {
|
||||
getUserMedia({
|
||||
constraints: {
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: obj.options.videoParams,
|
||||
optional: []
|
||||
},
|
||||
},
|
||||
localVideo: obj.options.localVideo,
|
||||
onsuccess: function(e) {self.options.localVideoStream = e; console.log("local video ready");},
|
||||
onerror: function(e) {console.error("local video error!");}
|
||||
});
|
||||
}
|
||||
|
||||
getUserMedia({
|
||||
constraints: {
|
||||
audio: audio,
|
||||
video: this.options.useVideo ? {
|
||||
mandatory: this.options.videoParams,
|
||||
optional: []
|
||||
} : null
|
||||
},
|
||||
video: this.options.useVideo ? true : false,
|
||||
onsuccess: onSuccess,
|
||||
onerror: onError
|
||||
});
|
||||
var video = {
|
||||
mandatory: obj.options.videoParams,
|
||||
optional: []
|
||||
}
|
||||
|
||||
var useVideo = obj.options.useVideo;
|
||||
|
||||
if (useVideo && obj.options.useCamera && obj.options.useCamera !== "none") {
|
||||
if (obj.options.useCamera !== "any") {
|
||||
video.optional = [{sourceId: obj.options.useCamera}]
|
||||
}
|
||||
} else {
|
||||
video = null;
|
||||
useVideo = null;
|
||||
}
|
||||
|
||||
return {audio: audio, video: video, useVideo: useVideo};
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
$.FSRTC.prototype.call = function(profile) {
|
||||
checkCompat();
|
||||
|
||||
|
||||
var self = this;
|
||||
var screen = false;
|
||||
|
||||
self.type = "offer";
|
||||
|
||||
if (self.options.videoParams && self.options.screenShare) { //self.options.videoParams.chromeMediaSource == 'desktop') {
|
||||
screen = true;
|
||||
}
|
||||
|
||||
function onSuccess(stream) {
|
||||
self.localStream = stream;
|
||||
self.localStream = stream;
|
||||
|
||||
self.peer = RTCPeerConnection({
|
||||
type: self.type,
|
||||
|
@ -393,7 +507,7 @@
|
|||
onICEComplete: function() {
|
||||
return onICEComplete(self);
|
||||
},
|
||||
onRemoteStream: function(stream) {
|
||||
onRemoteStream: screen ? function(stream) {console.error("SKIP");} : function(stream) {
|
||||
return onRemoteStream(self, stream);
|
||||
},
|
||||
onOfferSDP: function(sdp) {
|
||||
|
@ -409,53 +523,35 @@
|
|||
iceServers: self.options.iceServers,
|
||||
});
|
||||
|
||||
onStreamSuccess(self);
|
||||
onStreamSuccess(self, stream);
|
||||
}
|
||||
|
||||
function onError(e) {
|
||||
onStreamError(self, e);
|
||||
}
|
||||
|
||||
var mediaParams = getMediaParams(self);
|
||||
|
||||
var audio;
|
||||
|
||||
if (this.options.videoParams && this.options.videoParams.chromeMediaSource == 'screen') {
|
||||
|
||||
this.options.videoParams = {
|
||||
chromeMediaSource: 'screen',
|
||||
maxWidth:screen.width,
|
||||
maxHeight:screen.height
|
||||
};
|
||||
|
||||
console.error("SCREEN SHARE");
|
||||
audio = false;
|
||||
} else {
|
||||
audio = {
|
||||
mandatory: this.options.audioParams,
|
||||
optional: []
|
||||
};
|
||||
}
|
||||
|
||||
console.log("Mandatory audio constraints", this.options.audioParams);
|
||||
console.log("Mandatory video constraints", this.options.videoParams);
|
||||
console.log("Audio constraints", mediaParams.audio);
|
||||
console.log("Video constraints", mediaParams.video);
|
||||
|
||||
|
||||
getUserMedia({
|
||||
constraints: {
|
||||
audio: audio,
|
||||
video: this.options.useVideo ? {
|
||||
mandatory: this.options.videoParams,
|
||||
optional: []
|
||||
} : null
|
||||
audio: mediaParams.audio,
|
||||
video: mediaParams.video
|
||||
},
|
||||
video: this.options.useVideo ? true : false,
|
||||
video: mediaParams.useVideo,
|
||||
onsuccess: onSuccess,
|
||||
onerror: onError
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
navigator.getUserMedia({
|
||||
video: this.options.useVideo,
|
||||
video: self.options.useVideo,
|
||||
audio: true
|
||||
}, onSuccess, onError);
|
||||
*/
|
||||
|
@ -823,14 +919,22 @@
|
|||
});
|
||||
|
||||
function streaming(stream) {
|
||||
var video = options.video;
|
||||
if (video) {
|
||||
video[moz ? 'mozSrcObject' : 'src'] = moz ? stream : window.webkitURL.createObjectURL(stream);
|
||||
//var video = options.video;
|
||||
//var localVideo = options.localVideo;
|
||||
//if (video) {
|
||||
// video[moz ? 'mozSrcObject' : 'src'] = moz ? stream : window.webkitURL.createObjectURL(stream);
|
||||
//video.play();
|
||||
//}
|
||||
|
||||
if (options.localVideo) {
|
||||
options.localVideo[moz ? 'mozSrcObject' : 'src'] = moz ? stream : window.webkitURL.createObjectURL(stream);
|
||||
options.localVideo.style.display = 'block';
|
||||
}
|
||||
|
||||
if (options.onsuccess) {
|
||||
options.onsuccess(stream);
|
||||
}
|
||||
|
||||
media = stream;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
*/
|
||||
|
||||
(function($) {
|
||||
var sources = [];
|
||||
|
||||
var generateGUID = (typeof(window.crypto) !== 'undefined' && typeof(window.crypto.getRandomValues) !== 'undefined') ?
|
||||
function() {
|
||||
|
@ -71,6 +72,7 @@
|
|||
passwd: null,
|
||||
socketUrl: null,
|
||||
tag: null,
|
||||
localTag: null,
|
||||
videoParams: {},
|
||||
audioParams: {},
|
||||
loginParams: {},
|
||||
|
@ -436,6 +438,12 @@
|
|||
|
||||
if (data.params.callID) {
|
||||
var dialog = verto.dialogs[data.params.callID];
|
||||
|
||||
if (data.method === "verto.attach" && dialog) {
|
||||
delete dialog.verto.dialogs[dialog.callID];
|
||||
dialog.rtc.stop();
|
||||
dialog = null;
|
||||
}
|
||||
|
||||
if (dialog) {
|
||||
|
||||
|
@ -1171,21 +1179,51 @@
|
|||
var play_id = "play_" + confMan.serno;
|
||||
var stop_id = "stop_" + confMan.serno;
|
||||
var recording_id = "recording_" + confMan.serno;
|
||||
var snapshot_id = "snapshot_" + confMan.serno;
|
||||
var rec_stop_id = "recording_stop" + confMan.serno;
|
||||
var div_id = "confman_" + confMan.serno;
|
||||
|
||||
|
||||
|
||||
var html = "<div id='" + div_id + "'><br>" +
|
||||
"<button class='ctlbtn' id='" + play_id + "'>Play</button>" +
|
||||
"<button class='ctlbtn' id='" + stop_id + "'>Stop</button>" +
|
||||
"<button class='ctlbtn' id='" + recording_id + "'>Record</button>" +
|
||||
"<button class='ctlbtn' id='" + rec_stop_id + "'>Record Stop</button>" +
|
||||
"<br><br></div>";
|
||||
"<button class='ctlbtn' id='" + play_id + "'>Play</button>" +
|
||||
"<button class='ctlbtn' id='" + stop_id + "'>Stop</button>" +
|
||||
"<button class='ctlbtn' id='" + recording_id + "'>Record</button>" +
|
||||
"<button class='ctlbtn' id='" + rec_stop_id + "'>Record Stop</button>" +
|
||||
(confMan.params.hasVid ? "<button class='ctlbtn' id='" + snapshot_id + "'>PNG Snapshot</button>" : "") +
|
||||
"<br><br></div>";
|
||||
|
||||
jq.html(html);
|
||||
|
||||
if (confMan.params.hasVid) {
|
||||
var vlayout_id = "confman_vid_layout_" + confMan.serno;
|
||||
var vlselect_id = "confman_vl_select_" + confMan.serno;
|
||||
|
||||
var vlhtml = "<div id='" + vlayout_id + "'><br>" +
|
||||
"<b>Video Layout</b> <select id='" + vlselect_id + "'></select> " +
|
||||
"<br><br></div>";
|
||||
jq.append(vlhtml);
|
||||
|
||||
$("#" + vlselect_id).change(function() {
|
||||
var val = $("#" + vlselect_id).find(":selected").val();
|
||||
if (val !== "none") {
|
||||
confMan.modCommand("vid-layout", null, val);
|
||||
}
|
||||
});
|
||||
|
||||
$("#" + snapshot_id).click(function() {
|
||||
var file = prompt("Please enter file name", "");
|
||||
if (file) {
|
||||
confMan.modCommand("vid-write-png", null, file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#" + play_id).click(function() {
|
||||
var file = prompt("Please enter file name", "");
|
||||
confMan.modCommand("play", null, file);
|
||||
if (file) {
|
||||
confMan.modCommand("play", null, file);
|
||||
}
|
||||
});
|
||||
|
||||
$("#" + stop_id).click(function() {
|
||||
|
@ -1194,7 +1232,9 @@
|
|||
|
||||
$("#" + recording_id).click(function() {
|
||||
var file = prompt("Please enter file name", "");
|
||||
confMan.modCommand("recording", null, ["start", file]);
|
||||
if (file) {
|
||||
confMan.modCommand("recording", null, ["start", file]);
|
||||
}
|
||||
});
|
||||
|
||||
$("#" + rec_stop_id).click(function() {
|
||||
|
@ -1207,15 +1247,23 @@
|
|||
var x = parseInt(rowid);
|
||||
var kick_id = "kick_" + x;
|
||||
var tmute_id = "tmute_" + x;
|
||||
var tvmute_id = "tvmute_" + x;
|
||||
var vbanner_id = "vbanner_" + x;
|
||||
var tvpresenter_id = "tvpresenter_" + x;
|
||||
var tvfloor_id = "tvfloor_" + x;
|
||||
var box_id = "box_" + x;
|
||||
var volup_id = "volume_in_up" + x;
|
||||
var voldn_id = "volume_in_dn" + x;
|
||||
var transfer_id = "transfer" + x;
|
||||
|
||||
|
||||
|
||||
var html = "<div id='" + box_id + "'>" +
|
||||
"<button class='ctlbtn' id='" + kick_id + "'>Kick</button>" +
|
||||
"<button class='ctlbtn' id='" + tmute_id + "'>Mute</button>" +
|
||||
(confMan.params.hasVid ? "<button class='ctlbtn' id='" + tvmute_id + "'>VMute</button>" : "") +
|
||||
(confMan.params.hasVid ? "<button class='ctlbtn' id='" + tvpresenter_id + "'>Presenter</button>" : "") +
|
||||
(confMan.params.hasVid ? "<button class='ctlbtn' id='" + tvfloor_id + "'>Vid Floor</button>" : "") +
|
||||
(confMan.params.hasVid ? "<button class='ctlbtn' id='" + vbanner_id + "'>Banner</button>" : "") +
|
||||
"<button class='ctlbtn' id='" + voldn_id + "'>Vol -</button>" +
|
||||
"<button class='ctlbtn' id='" + volup_id + "'>Vol +</button>" +
|
||||
"<button class='ctlbtn' id='" + transfer_id + "'>Transfer</button>" +
|
||||
|
@ -1240,7 +1288,9 @@
|
|||
|
||||
$("#" + transfer_id).click(function() {
|
||||
var xten = prompt("Enter Extension");
|
||||
confMan.modCommand("transfer", x, xten);
|
||||
if (xten) {
|
||||
confMan.modCommand("transfer", x, xten);
|
||||
}
|
||||
});
|
||||
|
||||
$("#" + kick_id).click(function() {
|
||||
|
@ -1251,6 +1301,24 @@
|
|||
confMan.modCommand("tmute", x);
|
||||
});
|
||||
|
||||
if (confMan.params.hasVid) {
|
||||
$("#" + tvmute_id).click(function() {
|
||||
confMan.modCommand("tvmute", x);
|
||||
});
|
||||
$("#" + tvpresenter_id).click(function() {
|
||||
confMan.modCommand("vid-res-id", x, "presenter");
|
||||
});
|
||||
$("#" + tvfloor_id).click(function() {
|
||||
confMan.modCommand("vid-floor", x, "force");
|
||||
});
|
||||
$("#" + vbanner_id).click(function() {
|
||||
var text = prompt("Please enter text", "");
|
||||
if (text) {
|
||||
confMan.modCommand("vid-banner", x, escape(text));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#" + volup_id).click(function() {
|
||||
confMan.modCommand("volume_in", x, "up");
|
||||
});
|
||||
|
@ -1269,7 +1337,7 @@
|
|||
|
||||
if (confMan.params.laData.role === "moderator") {
|
||||
atitle = "Action";
|
||||
awidth = 200;
|
||||
awidth = 300;
|
||||
|
||||
if (confMan.params.mainModID) {
|
||||
genMainMod($(confMan.params.mainModID));
|
||||
|
@ -1284,16 +1352,47 @@
|
|||
if (confMan.params.onBroadcast) {
|
||||
confMan.params.onBroadcast(verto, confMan, e.data);
|
||||
}
|
||||
if (!confMan.destroyed && confMan.params.displayID) {
|
||||
$(confMan.params.displayID).html(e.data.response + "<br><br>");
|
||||
if (confMan.lastTimeout) {
|
||||
clearTimeout(confMan.lastTimeout);
|
||||
confMan.lastTimeout = 0;
|
||||
}
|
||||
confMan.lastTimeout = setTimeout(function() { $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready<br><br>");}, 4000);
|
||||
}
|
||||
|
||||
if (e.data["conf-command"] === "list-videoLayouts") {
|
||||
var vlselect_id = "#confman_vl_select_" + confMan.serno;
|
||||
var vlayout_id = "#confman_vid_layout_" + confMan.serno;
|
||||
var x = 0;
|
||||
var options;
|
||||
|
||||
$(vlselect_id).append(new Option("Choose a Layout", "none"));
|
||||
|
||||
if (e.data.responseData) {
|
||||
options = e.data.responseData.sort();
|
||||
|
||||
for (var i in options) {
|
||||
$(vlselect_id).append(new Option(options[i], options[i]));
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
if (x) {
|
||||
$(vlselect_id).selectmenu('refresh', true);
|
||||
} else {
|
||||
$(vlayout_id).hide();
|
||||
}
|
||||
} else {
|
||||
|
||||
if (!confMan.destroyed && confMan.params.displayID) {
|
||||
$(confMan.params.displayID).html(e.data.response + "<br><br>");
|
||||
if (confMan.lastTimeout) {
|
||||
clearTimeout(confMan.lastTimeout);
|
||||
confMan.lastTimeout = 0;
|
||||
}
|
||||
confMan.lastTimeout = setTimeout(function() { $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready<br><br>");}, 4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (confMan.params.hasVid) {
|
||||
confMan.modCommand("list-videoLayouts", null, null);
|
||||
}
|
||||
}
|
||||
|
||||
var row_callback = null;
|
||||
|
@ -1339,7 +1438,7 @@
|
|||
},
|
||||
{
|
||||
"sTitle": "Status",
|
||||
"sWidth": confMan.params.hasVid ? "300px" : "150px"
|
||||
"sWidth": confMan.params.hasVid ? "200px" : "150px"
|
||||
},
|
||||
{
|
||||
"sTitle": atitle,
|
||||
|
@ -1367,16 +1466,18 @@
|
|||
$.verto.confMan.prototype.modCommand = function(cmd, id, value) {
|
||||
var confMan = this;
|
||||
|
||||
confMan.verto.sendMethod("verto.broadcast", {
|
||||
confMan.verto.rpcClient.call("verto.broadcast", {
|
||||
"eventChannel": confMan.params.laData.modChannel,
|
||||
"data": {
|
||||
"application": "conf-control",
|
||||
"command": cmd,
|
||||
"id": id,
|
||||
"value": value
|
||||
"application": "conf-control",
|
||||
"command": cmd,
|
||||
"id": id,
|
||||
"value": value
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
$.verto.confMan.prototype.destroy = function() {
|
||||
var confMan = this;
|
||||
|
@ -1402,10 +1503,15 @@
|
|||
dialog.params = $.extend({
|
||||
useVideo: verto.options.useVideo,
|
||||
useStereo: verto.options.useStereo,
|
||||
screenShare: false,
|
||||
useCamera: "any",
|
||||
useMic: "any",
|
||||
tag: verto.options.tag,
|
||||
login: verto.options.login
|
||||
localTag: verto.options.localTag,
|
||||
login: verto.options.login,
|
||||
videoParams: verto.options.videoParams
|
||||
}, params);
|
||||
|
||||
|
||||
dialog.verto = verto;
|
||||
dialog.direction = direction;
|
||||
dialog.lastState = null;
|
||||
|
@ -1413,13 +1519,16 @@
|
|||
dialog.callbacks = verto.callbacks;
|
||||
dialog.answered = false;
|
||||
dialog.attach = params.attach || false;
|
||||
dialog.screenShare = params.screenShare || false;
|
||||
dialog.useCamera = params.useCamera;
|
||||
dialog.useMic = params.useMic;
|
||||
|
||||
if (dialog.params.callID) {
|
||||
dialog.callID = dialog.params.callID;
|
||||
} else {
|
||||
dialog.callID = dialog.params.callID = generateGUID();
|
||||
}
|
||||
|
||||
|
||||
if (dialog.params.tag) {
|
||||
dialog.audioStream = document.getElementById(dialog.params.tag);
|
||||
|
||||
|
@ -1428,6 +1537,10 @@
|
|||
}
|
||||
} //else conjure one TBD
|
||||
|
||||
if (dialog.params.localTag) {
|
||||
dialog.localVideo = document.getElementById(dialog.params.localTag);
|
||||
}
|
||||
|
||||
dialog.verto.dialogs[dialog.callID] = dialog;
|
||||
|
||||
var RTCcallbacks = {};
|
||||
|
@ -1488,19 +1601,27 @@
|
|||
}
|
||||
};
|
||||
|
||||
RTCcallbacks.onStream = function(rtc, stream) {
|
||||
console.log("stream started");
|
||||
};
|
||||
|
||||
RTCcallbacks.onError = function(e) {
|
||||
console.error("ERROR:", e);
|
||||
dialog.hangup();
|
||||
dialog.hangup({cause: "Device or Permission Error"});
|
||||
};
|
||||
|
||||
dialog.rtc = new $.FSRTC({
|
||||
callbacks: RTCcallbacks,
|
||||
localVideo: dialog.localVideo,
|
||||
useVideo: dialog.videoStream,
|
||||
useAudio: dialog.audioStream,
|
||||
useStereo: dialog.params.useStereo,
|
||||
videoParams: verto.options.videoParams,
|
||||
videoParams: dialog.params.videoParams,
|
||||
audioParams: verto.options.audioParams,
|
||||
iceServers: verto.options.iceServers
|
||||
iceServers: verto.options.iceServers,
|
||||
screenShare: dialog.screenShare,
|
||||
useCamera: dialog.useCamera,
|
||||
useMic: dialog.useMic
|
||||
});
|
||||
|
||||
dialog.rtc.verto = dialog.verto;
|
||||
|
@ -1604,7 +1725,9 @@
|
|||
break;
|
||||
case $.verto.enum.state.destroy:
|
||||
delete dialog.verto.dialogs[dialog.callID];
|
||||
dialog.rtc.stop();
|
||||
if (!dialog.params.screenShare) {
|
||||
dialog.rtc.stop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1666,15 +1789,15 @@
|
|||
|
||||
if (params) {
|
||||
if (params.causeCode) {
|
||||
dialog.causeCode = params.causeCode;
|
||||
dialog.causeCode = params.causeCode;
|
||||
}
|
||||
|
||||
if (params.cause) {
|
||||
dialog.cause = params.cause;
|
||||
dialog.cause = params.cause;
|
||||
}
|
||||
}
|
||||
|
||||
if (dialog.state.val > $.verto.enum.state.new.val && dialog.state.val < $.verto.enum.state.hangup.val) {
|
||||
if (dialog.state.val >= $.verto.enum.state.new.val && dialog.state.val < $.verto.enum.state.hangup.val) {
|
||||
dialog.setState($.verto.enum.state.hangup);
|
||||
} else if (dialog.state.val < $.verto.enum.state.destroy) {
|
||||
dialog.setState($.verto.enum.state.destroy);
|
||||
|
@ -1722,10 +1845,20 @@
|
|||
dialog.videoStream = null;
|
||||
}
|
||||
|
||||
dialog.rtc.useVideo(dialog.videoStream);
|
||||
dialog.rtc.useVideo(dialog.videoStream, dialog.localVideo);
|
||||
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.setMute = function(what) {
|
||||
var dialog = this;
|
||||
return dialog.rtc.setMute(what);
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.getMute = function(what) {
|
||||
var dialog = this;
|
||||
return dialog.rtc.getMute(what);
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.useStereo = function(on) {
|
||||
var dialog = this;
|
||||
|
||||
|
@ -1809,16 +1942,23 @@
|
|||
|
||||
$.verto.dialog.prototype.answer = function(params) {
|
||||
var dialog = this;
|
||||
|
||||
|
||||
if (!dialog.answered) {
|
||||
if (!params) {
|
||||
params = {};
|
||||
}
|
||||
|
||||
params.sdp = dialog.params.sdp;
|
||||
|
||||
if (params) {
|
||||
if (params.useVideo) {
|
||||
dialog.useVideo(true);
|
||||
}
|
||||
dialog.params.callee_id_name = params.callee_id_name;
|
||||
dialog.params.callee_id_number = params.callee_id_number;
|
||||
dialog.params.callee_id_name = params.callee_id_name;
|
||||
dialog.params.callee_id_number = params.callee_id_number;
|
||||
}
|
||||
dialog.rtc.createAnswer(dialog.params.sdp);
|
||||
|
||||
dialog.rtc.createAnswer(params);
|
||||
dialog.answered = true;
|
||||
}
|
||||
};
|
||||
|
@ -1836,9 +1976,9 @@
|
|||
dialog.setState($.verto.enum.state.active);
|
||||
} else {
|
||||
if (dialog.gotEarly) {
|
||||
console.log("Dialog " + dialog.callID + "Got answer while still establishing early media, delaying...");
|
||||
console.log("Dialog " + dialog.callID + " Got answer while still establishing early media, delaying...");
|
||||
} else {
|
||||
console.log("Dialog " + dialog.callID + "Answering Channel");
|
||||
console.log("Dialog " + dialog.callID + " Answering Channel");
|
||||
dialog.rtc.answer(params.sdp, function() {
|
||||
dialog.setState($.verto.enum.state.active);
|
||||
}, function(e) {
|
||||
|
@ -1848,6 +1988,8 @@
|
|||
console.log("Dialog " + dialog.callID + "ANSWER SDP", params.sdp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.cidString = function(enc) {
|
||||
|
@ -1927,7 +2069,8 @@
|
|||
recovering: 1,
|
||||
ringing: 1,
|
||||
destroy: 1,
|
||||
answering: 1
|
||||
answering: 1,
|
||||
hangup: 1
|
||||
},
|
||||
requesting: {
|
||||
trying: 1,
|
||||
|
@ -1985,11 +2128,39 @@
|
|||
for (var i in $.verto.saved) {
|
||||
var verto = $.verto.saved[i];
|
||||
if (verto) {
|
||||
verto.logout();
|
||||
verto.purge();
|
||||
verto.logout();
|
||||
}
|
||||
}
|
||||
return $.verto.warnOnUnload;
|
||||
});
|
||||
|
||||
$.verto.videoDevices = [];
|
||||
$.verto.audioDevices = [];
|
||||
|
||||
$.verto.findDevices = function(runtime) {
|
||||
var aud = [], vid = [];
|
||||
|
||||
MediaStreamTrack.getSources(function (media_sources) {
|
||||
for (var i = 0; i < media_sources.length; i++) {
|
||||
|
||||
if (media_sources[i].kind == 'video') {
|
||||
vid.push(media_sources[i]);
|
||||
} else {
|
||||
aud.push(media_sources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
$.verto.videoDevices = vid;
|
||||
$.verto.audioDevices = aud;
|
||||
|
||||
console.info("Audio Devices", $.verto.audioDevices);
|
||||
console.info("Video Devices", $.verto.videoDevices);
|
||||
runtime();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
})(jQuery);
|
||||
|
|
|
@ -37,6 +37,27 @@ m4_include(m4/ax_c99_features.m4)
|
|||
m4_include(m4/ax_check_export_capability.m4)
|
||||
m4_include(m4/ax_check_arm_neon.m4)
|
||||
|
||||
AC_DEFUN([AC_FUNC_ALIGNED_ALLOC],[
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
AC_CACHE_CHECK([checking for aligned_alloc],
|
||||
[ac_cv_func_aligned_alloc],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
#define _ISOC11_SOURCE
|
||||
#include <stdlib.h>
|
||||
],
|
||||
[
|
||||
aligned_alloc(0,0);
|
||||
])],
|
||||
[ac_cv_func_aligned_alloc=yes],
|
||||
[ac_cv_func_aligned_alloc=no])])
|
||||
|
||||
if test "x${ac_cv_func_aligned_alloc}" = "xyes" ; then
|
||||
AC_DEFINE([HAVE_ALIGNED_ALLOC], [1], [Define to 1 if you have the aligned_alloc() function.])
|
||||
fi
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
])
|
||||
|
||||
AC_CONFIG_SRCDIR([src/tone_generate.c])
|
||||
AC_CONFIG_AUX_DIR([config])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
@ -174,7 +195,7 @@ fi
|
|||
|
||||
AX_C99_FLEXIBLE_ARRAY
|
||||
|
||||
AC_CHECK_FUNCS([aligned_alloc])
|
||||
AC_FUNC_ALIGNED_ALLOC
|
||||
AC_CHECK_FUNCS([memalign])
|
||||
AC_CHECK_FUNCS([posix_memalign])
|
||||
AC_CHECK_FUNCS([memmove])
|
||||
|
@ -464,6 +485,13 @@ intel)
|
|||
fi
|
||||
COMP_VENDOR_LDFLAGS=
|
||||
;;
|
||||
clang*)
|
||||
COMP_VENDOR_CFLAGS="-D_XOPEN_SOURCE=700 -std=c99 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS"
|
||||
if test x"$ac_cv_gcc_unused_but_set_variable" = xyes ; then
|
||||
COMP_VENDOR_CFLAGS="-Wunused-but-set-variable $COMP_VENDOR_CFLAGS"
|
||||
fi
|
||||
COMP_VENDOR_LDFLAGS=
|
||||
;;
|
||||
*)
|
||||
COMP_VENDOR_CFLAGS="-std=c99 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS"
|
||||
if test x"$ac_cv_gcc_unused_but_set_variable" = xyes ; then
|
||||
|
|
|
@ -19,12 +19,16 @@
|
|||
name CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT test (step|possible-step)* >
|
||||
<!ELEMENT test (repeat|step)* >
|
||||
<!ATTLIST test
|
||||
name CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT possible-step (step)* >
|
||||
<!ELEMENT repeat (step)* >
|
||||
<!ATTLIST repeat
|
||||
min CDATA #IMPLIED
|
||||
max CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT step (check|EMPTY)* >
|
||||
<!ATTLIST step
|
||||
|
@ -49,5 +53,6 @@
|
|||
<!ATTLIST check
|
||||
name CDATA #IMPLIED
|
||||
desc CDATA #IMPLIED
|
||||
cond CDATA #IMPLIED
|
||||
>
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 80 08"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -155,7 +155,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -169,7 +169,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 80 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -177,7 +177,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -200,6 +200,7 @@
|
|||
|
||||
<step dir="T" type="CED"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
@ -261,7 +262,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -269,7 +270,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -283,7 +284,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -291,7 +292,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -305,7 +306,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -313,7 +314,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -327,7 +328,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -335,7 +336,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -357,7 +358,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -365,7 +366,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -379,5 +380,214 @@
|
|||
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||
<step type="STATUS" value="OK"/>
|
||||
</test>
|
||||
<test name="ECM-DCN-clipped">
|
||||
<!-- Tester calls DUT and sends one 31k byte STAIRSTEP page and one 15k byte STAIRSTEP page. -->
|
||||
<step type="CALL"/>
|
||||
|
||||
<!--<step dir="T" type="CNG"/>-->
|
||||
|
||||
<step dir="R" type="CED"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DIS" value="FF C8 01 ..." timeout="60000"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="DCS" value="FF C8 41 00 50 1F 30"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="TCF" modem="V.27ter/4800" value="900"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="CFR" value="FF C8 21"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.27ter/4800"/>
|
||||
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif" min_bits="141"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 08"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.27ter/4800"/>
|
||||
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 80 08"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
|
||||
<repeat min="2" max="2">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
</repeat>
|
||||
|
||||
<step dir="T" type="CLEAR"/>
|
||||
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||
<step type="STATUS" value="OK"/>
|
||||
</test>
|
||||
<test name="Non-ECM-DCN-clipped">
|
||||
<!-- Tester calls DUT and sends 2 WHITE pages. DUT should send CSI for this test procedure. -->
|
||||
<step type="CALL"/>
|
||||
<step dir="T" type="SET" tag="IDENT" value="+0123456789"/>
|
||||
|
||||
<!--<step dir="T" type="CNG"/>-->
|
||||
|
||||
<step dir="R" type="CED"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DIS" value="FF C8 01 ..." timeout="60000"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="DCS" value="FF C8 41 00 50 00"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="TCF" modem="V.27ter/4800" value="900"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="CFR" value="FF C8 21"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="MSG" modem="V.27ter/4800" value="etsi_300_242_a4_white.tif"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="EOP" value="FF C8 72"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
|
||||
<repeat min="2" max="2">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
</repeat>
|
||||
|
||||
<step dir="T" type="CLEAR"/>
|
||||
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||
<step type="STATUS" value="OK"/>
|
||||
</test>
|
||||
<test name="Tx-EOP-echo">
|
||||
<!-- DUT calls tester and sends 1 IMPRESS and 1 WHITE page. -->
|
||||
<step type="ANSWER" value="etsi_300_242_a4_impress_white.tif"/>
|
||||
<step dir="T" type="SET" tag="IDENT" value="+0123456789"/>
|
||||
|
||||
<step dir="R" type="CNG"/>
|
||||
|
||||
<step dir="T" type="CED"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 00"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="TSI+" value="FF C0 C2 9C 1C EC 6C AC 2C CC 4C 8C 0C D4 04 04 04 04 04 04 04 04 04 ..."/>
|
||||
<step dir="R" type="HDLC" tag="DCS+" value="FF C8 C1 ..."/>
|
||||
<step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="CFR" value="FF C8 21"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="MSG" modem="V.27ter/4800" timeout="180000"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MPS+" value="FF C8 F2"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="EOP+" value="FF C8 F4"/>
|
||||
|
||||
<!-- Erroneous echo of EOP -->
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21" />
|
||||
<step dir="T" type="HDLC" tag="EOP" value="FF C8 F4"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
|
||||
|
||||
<step dir="R" type="CLEAR" timein="800" timeout="1200"/>
|
||||
<step type="STATUS" value="OK"/>
|
||||
</test>
|
||||
<test name="Tx-PPS-echo">
|
||||
<!-- DUT calls tester and sends 1 IMPRESS and 1 WHITE page. -->
|
||||
<step type="ANSWER" value="etsi_300_242_a4_impress_white.tif"/>
|
||||
|
||||
<step dir="R" type="CNG"/>
|
||||
|
||||
<step dir="T" type="CED"/>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="DIS" value="FF C8 01 00 50 1F 20"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCS+" value="FF C8 C1 ..."/>
|
||||
<step dir="R" type="TCF" modem="V.27ter/4800" timeout="10000"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="CFR" value="FF C8 21"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="PP" modem="V.27ter/4800" frame_size="64" timeout="180000"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPS-NULL+" value="FF C8 FD 00 ..."/>
|
||||
|
||||
<!-- Erroneous echo of PPS-NULL -->
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 FF"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="PP" modem="V.27ter/4800" frame_size="64" timeout="180000"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPS-MPS+" value="FF C8 FD F2 ..."/>
|
||||
|
||||
<!-- Erroneous echo of PPS-MPS -->
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 80 3B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="PP" modem="V.27ter/4800" frame_size="64" timeout="60000"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPS-EOP+" value="FF C8 FD F4 ..."/>
|
||||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
|
||||
|
||||
<step dir="R" type="CLEAR" timein="800" timeout="1200"/>
|
||||
<step type="STATUS" value="OK"/>
|
||||
</test>
|
||||
</test-group>
|
||||
</fax-tests>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<!--<step dir="T" type="CNG"/>-->
|
||||
|
||||
<step dir="R" type="CED">
|
||||
<check name="MRGN01M01" desc="receipt of CED"/>
|
||||
<check name="MRGN01M01" desc="receipt of CED" cond="Confirm receipt of CED. FAIL otherwise"/>
|
||||
<check name="MRGN01M02" desc="CED is 2.6s to 4s"/>
|
||||
</step>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="NSF" value="FF C0 04 ..." timeout="60000">
|
||||
|
@ -171,7 +171,7 @@
|
|||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="MSG" modem="V.27ter/4800" value="etsi_300_242_a4_duration1.tif">
|
||||
<check name="MRGN02M01" desc="Accept 4.9s long scan line"/>
|
||||
<check name="MRGN03M01" desc="Accept 4.9s long scan line"/>
|
||||
</step>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
|
@ -183,7 +183,7 @@
|
|||
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="MSG" modem="V.27ter/4800" value="etsi_300_242_a4_duration2.tif">
|
||||
<check name="MRGN02M02" desc="Reject 5.1s long scan line"/>
|
||||
<check name="MRGN03M02" desc="Reject 5.1s long scan line"/>
|
||||
</step>
|
||||
<step type="WAIT" value="75"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
|
@ -239,7 +239,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF or RTP" value="FF C8 31" xxx="FF C8 33">
|
||||
<check name="MRGN02M01" desc="Accept 4.9% of scan lines in error"/>
|
||||
<check name="MRGN04M01" desc="Accept 4.9% of scan lines in error"/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -255,7 +255,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RTN" value="FF C8 32">
|
||||
<check name="MRGN02M01" desc="Reject 15.1% of scan lines in error"/>
|
||||
<check name="MRGN04M02" desc="Reject 15.1% of scan lines in error"/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -493,9 +493,9 @@
|
|||
<step dir="T" type="TCF" modem="V.27ter/2400" value="450"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="FTT" value="FF C8 22">
|
||||
<check name="MRGN07M01" desc="FTT returned for corrupted TCF pattern"/>
|
||||
<check name="MRGN07M02" desc="FTT preamble between 850ms and 1150ms"/>
|
||||
<check name="MRGN07M03" desc="FTT is 0xFF, 0xC8, FCF with MSB of zero, and no FIF bytes"/>
|
||||
<check name="MRGN08M01" desc="FTT returned for corrupted TCF pattern"/>
|
||||
<check name="MRGN08M02" desc="FTT preamble between 850ms and 1150ms"/>
|
||||
<check name="MRGN08M03" desc="FTT is 0xFF, 0xC8, FCF with MSB of zero, and no FIF bytes"/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -507,7 +507,7 @@
|
|||
<step dir="T" type="TCF" modem="V.27ter/4800" value="900"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="CFR" value="FF C8 21">
|
||||
<check name="MRGN07M04" desc="Accept TCF"/>
|
||||
<check name="MRGN08M04" desc="Accept TCF"/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1356,7 +1356,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 80 08"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1364,7 +1364,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1378,7 +1378,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 80 00 08"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1386,7 +1386,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1491,7 +1491,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 80 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1499,7 +1499,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
|
||||
|
@ -1539,7 +1539,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1547,7 +1547,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1561,7 +1561,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1569,7 +1569,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1583,7 +1583,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1591,7 +1591,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1605,7 +1605,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 10"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1613,7 +1613,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1635,7 +1635,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1643,7 +1643,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1686,7 +1686,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1694,7 +1694,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1708,7 +1708,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1716,7 +1716,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1730,7 +1730,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1738,7 +1738,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1752,7 +1752,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1760,7 +1760,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1782,7 +1782,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1790,7 +1790,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1833,7 +1833,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 FF"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1841,7 +1841,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1855,7 +1855,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 80 DC"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1863,7 +1863,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 ff ff ff ff"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1877,7 +1877,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 80 DC"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1885,7 +1885,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 ff ff ff ff"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1899,7 +1899,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 80 DC"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1907,7 +1907,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 ff ff ff ff"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1921,7 +1921,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 80 DC"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1929,7 +1929,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 ff ff ff ff"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -1980,7 +1980,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -1988,7 +1988,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2002,7 +2002,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2010,7 +2010,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2024,7 +2024,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2032,7 +2032,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2046,7 +2046,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2054,7 +2054,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2076,7 +2076,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2084,7 +2084,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2126,7 +2126,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2134,7 +2134,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2148,7 +2148,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2156,7 +2156,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2170,7 +2170,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2178,7 +2178,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2192,7 +2192,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2200,7 +2200,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="PPR" value="FF C8 3D 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF FF FF FF"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2251,7 +2251,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2259,7 +2259,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -2273,7 +2273,7 @@
|
|||
<step dir="T" type="HDLC" tag="PPS-EOP" value="FF C8 7D 74 80 00 6B"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<possible-step>
|
||||
<repeat min="0">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -2281,7 +2281,7 @@
|
|||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RR" value="FF C8 76"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</possible-step>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -5456,166 +5456,14 @@
|
|||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
<repeat min="23" max="30">
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="RR+" value="FF C8 F6"/>
|
||||
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
<step type="WAIT" value="500"/>
|
||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||
<step dir="T" type="HDLC" tag="RNR" value="FF C8 37"/>
|
||||
<step dir="T" type="POSTAMBLE"/>
|
||||
</repeat>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF"/>
|
||||
|
||||
|
@ -6755,12 +6603,12 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="MSG" modem="V.27ter/4800" value="etsi_300_242_a4_white.tif" timeout="60000">
|
||||
<check name="MRGP01M10" desc="Polled, MSG1"/>
|
||||
<check name="MRGP01M10" desc="Polled, transmit MSG1"/>
|
||||
</step>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="MPS" value="FF C8 72">
|
||||
<check name="MRGP01M11" desc="Polled, MPS"/>
|
||||
<check name="MRGP01M12" desc="Polled, MPS preamble"/>
|
||||
<check name="MRGP01M13" desc="Polled, MPS framing"/>
|
||||
<check name="MRGP01M11" desc="Polled, transmit MPS"/>
|
||||
<check name="MRGP01M12" desc="Polled, MPS preamble" cond="Confirm MPS preamble length is not less than 850ms, and not more than 1150ms. WARNING otherwise."/>
|
||||
<check name="MRGP01M13" desc="Polled, MPS framing" cond="Confirm MPS has HDLC address FF hex, HDLC control C8 hex, FCF MSB of zero, no FIF bytes and a valid FCS. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6770,12 +6618,12 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="MSG" modem="V.27ter/4800" timeout="60000">
|
||||
<check name="MRGP01M14" desc="Polled, MSG1"/>
|
||||
<check name="MRGP01M14" desc="Polled, transmit MSG2" cond="Confirm receipt of MSG2. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="EOP" value="FF C8 74">
|
||||
<check name="MRGP01M15" desc="Polled, EOP"/>
|
||||
<check name="MRGP01M16" desc="Polled, EOP preamble"/>
|
||||
<check name="MRGP01M17" desc="Polled, EOP framing"/>
|
||||
<check name="MRGP01M15" desc="Polled, EOP" cond="Confirm receipt of EOP. FAIL otherwise."/>
|
||||
<check name="MRGP01M16" desc="Polled, EOP preamble" cond="Confirm EOP preamble length is not less than 850ms, and not more than 1150ms. WARNING otherwise."/>
|
||||
<check name="MRGP01M17" desc="Polled, EOP framing" cond="Confirm EOP has HDLC address FF hex, HDLC control C8 hex, FCF MSB of zero, no FIF bytes and a valid FCS. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6785,10 +6633,10 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F">
|
||||
<check name="MRGP01M18" desc="Polled, DCN"/>
|
||||
<check name="MRGP01M19" desc="Polled, DCN preamble"/>
|
||||
<check name="MRGP01M20" desc="Polled, DCN framing"/>
|
||||
<check name="MRGP01M21" desc="Polled, disconnect after DCN"/>
|
||||
<check name="MRGP01M18" desc="Polled, DCN" cond="Confirm receipt of DCN. FAIL otherwise."/>
|
||||
<check name="MRGP01M19" desc="Polled, DCN preamble" cond="Confirm DCN preamble length is not less than 850ms, and not more than 1150ms. WARNING otherwise."/>
|
||||
<check name="MRGP01M20" desc="Polled, DCN framing" cond="Confirm DCN has HDLC address FF hex, HDLC control C8 hex, FCF MSB of zero, no FIF bytes and a valid FCS. FAIL otherwise."/>
|
||||
<check name="MRGP01M21" desc="Polled, disconnect after DCN" cond="Confirm DUT disconnects. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6805,7 +6653,7 @@
|
|||
|
||||
<step dir="R" type="CED"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DIS" value="FF C8 01 ..." timeout="60000">
|
||||
<check name="MRGP02M01" desc="DIS exhibits T.4 transmitter ability with password"/>
|
||||
<check name="MRGP02M01" desc="DIS exhibits T.4 transmitter ability with password" cond="Confirm DIS FIF bit 9 T.4 transmitter is 1. Confirm DIS FIF bit 50 is 1. Confirm DIS extend bits are set correctly. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6817,7 +6665,7 @@
|
|||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="TSI" value="FF C0 42 ..."/>
|
||||
<step dir="R" type="HDLC" tag="DCS" value="FF C8 41 ...">
|
||||
<check name="MRGP02M02" desc="Polled, DUT accepts tester's password"/>
|
||||
<check name="MRGP02M02" desc="Polled, DUT accepts tester's password" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
<step dir="R" type="TCF" modem="V.27ter/4800"/>
|
||||
|
@ -6870,7 +6718,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F">
|
||||
<check name="MRGP03M01" desc="Polled, DUT rejects tester's password"/>
|
||||
<check name="MRGP03M01" desc="Polled, DUT rejects tester's password" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6894,7 +6742,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F">
|
||||
<check name="MRGP04M01" desc="Polled, DUT rejects DTC for lack of password"/>
|
||||
<check name="MRGP04M01" desc="Polled, DUT rejects DTC for lack of password" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6909,7 +6757,7 @@
|
|||
|
||||
<step dir="R" type="CED"/>
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DIS" value="FF C8 01 ..." timeout="60000">
|
||||
<check name="MRGP05M01" desc="DIS not exhibit T.4 transmit capability"/>
|
||||
<check name="MRGP05M01" desc="DIS not exhibit T.4 transmit capability" cond="Confirm DIS FI bit 9, T.4 transmitter is 0. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6919,7 +6767,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN" value="FF C8 5F">
|
||||
<check name="MRGP05M02" desc="Polled, DUT rejects DTC for no document available"/>
|
||||
<check name="MRGP05M02" desc="Polled, DUT rejects DTC for no document available" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -6942,7 +6790,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCS+" value="FF C8 C1 ...">
|
||||
<check name="MRGP06M01" desc="Polled, DUT accepts DIS in place of DTC"/>
|
||||
<check name="MRGP06M01" desc="Polled, DUT accepts DIS in place of DTC" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="TCF" modem="V.27ter/4800" timeout="60000"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -6993,7 +6841,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF">
|
||||
<check name="MRGP07M01" desc="Polled, DUT rejects DIS in place of DTC for lackof password"/>
|
||||
<check name="MRGP07M01" desc="Polled, DUT rejects DIS in place of DTC for lack of password" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -7016,7 +6864,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCN+" value="FF C8 DF">
|
||||
<check name="MRGP08M01" desc="Polled, DUT rejects DIS in place of DTC for no document available"/>
|
||||
<check name="MRGP08M01" desc="Polled, DUT rejects DIS in place of DTC for no document available" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
||||
|
@ -7061,7 +6909,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 ...">
|
||||
<check name="ORGP09M01" desc="Reception followed by invited polling transmission"/>
|
||||
<check name="ORGP09M01" desc="Reception followed by invited polling transmission" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="TCF" modem="V.17/14400"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
@ -7123,7 +6971,7 @@
|
|||
<step dir="T" type="POSTAMBLE"/>
|
||||
|
||||
<step dir="R" type="HDLC" modem="V.21" tag="DCS" value="FF C8 41 ...">
|
||||
<check name="ORGP10M01" desc="Reception followed by immediate polling transmission"/>
|
||||
<check name="ORGP10M01" desc="Reception followed by immediate polling transmission" cond="Confirm outcome per execution sequence. FAIL otherwise."/>
|
||||
</step>
|
||||
<step dir="R" type="TCF" modem="V.17/14400"/>
|
||||
<step dir="R" type="SILENCE"/>
|
||||
|
|
|
@ -755,7 +755,7 @@ SPAN_DECLARE(ademco_contactid_receiver_state_t *) ademco_contactid_receiver_init
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (ademco_contactid_receiver_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (ademco_contactid_receiver_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
@ -1090,7 +1090,7 @@ SPAN_DECLARE(ademco_contactid_sender_state_t *) ademco_contactid_sender_init(ade
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (ademco_contactid_sender_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (ademco_contactid_sender_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
|
|
@ -417,7 +417,7 @@ SPAN_DECLARE(dtmf_rx_state_t *) dtmf_rx_init(dtmf_rx_state_t *s,
|
|||
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (dtmf_rx_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (dtmf_rx_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
@ -578,7 +578,7 @@ SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s,
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (dtmf_tx_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (dtmf_tx_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
|
|
@ -116,12 +116,12 @@ SPAN_DECLARE(gsm0610_state_t *) gsm0610_init(gsm0610_state_t *s, int packing)
|
|||
{
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (gsm0610_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (gsm0610_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
}
|
||||
/*endif*/
|
||||
memset((char *) s, '\0', sizeof (gsm0610_state_t));
|
||||
memset((char *) s, '\0', sizeof(gsm0610_state_t));
|
||||
s->nrp = 40;
|
||||
s->packing = packing;
|
||||
return s;
|
||||
|
|
|
@ -605,6 +605,33 @@ static void dump_trie(void)
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
||||
static void trie_recursive_free(trie_node_t *t)
|
||||
{
|
||||
int i;
|
||||
if (t)
|
||||
{
|
||||
if (t->first <= t->last)
|
||||
{
|
||||
for (i = t->first; i <= t->last; i++)
|
||||
trie_recursive_free(t->child_list[i]);
|
||||
}
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void trie_free(trie_t *s)
|
||||
{
|
||||
if(s)
|
||||
{
|
||||
if(s->root)
|
||||
trie_recursive_free(s->root);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
trie_t *s;
|
||||
|
@ -627,6 +654,8 @@ int main(int argc, char *argv[])
|
|||
trie_recursive_build_packed_trie(s->root);
|
||||
|
||||
dump_trie();
|
||||
|
||||
trie_free(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -526,7 +526,7 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
|||
filtered = 0.001599787f*(v1 - s->z15hz_2);
|
||||
s->z15hz_2 = s->z15hz_1;
|
||||
s->z15hz_1 = v1;
|
||||
s->am_level += abs(lfastrintf(filtered)) - (s->am_level >> 8);
|
||||
s->am_level += abs((int) lfastrintf(filtered)) - (s->am_level >> 8);
|
||||
//printf("%9.1f %10.4f %9d %9d\n", famp, filtered, s->am_level, s->channel_level);
|
||||
/* A Cauer notch at 2100Hz, spread just wide enough to meet our detection bandwidth
|
||||
criteria. */
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef __int16 int16_t;
|
|||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
|
||||
#if !defined(INFINITY)
|
||||
#if !defined(INFINITY) && _MSC_VER < 1800
|
||||
#define INFINITY 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include <spandsp/stdbool.h>
|
||||
#endif
|
||||
#include <spandsp/telephony.h>
|
||||
#include <spandsp/alloc.h>
|
||||
#include <spandsp/fast_convert.h>
|
||||
#include <spandsp/logging.h>
|
||||
#include <spandsp/complex.h>
|
||||
|
@ -96,8 +97,6 @@
|
|||
#include <spandsp/modem_connect_tones.h>
|
||||
#include <spandsp/silence_gen.h>
|
||||
#include <spandsp/v8.h>
|
||||
#include <spandsp/v42.h>
|
||||
#include <spandsp/v42bis.h>
|
||||
#include <spandsp/v29rx.h>
|
||||
#include <spandsp/v29tx.h>
|
||||
#include <spandsp/v17rx.h>
|
||||
|
@ -105,9 +104,14 @@
|
|||
#include <spandsp/v22bis.h>
|
||||
#include <spandsp/v27ter_rx.h>
|
||||
#include <spandsp/v27ter_tx.h>
|
||||
#if defined(SPANDSP_SUPPORT_V32BIS)
|
||||
#include <spandsp/v32bis.h>
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_V34)
|
||||
#include <spandsp/v34.h>
|
||||
#endif
|
||||
#include <spandsp/v42.h>
|
||||
#include <spandsp/v42bis.h>
|
||||
#include <spandsp/v18.h>
|
||||
#include <spandsp/timezone.h>
|
||||
#include <spandsp/t4_rx.h>
|
||||
|
@ -125,6 +129,7 @@
|
|||
#include <spandsp/t30_logging.h>
|
||||
#include <spandsp/t35.h>
|
||||
#include <spandsp/at_interpreter.h>
|
||||
#include <spandsp/data_modems.h>
|
||||
#include <spandsp/fax_modems.h>
|
||||
#include <spandsp/fax.h>
|
||||
#include <spandsp/t38_core.h>
|
||||
|
|
|
@ -173,7 +173,6 @@ SPAN_DECLARE(void) at_set_class1_handler(at_state_t *s, at_class1_handler_t hand
|
|||
\return A pointer to the logging context */
|
||||
SPAN_DECLARE(logging_state_t *) at_get_logging_state(at_state_t *s);
|
||||
|
||||
|
||||
SPAN_DECLARE(void) at_set_modem_control_handler(at_state_t *s,
|
||||
at_modem_control_handler_t modem_control_handler,
|
||||
void *modem_control_user_data);
|
||||
|
|
|
@ -53,13 +53,13 @@ static __inline__ int top_bit(uint32_t bits)
|
|||
: [res] "=&r" (res)
|
||||
: [bits] "rm" (bits));
|
||||
return res;
|
||||
#elif defined(__GNUC__x) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
|
||||
#elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
|
||||
int res;
|
||||
|
||||
__asm__("clz %[res], %[bits]"
|
||||
: [res] "=r" (res)
|
||||
: [bits] "r" (bits));
|
||||
return res;
|
||||
return 31 - res;
|
||||
#elif defined(__ppc__) || defined(__powerpc__)
|
||||
int res;
|
||||
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include "mmx.h"
|
||||
#endif
|
||||
|
||||
#include "alloc.h"
|
||||
|
||||
/*!
|
||||
16 bit integer FIR descriptor. This defines the working state for a single
|
||||
instance of an FIR filter using 16 bit integer coefficients.
|
||||
|
|
|
@ -111,7 +111,6 @@ That's it!
|
|||
*/
|
||||
typedef struct plc_state_s plc_state_t;
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -34,15 +34,27 @@
|
|||
/*! Audio time scaling descriptor. */
|
||||
struct time_scale_state_s
|
||||
{
|
||||
/*! \brief The sample rate of both the incoming and outgoing signal */
|
||||
int sample_rate;
|
||||
/*! \brief The minimum pitch we will search for, in samples per cycle */
|
||||
int min_pitch;
|
||||
/*! \brief The maximum pitch we will search for, in samples per cycle */
|
||||
int max_pitch;
|
||||
int buf_len;
|
||||
/*! \brief The playout speed, as the fraction output time/input time.
|
||||
(i.e. >1.0 == slow down, 1.0 == no speed change, <1.0 == speed up) */
|
||||
float playout_rate;
|
||||
/*! \brief */
|
||||
double rcomp;
|
||||
/*! \brief The fractional sample adjustment, to allow for non-integer values of lcp. */
|
||||
double rate_nudge;
|
||||
int fill;
|
||||
/*! \brief */
|
||||
int lcp;
|
||||
/*! \brief The active length of buf at the current sample rate. */
|
||||
int buf_len;
|
||||
/*! \brief The number of samples in buf */
|
||||
int fill;
|
||||
/*! \brief Buffer for residual samples kept over from one call of time_scale() to
|
||||
the next. */
|
||||
int16_t buf[TIME_SCALE_BUF_LEN];
|
||||
};
|
||||
|
||||
|
|
|
@ -28,11 +28,33 @@
|
|||
#if !defined(_SPANDSP_T30_API_H_)
|
||||
#define _SPANDSP_T30_API_H_
|
||||
|
||||
enum
|
||||
{
|
||||
T33_NONE = 0,
|
||||
T33_SST = 1,
|
||||
T33_EXT = 2
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! Get the specified field from a T.33 formatted string.
|
||||
\brief Get the specified field from a T.33 formatted string.
|
||||
\param field The extracted field.
|
||||
\param t33 The T.33 formatted string.
|
||||
\param field_no The field number to extract. The first field is 0.
|
||||
\return The extracted field type. -1 indicates a over length or badly formatted field. */
|
||||
SPAN_DECLARE(int) t33_sub_address_extract_field(uint8_t field[21], const uint8_t t33[], int field_no);
|
||||
|
||||
/*! Append the specified field to a T.33 formatted string.
|
||||
\brief Append the specified field to a T.33 formatted string.
|
||||
\param t33 The T.33 formatted string.
|
||||
\param field The field to be adppended.
|
||||
\param type The type of the field to be appended. */
|
||||
SPAN_DECLARE(void) t33_sub_address_add_field(uint8_t t33[], const uint8_t field[], int type);
|
||||
|
||||
/*! Set the transmitted NSF frame to be associated with a T.30 context.
|
||||
\brief Set the transmitted NSF frame to be associated with a T.30 context.
|
||||
\param s The T.30 context.
|
||||
|
|
|
@ -62,25 +62,6 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
/*! Initialise a time scale context. This must be called before the first
|
||||
use of the context, to initialise its contents.
|
||||
\brief Initialise a time scale context.
|
||||
\param s The time scale context.
|
||||
\param sample_rate The sample rate of the signal.
|
||||
\param playout_rate The ratio between the output speed and the input speed.
|
||||
\return A pointer to the context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sample_rate, float playout_rate);
|
||||
|
||||
/*! \brief Release a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_release(time_scale_state_t *s);
|
||||
|
||||
/*! \brief Free a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_free(time_scale_state_t *s);
|
||||
|
||||
/*! Change the time scale rate.
|
||||
\brief Change the time scale rate.
|
||||
\param s The time scale context.
|
||||
|
@ -108,6 +89,27 @@ SPAN_DECLARE(int) time_scale_max_output_len(time_scale_state_t *s, int input_len
|
|||
*/
|
||||
SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[], int len);
|
||||
|
||||
SPAN_DECLARE(int) time_scale_flush(time_scale_state_t *s, int16_t out[]);
|
||||
|
||||
/*! Initialise a time scale context. This must be called before the first
|
||||
use of the context, to initialise its contents.
|
||||
\brief Initialise a time scale context.
|
||||
\param s The time scale context.
|
||||
\param sample_rate The sample rate of the signal.
|
||||
\param playout_rate The ratio between the output speed and the input speed.
|
||||
\return A pointer to the context, or NULL if there was a problem. */
|
||||
SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sample_rate, float playout_rate);
|
||||
|
||||
/*! \brief Release a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_release(time_scale_state_t *s);
|
||||
|
||||
/*! \brief Free a time scale context.
|
||||
\param s The time scale context.
|
||||
\return 0 for OK, else -1. */
|
||||
SPAN_DECLARE(int) time_scale_free(time_scale_state_t *s);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -95,6 +95,65 @@
|
|||
|
||||
#include "t30_local.h"
|
||||
|
||||
SPAN_DECLARE(int) t33_sub_address_extract_field(uint8_t num[21], const uint8_t t33[], int field_no)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
int ch;
|
||||
int type;
|
||||
|
||||
num[0] = '\0';
|
||||
k = 0;
|
||||
for (i = 0; t33[i]; )
|
||||
{
|
||||
if (k++ == field_no)
|
||||
{
|
||||
ch = t33[i++];
|
||||
j = 0;
|
||||
if (ch != '#')
|
||||
{
|
||||
num[j++] = ch;
|
||||
type = T33_EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = T33_SST;
|
||||
}
|
||||
while (t33[i])
|
||||
{
|
||||
ch = t33[i++];
|
||||
if (ch == '#')
|
||||
break;
|
||||
num[j++] = ch;
|
||||
if (j >= 20)
|
||||
return -1;
|
||||
}
|
||||
num[j] = '\0';
|
||||
return type;
|
||||
}
|
||||
/* Skip this field */
|
||||
i++;
|
||||
while (t33[i])
|
||||
{
|
||||
if (t33[i++] == '#')
|
||||
break;
|
||||
}
|
||||
}
|
||||
return T33_NONE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(void) t33_sub_address_add_field(uint8_t t33[], const uint8_t field[], int type)
|
||||
{
|
||||
if (t33[0] != '\0')
|
||||
strcat((char *) t33, "#");
|
||||
if (type == T33_SST)
|
||||
strcat((char *) t33, "#");
|
||||
strcat((char *) t33, (const char *) field);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) t30_set_tx_ident(t30_state_t *s, const char *id)
|
||||
{
|
||||
if (id == NULL)
|
||||
|
|
|
@ -2994,7 +2994,7 @@ SPAN_DECLARE(t31_state_t *) t31_init(t31_state_t *s,
|
|||
alloced = false;
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (t31_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (t31_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
alloced = true;
|
||||
|
|
|
@ -662,8 +662,8 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
|||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
/* If we are processing a message from the modem side, the contents determine the fast receive modem.
|
||||
we are to use. If it comes from the T.38 side the contents do not. */
|
||||
/* If we are processing a message from the modem side, the contents determine the fast
|
||||
receive modem we are to use. If it comes from the T.38 side the contents do not. */
|
||||
s->core.fast_bit_rate = modem_codes[i].bit_rate;
|
||||
if (from_modem)
|
||||
s->core.fast_rx_modem = modem_codes[i].modem_type;
|
||||
|
@ -700,8 +700,9 @@ static void monitor_control_messages(t38_gateway_state_t *s,
|
|||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
/* If we are processing a message from the modem side, the contents determine the fast receive modem.
|
||||
we are to use. If it comes from the T.38 side the contents do not. */
|
||||
/* If we are processing a DCS message from the modem side, the contents determine the fast
|
||||
receive modem we are to use. If it comes from the T.38 side the contents do not. For a
|
||||
DTC message this is reversed. */
|
||||
s->core.fast_bit_rate = modem_codes[i].bit_rate;
|
||||
if ((buf[2] == T30_DTC && !from_modem) || (buf[2] != T30_DTC && from_modem))
|
||||
s->core.fast_rx_modem = modem_codes[i].modem_type;
|
||||
|
|
|
@ -78,12 +78,15 @@ static __inline__ int amdf_pitch(int min_pitch, int max_pitch, int16_t amp[], in
|
|||
acc = 0;
|
||||
for (j = 0; j < len; j++)
|
||||
acc += abs(amp[i + j] - amp[j]);
|
||||
/*endfor*/
|
||||
if (acc < min_acc)
|
||||
{
|
||||
min_acc = acc;
|
||||
pitch = i;
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endfor*/
|
||||
return pitch;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -99,9 +102,10 @@ static __inline__ void overlap_add(int16_t amp1[], int16_t amp2[], int len)
|
|||
for (i = 0; i < len; i++)
|
||||
{
|
||||
/* TODO: saturate */
|
||||
amp2[i] = (int16_t) ((float) amp1[i]*(1.0f - weight) + (float) amp2[i]*weight);
|
||||
amp1[i] = (int16_t) ((float) amp2[i]*(1.0f - weight) + (float) amp1[i]*weight);
|
||||
weight += step;
|
||||
}
|
||||
/*endfor*/
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -130,16 +134,166 @@ SPAN_DECLARE(int) time_scale_rate(time_scale_state_t *s, float playout_rate)
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[], int len)
|
||||
{
|
||||
double lcpf;
|
||||
int pitch;
|
||||
int out_len;
|
||||
int in_len;
|
||||
int k;
|
||||
|
||||
out_len = 0;
|
||||
in_len = 0;
|
||||
|
||||
if (s->playout_rate == 1.0f)
|
||||
{
|
||||
vec_copyi16(out, in, len);
|
||||
return len;
|
||||
}
|
||||
/*endif*/
|
||||
|
||||
/* Top up the buffer */
|
||||
if (s->fill + len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(&s->buf[s->fill], in, len);
|
||||
s->fill += len;
|
||||
return 0;
|
||||
}
|
||||
/*endif*/
|
||||
k = s->buf_len - s->fill;
|
||||
vec_copyi16(&s->buf[s->fill], in, k);
|
||||
in_len += k;
|
||||
s->fill = s->buf_len;
|
||||
while (s->fill == s->buf_len)
|
||||
{
|
||||
while (s->lcp >= s->buf_len)
|
||||
{
|
||||
vec_copyi16(&out[out_len], s->buf, s->buf_len);
|
||||
out_len += s->buf_len;
|
||||
if (len - in_len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(s->buf, &in[in_len], len - in_len);
|
||||
s->fill = len - in_len;
|
||||
s->lcp -= s->buf_len;
|
||||
return out_len;
|
||||
}
|
||||
/*endif*/
|
||||
vec_copyi16(s->buf, &in[in_len], s->buf_len);
|
||||
in_len += s->buf_len;
|
||||
s->lcp -= s->buf_len;
|
||||
}
|
||||
/*endwhile*/
|
||||
if (s->lcp > 0)
|
||||
{
|
||||
vec_copyi16(&out[out_len], s->buf, s->lcp);
|
||||
out_len += s->lcp;
|
||||
vec_movei16(s->buf, &s->buf[s->lcp], s->buf_len - s->lcp);
|
||||
if (len - in_len < s->lcp)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(&s->buf[s->buf_len - s->lcp], &in[in_len], len - in_len);
|
||||
s->fill = s->buf_len - s->lcp + len - in_len;
|
||||
s->lcp = 0;
|
||||
return out_len;
|
||||
}
|
||||
/*endif*/
|
||||
vec_copyi16(&s->buf[s->buf_len - s->lcp], &in[in_len], s->lcp);
|
||||
in_len += s->lcp;
|
||||
s->lcp = 0;
|
||||
}
|
||||
/*endif*/
|
||||
pitch = amdf_pitch(s->min_pitch, s->max_pitch, s->buf, s->min_pitch);
|
||||
lcpf = (double) pitch*s->rcomp;
|
||||
/* Nudge around to compensate for fractional samples */
|
||||
s->lcp = (int) lcpf;
|
||||
/* Note that s->lcp and lcpf are not the same, as lcpf has a fractional part, and s->lcp doesn't */
|
||||
s->rate_nudge += s->lcp - lcpf;
|
||||
if (s->rate_nudge >= 0.5f)
|
||||
{
|
||||
s->lcp--;
|
||||
s->rate_nudge -= 1.0f;
|
||||
}
|
||||
else if (s->rate_nudge <= -0.5f)
|
||||
{
|
||||
s->lcp++;
|
||||
s->rate_nudge += 1.0f;
|
||||
}
|
||||
/*endif*/
|
||||
if (s->playout_rate < 1.0f)
|
||||
{
|
||||
/* Speed up - drop a pitch period of signal */
|
||||
overlap_add(&s->buf[pitch], s->buf, pitch);
|
||||
vec_copyi16(&s->buf[pitch], &s->buf[2*pitch], s->buf_len - 2*pitch);
|
||||
if (len - in_len < pitch)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
/* Save the residual signal for next time. */
|
||||
vec_copyi16(&s->buf[s->buf_len - pitch], &in[in_len], len - in_len);
|
||||
s->fill += (len - in_len - pitch);
|
||||
return out_len;
|
||||
}
|
||||
/*endif*/
|
||||
vec_copyi16(&s->buf[s->buf_len - pitch], &in[in_len], pitch);
|
||||
in_len += pitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Slow down - insert a pitch period of signal */
|
||||
vec_copyi16(&out[out_len], s->buf, pitch);
|
||||
out_len += pitch;
|
||||
overlap_add(s->buf, &s->buf[pitch], pitch);
|
||||
}
|
||||
/*endif*/
|
||||
}
|
||||
/*endwhile*/
|
||||
return out_len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_flush(time_scale_state_t *s, int16_t out[])
|
||||
{
|
||||
int len;
|
||||
int pad;
|
||||
|
||||
if (s->playout_rate < 1.0f)
|
||||
return 0;
|
||||
/*endif*/
|
||||
vec_copyi16(out, s->buf, s->fill);
|
||||
len = s->fill;
|
||||
if (s->playout_rate > 1.0f)
|
||||
{
|
||||
pad = s->fill*(s->playout_rate - 1.0f);
|
||||
vec_zeroi16(&out[len], pad);
|
||||
len += pad;
|
||||
}
|
||||
/*endif*/
|
||||
s->fill = 0;
|
||||
return len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_max_output_len(time_scale_state_t *s, int input_len)
|
||||
{
|
||||
return (int) (input_len*s->playout_rate + s->min_pitch + 1);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sample_rate, float playout_rate)
|
||||
{
|
||||
bool alloced;
|
||||
|
||||
if (sample_rate > TIME_SCALE_MAX_SAMPLE_RATE)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
alloced = false;
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (time_scale_state_t *) span_alloc(sizeof (*s))) == NULL)
|
||||
if ((s = (time_scale_state_t *) span_alloc(sizeof(*s))) == NULL)
|
||||
return NULL;
|
||||
/*endif*/
|
||||
alloced = true;
|
||||
|
@ -153,6 +307,7 @@ SPAN_DECLARE(time_scale_state_t *) time_scale_init(time_scale_state_t *s, int sa
|
|||
{
|
||||
if (alloced)
|
||||
span_free(s);
|
||||
/*endif*/
|
||||
return NULL;
|
||||
}
|
||||
/*endif*/
|
||||
|
@ -175,118 +330,4 @@ SPAN_DECLARE(int) time_scale_free(time_scale_state_t *s)
|
|||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale(time_scale_state_t *s, int16_t out[], int16_t in[], int len)
|
||||
{
|
||||
double lcpf;
|
||||
int pitch;
|
||||
int out_len;
|
||||
int in_len;
|
||||
int k;
|
||||
|
||||
out_len = 0;
|
||||
in_len = 0;
|
||||
|
||||
/* Top up the buffer */
|
||||
if (s->fill + len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
vec_copyi16(&s->buf[s->fill], in, len);
|
||||
s->fill += len;
|
||||
return out_len;
|
||||
}
|
||||
k = s->buf_len - s->fill;
|
||||
vec_copyi16(&s->buf[s->fill], in, k);
|
||||
in_len += k;
|
||||
s->fill = s->buf_len;
|
||||
while (s->fill == s->buf_len)
|
||||
{
|
||||
while (s->lcp >= s->buf_len)
|
||||
{
|
||||
vec_copyi16(&out[out_len], s->buf, s->buf_len);
|
||||
out_len += s->buf_len;
|
||||
if (len - in_len < s->buf_len)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
vec_copyi16(s->buf, &in[in_len], len - in_len);
|
||||
s->fill = len - in_len;
|
||||
s->lcp -= s->buf_len;
|
||||
return out_len;
|
||||
}
|
||||
vec_copyi16(s->buf, &in[in_len], s->buf_len);
|
||||
in_len += s->buf_len;
|
||||
s->lcp -= s->buf_len;
|
||||
}
|
||||
if (s->lcp > 0)
|
||||
{
|
||||
vec_copyi16(&out[out_len], s->buf, s->lcp);
|
||||
out_len += s->lcp;
|
||||
vec_movei16(s->buf, &s->buf[s->lcp], s->buf_len - s->lcp);
|
||||
if (len - in_len < s->lcp)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
vec_copyi16(&s->buf[s->buf_len - s->lcp], &in[in_len], len - in_len);
|
||||
s->fill = s->buf_len - s->lcp + len - in_len;
|
||||
s->lcp = 0;
|
||||
return out_len;
|
||||
}
|
||||
vec_copyi16(&s->buf[s->buf_len - s->lcp], &in[in_len], s->lcp);
|
||||
in_len += s->lcp;
|
||||
s->lcp = 0;
|
||||
}
|
||||
if (s->playout_rate == 1.0f)
|
||||
{
|
||||
s->lcp = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = amdf_pitch(s->min_pitch, s->max_pitch, s->buf, s->min_pitch);
|
||||
lcpf = (double) pitch*s->rcomp;
|
||||
/* Nudge around to compensate for fractional samples */
|
||||
s->lcp = (int) lcpf;
|
||||
/* Note that s->lcp and lcpf are not the same, as lcpf has a fractional part, and s->lcp doesn't */
|
||||
s->rate_nudge += s->lcp - lcpf;
|
||||
if (s->rate_nudge >= 0.5f)
|
||||
{
|
||||
s->lcp--;
|
||||
s->rate_nudge -= 1.0f;
|
||||
}
|
||||
else if (s->rate_nudge <= -0.5f)
|
||||
{
|
||||
s->lcp++;
|
||||
s->rate_nudge += 1.0f;
|
||||
}
|
||||
if (s->playout_rate < 1.0f)
|
||||
{
|
||||
/* Speed up - drop a chunk of data */
|
||||
overlap_add(s->buf, &s->buf[pitch], pitch);
|
||||
vec_copyi16(&s->buf[pitch], &s->buf[2*pitch], s->buf_len - 2*pitch);
|
||||
if (len - in_len < pitch)
|
||||
{
|
||||
/* Cannot continue without more samples */
|
||||
vec_copyi16(&s->buf[s->buf_len - pitch], &in[in_len], len - in_len);
|
||||
s->fill += (len - in_len - pitch);
|
||||
return out_len;
|
||||
}
|
||||
vec_copyi16(&s->buf[s->buf_len - pitch], &in[in_len], pitch);
|
||||
in_len += pitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Slow down - insert a chunk of data */
|
||||
vec_copyi16(&out[out_len], s->buf, pitch);
|
||||
out_len += pitch;
|
||||
overlap_add(&s->buf[pitch], s->buf, pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out_len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) time_scale_max_output_len(time_scale_state_t *s, int input_len)
|
||||
{
|
||||
return (int) (input_len*s->playout_rate + s->min_pitch + 1);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
|
|
|
@ -579,7 +579,7 @@ static __inline__ void process_half_baud(v22bis_state_t *s, const complexf_t *sa
|
|||
s->rx.gardner_step = 32;
|
||||
break;
|
||||
case V22BIS_RX_TRAINING_STAGE_UNSCRAMBLED_ONES:
|
||||
/* Calling modem only */
|
||||
/* Calling modem only. */
|
||||
/* The calling modem should initially receive unscrambled ones at 1200bps */
|
||||
target = &v22bis_constellation[nearest];
|
||||
track_carrier(s, &z, target);
|
||||
|
@ -621,7 +621,7 @@ static __inline__ void process_half_baud(v22bis_state_t *s, const complexf_t *sa
|
|||
}
|
||||
break;
|
||||
case V22BIS_RX_TRAINING_STAGE_UNSCRAMBLED_ONES_SUSTAINING:
|
||||
/* Calling modem only */
|
||||
/* Calling modem only. */
|
||||
/* Wait for the end of the unscrambled ones at 1200bps. */
|
||||
target = &v22bis_constellation[nearest];
|
||||
track_carrier(s, &z, target);
|
||||
|
@ -682,7 +682,7 @@ static __inline__ void process_half_baud(v22bis_state_t *s, const complexf_t *sa
|
|||
/* The transmit side needs to sustain the scrambled ones for a timed period. */
|
||||
s->tx.training_count = 0;
|
||||
s->tx.training = V22BIS_TX_TRAINING_STAGE_TIMED_S11;
|
||||
/* Normal reception starts immediately */
|
||||
/* Normal reception starts immediately. */
|
||||
s->rx.training = V22BIS_RX_TRAINING_STAGE_NORMAL_OPERATION;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
s->rx.carrier_track_i = 8;
|
||||
|
|
|
@ -149,7 +149,7 @@ static void rx_callback(void *user_data, const ademco_contactid_report_t *report
|
|||
printf(" Event %X\n", report->xyz);
|
||||
printf(" Group/partition %X\n", report->gg);
|
||||
printf(" User/Zone information %X\n", report->ccc);
|
||||
if (memcmp(&reports[reports_entry], report, sizeof (*report)))
|
||||
if (memcmp(&reports[reports_entry], report, sizeof(*report)))
|
||||
{
|
||||
printf("Report mismatch\n");
|
||||
exit(2);
|
||||
|
|
|
@ -77,7 +77,7 @@ int main(int argc, char *argv[])
|
|||
total = 0.0;
|
||||
if ((noise_source = awgn_init_dbm0(NULL, idum, (float) j)) == NULL)
|
||||
{
|
||||
printf("Failed to allocation AWGN source\n");
|
||||
printf("Failed to allocate AWGN source\n");
|
||||
exit(2);
|
||||
}
|
||||
total_samples = 1000000;
|
||||
|
@ -114,7 +114,7 @@ int main(int argc, char *argv[])
|
|||
clip_low = 0;
|
||||
if ((noise_source = awgn_init_dbm0(NULL, idum, -15.0)) == NULL)
|
||||
{
|
||||
printf("Failed to allocation AWGN source\n");
|
||||
printf("Failed to allocate AWGN source\n");
|
||||
exit(2);
|
||||
}
|
||||
total_samples = 10000000;
|
||||
|
|
|
@ -232,7 +232,11 @@ static int check_rx_dcs(const uint8_t *msg, int len)
|
|||
image_width = widths[(dcs_frame[8] & DISBIT3) ? 2 : 1][dcs_frame[5] & (DISBIT2 | DISBIT1)];
|
||||
|
||||
/* Check which compression we will use. */
|
||||
if ((dcs_frame[6] & DISBIT7))
|
||||
if ((dcs_frame[12] & DISBIT7))
|
||||
line_encoding = T4_COMPRESSION_T85_L0;
|
||||
else if ((dcs_frame[12] & DISBIT6))
|
||||
line_encoding = T4_COMPRESSION_T85;
|
||||
else if ((dcs_frame[6] & DISBIT7))
|
||||
line_encoding = T4_COMPRESSION_T6;
|
||||
else if ((dcs_frame[4] & DISBIT8))
|
||||
line_encoding = T4_COMPRESSION_T4_2D;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#if defined(HAVE_TGMATH_H)
|
||||
#include <tgmath.h>
|
||||
#endif
|
||||
|
@ -59,10 +60,102 @@
|
|||
|
||||
#include "spandsp.h"
|
||||
|
||||
#include "fax_utils.h"
|
||||
#include "fax_tester.h"
|
||||
|
||||
#define HDLC_FRAMING_OK_THRESHOLD 5
|
||||
|
||||
extern const char *output_tiff_file_name;
|
||||
|
||||
struct xml_node_parms_s
|
||||
{
|
||||
xmlChar *dir;
|
||||
xmlChar *type;
|
||||
xmlChar *modem;
|
||||
xmlChar *value;
|
||||
xmlChar *tag;
|
||||
xmlChar *bad_rows;
|
||||
xmlChar *crc_error;
|
||||
xmlChar *pattern;
|
||||
xmlChar *timein;
|
||||
xmlChar *timeout;
|
||||
xmlChar *min_bits;
|
||||
xmlChar *frame_size;
|
||||
xmlChar *block;
|
||||
xmlChar *compression;
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
const char *tag;
|
||||
int code;
|
||||
} t30_status[] =
|
||||
{
|
||||
{"OK", T30_ERR_OK},
|
||||
{"CEDTONE", T30_ERR_CEDTONE},
|
||||
{"T0_EXPIRED", T30_ERR_T0_EXPIRED},
|
||||
{"T1_EXPIRED", T30_ERR_T1_EXPIRED},
|
||||
{"T3_EXPIRED", T30_ERR_T3_EXPIRED},
|
||||
{"HDLC_CARRIER", T30_ERR_HDLC_CARRIER},
|
||||
{"CANNOT_TRAIN", T30_ERR_CANNOT_TRAIN},
|
||||
{"OPER_INT_FAIL", T30_ERR_OPER_INT_FAIL},
|
||||
{"INCOMPATIBLE", T30_ERR_INCOMPATIBLE},
|
||||
{"RX_INCAPABLE", T30_ERR_RX_INCAPABLE},
|
||||
{"TX_INCAPABLE", T30_ERR_TX_INCAPABLE},
|
||||
{"NORESSUPPORT", T30_ERR_NORESSUPPORT},
|
||||
{"NOSIZESUPPORT", T30_ERR_NOSIZESUPPORT},
|
||||
{"UNEXPECTED", T30_ERR_UNEXPECTED},
|
||||
{"TX_BADDCS", T30_ERR_TX_BADDCS},
|
||||
{"TX_BADPG", T30_ERR_TX_BADPG},
|
||||
{"TX_ECMPHD", T30_ERR_TX_ECMPHD},
|
||||
{"TX_GOTDCN", T30_ERR_TX_GOTDCN},
|
||||
{"TX_INVALRSP", T30_ERR_TX_INVALRSP},
|
||||
{"TX_NODIS", T30_ERR_TX_NODIS},
|
||||
{"TX_PHBDEAD", T30_ERR_TX_PHBDEAD},
|
||||
{"TX_PHDDEAD", T30_ERR_TX_PHDDEAD},
|
||||
{"TX_T5EXP", T30_ERR_TX_T5EXP},
|
||||
{"RX_ECMPHD", T30_ERR_RX_ECMPHD},
|
||||
{"RX_GOTDCS", T30_ERR_RX_GOTDCS},
|
||||
{"RX_INVALCMD", T30_ERR_RX_INVALCMD},
|
||||
{"RX_NOCARRIER", T30_ERR_RX_NOCARRIER},
|
||||
{"RX_NOEOL", T30_ERR_RX_NOEOL},
|
||||
{"RX_NOFAX", T30_ERR_RX_NOFAX},
|
||||
{"RX_T2EXPDCN", T30_ERR_RX_T2EXPDCN},
|
||||
{"RX_T2EXPD", T30_ERR_RX_T2EXPD},
|
||||
{"RX_T2EXPFAX", T30_ERR_RX_T2EXPFAX},
|
||||
{"RX_T2EXPMPS", T30_ERR_RX_T2EXPMPS},
|
||||
{"RX_T2EXPRR", T30_ERR_RX_T2EXPRR},
|
||||
{"RX_T2EXP", T30_ERR_RX_T2EXP},
|
||||
{"RX_DCNWHY", T30_ERR_RX_DCNWHY},
|
||||
{"RX_DCNDATA", T30_ERR_RX_DCNDATA},
|
||||
{"RX_DCNFAX", T30_ERR_RX_DCNFAX},
|
||||
{"RX_DCNPHD", T30_ERR_RX_DCNPHD},
|
||||
{"RX_DCNRRD", T30_ERR_RX_DCNRRD},
|
||||
{"RX_DCNNORTN", T30_ERR_RX_DCNNORTN},
|
||||
{"FILEERROR", T30_ERR_FILEERROR},
|
||||
{"NOPAGE", T30_ERR_NOPAGE},
|
||||
{"BADTIFF", T30_ERR_BADTIFF},
|
||||
{"BADPAGE", T30_ERR_BADPAGE},
|
||||
{"BADTAG", T30_ERR_BADTAG},
|
||||
{"BADTIFFHDR", T30_ERR_BADTIFFHDR},
|
||||
{"NOMEM", T30_ERR_NOMEM},
|
||||
{"RETRYDCN", T30_ERR_RETRYDCN},
|
||||
{"CALLDROPPED", T30_ERR_CALLDROPPED},
|
||||
{"NOPOLL", T30_ERR_NOPOLL},
|
||||
{"IDENT_UNACCEPTABLE", T30_ERR_IDENT_UNACCEPTABLE},
|
||||
{"SUB_UNACCEPTABLE", T30_ERR_SUB_UNACCEPTABLE},
|
||||
{"SEP_UNACCEPTABLE", T30_ERR_SEP_UNACCEPTABLE},
|
||||
{"PSA_UNACCEPTABLE", T30_ERR_PSA_UNACCEPTABLE},
|
||||
{"SID_UNACCEPTABLE", T30_ERR_SID_UNACCEPTABLE},
|
||||
{"PWD_UNACCEPTABLE", T30_ERR_PWD_UNACCEPTABLE},
|
||||
{"TSA_UNACCEPTABLE", T30_ERR_TSA_UNACCEPTABLE},
|
||||
{"IRA_UNACCEPTABLE", T30_ERR_IRA_UNACCEPTABLE},
|
||||
{"CIA_UNACCEPTABLE", T30_ERR_CIA_UNACCEPTABLE},
|
||||
{"ISP_UNACCEPTABLE", T30_ERR_ISP_UNACCEPTABLE},
|
||||
{"CSA_UNACCEPTABLE", T30_ERR_CSA_UNACCEPTABLE},
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
static void timer_update(faxtester_state_t *s, int len)
|
||||
{
|
||||
s->timer += len;
|
||||
|
|
|
@ -90,7 +90,7 @@ uint8_t unpacked[MAX_TEST_VECTOR_LEN];
|
|||
uint8_t xlaw[MAX_TEST_VECTOR_LEN];
|
||||
|
||||
/*
|
||||
Table 4 - V Reset and homing sequences for u-law
|
||||
Table 4 - Reset and homing sequences for u-law
|
||||
Normal I-input Overload
|
||||
Algorithm Input Intermediate Output Input Output Input Intermediate Output
|
||||
(PCM) (ADPCM) (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM)
|
||||
|
@ -108,7 +108,7 @@ Algorithm Input Intermediate Output Input Output Input
|
|||
HN40FM.I HN40FM.O HI40FM.O HV40FM.I HV40FM.O
|
||||
|
||||
|
||||
Table 5 - V Reset and homing sequences for A-law
|
||||
Table 5 - Reset and homing sequences for A-law
|
||||
Normal I-input Overload
|
||||
Algorithm Input Intermediate Output Input Output Input Intermediate Output
|
||||
(PCM) (ADPCM) (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM)
|
||||
|
|
|
@ -275,7 +275,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
oki_adpcm_free(oki_enc_state);
|
||||
if (sf_close_telephony(inhandle))
|
||||
{
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
#include "spandsp.h"
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
#include <tif_dir.h>
|
||||
#endif
|
||||
|
||||
|
@ -157,7 +157,7 @@ int main(int argc, char *argv[])
|
|||
logging = span_log_init(NULL, SPAN_LOG_FLOW, "T.42");
|
||||
#endif
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
TIFF_FX_init();
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
#include "spandsp.h"
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
#include <tif_dir.h>
|
||||
#endif
|
||||
|
||||
|
@ -63,7 +63,7 @@ typedef struct
|
|||
int ptr;
|
||||
} packer_t;
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
/* TIFF-FX related extensions to the tag set supported by libtiff */
|
||||
static const TIFFFieldInfo tiff_fx_tiff_field_info[] =
|
||||
{
|
||||
|
@ -184,7 +184,7 @@ int write_file(meta_t *meta, int page, const uint8_t buf[])
|
|||
uint8_t *out_buf;
|
||||
uint8_t *out_buf2;
|
||||
packer_t packer;
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
toff_t diroff;
|
||||
#endif
|
||||
|
||||
|
@ -222,7 +222,7 @@ int write_file(meta_t *meta, int page, const uint8_t buf[])
|
|||
TIFFSetField(tif, TIFFTAG_MAKE, "soft-switch.org");
|
||||
TIFFSetField(tif, TIFFTAG_MODEL, "spandsp");
|
||||
TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, "i7.coppice.org");
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
/* Make space for this to be filled in later */
|
||||
TIFFSetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, 0);
|
||||
#endif
|
||||
|
@ -310,7 +310,7 @@ int write_file(meta_t *meta, int page, const uint8_t buf[])
|
|||
if (!TIFFWriteDirectory(tif))
|
||||
printf("Failed to write directory.\n");
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
if (!TIFFCreateCustomDirectory(tif, &tiff_fx_field_array))
|
||||
{
|
||||
TIFFSetField(tif, TIFFTAG_PROFILETYPE, PROFILETYPE_G3_FAX);
|
||||
|
@ -337,7 +337,7 @@ int write_file(meta_t *meta, int page, const uint8_t buf[])
|
|||
|
||||
int read_file(meta_t *meta, int page)
|
||||
{
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
static const char *tiff_fx_fax_profiles[] =
|
||||
{
|
||||
"???",
|
||||
|
@ -419,7 +419,7 @@ int read_file(meta_t *meta, int page)
|
|||
meta->bmax = 0.0f;
|
||||
break;
|
||||
}
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
if (TIFFGetField(tif, TIFFTAG_DECODE, &parm16, &fl_parms))
|
||||
{
|
||||
meta->lmin = fl_parms[0];
|
||||
|
@ -432,7 +432,7 @@ int read_file(meta_t *meta, int page)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
printf("Trying to get global parameters\n");
|
||||
if (TIFFGetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, &diroff))
|
||||
{
|
||||
|
@ -891,7 +891,7 @@ int main(int argc, char *argv[])
|
|||
meta_t meta;
|
||||
int output_compression;
|
||||
int page_no;
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
toff_t diroff;
|
||||
#endif
|
||||
|
||||
|
@ -900,7 +900,7 @@ int main(int argc, char *argv[])
|
|||
destination_file = OUT_FILE_NAME;
|
||||
output_compression = (argc > 2) ? atoi(argv[2]) : COMPRESSION_CCITT_T6;
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
TIFF_FX_init();
|
||||
#endif
|
||||
|
||||
|
@ -1305,7 +1305,7 @@ int main(int argc, char *argv[])
|
|||
TIFFSetField(tif, TIFFTAG_MAKE, "soft-switch.org");
|
||||
TIFFSetField(tif, TIFFTAG_MODEL, "spandsp");
|
||||
TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, "i7.coppice.org");
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
/* Make space for this to be filled in later */
|
||||
TIFFSetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, 0);
|
||||
#endif
|
||||
|
@ -1379,7 +1379,7 @@ int main(int argc, char *argv[])
|
|||
if (!TIFFWriteDirectory(tif))
|
||||
printf("Failed to write directory.\n");
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
|
||||
if (!TIFFCreateCustomDirectory(tif, &tiff_fx_field_array))
|
||||
{
|
||||
TIFFSetField(tif, TIFFTAG_PROFILETYPE, PROFILETYPE_G3_FAX);
|
||||
|
|
|
@ -65,6 +65,8 @@ int main(int argc, char *argv[])
|
|||
int out_frames;
|
||||
int count;
|
||||
int max;
|
||||
int samples_in;
|
||||
int samples_out;
|
||||
time_scale_state_t state;
|
||||
float rate;
|
||||
float sample_rate;
|
||||
|
@ -129,9 +131,19 @@ int main(int argc, char *argv[])
|
|||
max = time_scale_max_output_len(&state, BLOCK_LEN);
|
||||
printf("Rate is %f, longest output block is %d\n", rate, max);
|
||||
count = 0;
|
||||
samples_in = 0;
|
||||
samples_out = 0;
|
||||
while ((frames = sf_readf_short(inhandle, in, BLOCK_LEN)))
|
||||
{
|
||||
samples_in += frames;
|
||||
new_frames = time_scale(&state, out, in, frames);
|
||||
if (new_frames > max)
|
||||
{
|
||||
printf("Generated signal has more than the expected maximum samples - %d vs %d\n", new_frames, max);
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
samples_out += new_frames;
|
||||
out_frames = sf_writef_short(outhandle, out, new_frames);
|
||||
if (out_frames != new_frames)
|
||||
{
|
||||
|
@ -152,7 +164,27 @@ int main(int argc, char *argv[])
|
|||
count = 0;
|
||||
}
|
||||
}
|
||||
new_frames = time_scale_flush(&state, out);
|
||||
if (new_frames > max)
|
||||
{
|
||||
printf("Generated signal has more than the expected maximum samples - %d vs %d\n", new_frames, max);
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
samples_out += new_frames;
|
||||
out_frames = sf_writef_short(outhandle, out, new_frames);
|
||||
if (out_frames != new_frames)
|
||||
{
|
||||
fprintf(stderr, " Error writing audio file\n");
|
||||
exit(2);
|
||||
}
|
||||
time_scale_release(&state);
|
||||
if ((int) (rate*samples_in) < samples_out - 1 || (int) (rate*samples_in) > samples_out + 1)
|
||||
{
|
||||
printf("%d samples became %d samples\n", (int) (rate*samples_in), samples_out);
|
||||
printf("Tests failed\n");
|
||||
exit(2);
|
||||
}
|
||||
if (sf_close(inhandle))
|
||||
{
|
||||
printf(" Cannot close audio file '%s'\n", in_file_name);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
run_tsb85_test()
|
||||
{
|
||||
rm -f fax_tests_1.tif
|
||||
rm -f tsb85_tests.tif
|
||||
echo ./tsb85_tests ${TEST}
|
||||
./tsb85_tests -x ../spandsp/fax-tests.xml ${TEST} 2>xyzzy2
|
||||
RETVAL=$?
|
||||
|
@ -28,7 +28,7 @@ run_tsb85_test()
|
|||
fi
|
||||
}
|
||||
|
||||
for TEST in PPS-MPS-lost-PPS V17-12000-V29-9600 Phase-D-collision Modem-change-at-CTC
|
||||
for TEST in PPS-MPS-lost-PPS V17-12000-V29-9600 Phase-D-collision Modem-change-at-CTC ECM-DCN-clipped Non-ECM-DCN-clipped Tx-EOP-echo Tx-PPS-echo
|
||||
do
|
||||
run_tsb85_test
|
||||
done
|
||||
|
|
|
@ -60,8 +60,8 @@
|
|||
#include "spandsp.h"
|
||||
#include "spandsp-sim.h"
|
||||
|
||||
#include "fax_tester.h"
|
||||
#include "fax_utils.h"
|
||||
#include "fax_tester.h"
|
||||
|
||||
#define OUTPUT_TIFF_FILE_NAME "tsb85.tif"
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
run_tsb85_test()
|
||||
{
|
||||
rm -f fax_tests_1.tif
|
||||
rm -f tsb85_tests.tif
|
||||
echo ./tsb85_tests ${TEST}
|
||||
./tsb85_tests ${TEST} 2>xyzzy2
|
||||
RETVAL=$?
|
||||
|
@ -33,11 +33,6 @@ do
|
|||
run_tsb85_test
|
||||
done
|
||||
|
||||
#MRGN14 fails because we don't adequately distinguish between receiving a
|
||||
#bad image signal and receiving none at all.
|
||||
#MRGN16 fails because we don't adequately distinguish between receiving a
|
||||
#bad image signal and receiving none at all.
|
||||
|
||||
for TEST in MRGN09 MRGN10 MRGN11 MRGN12 MRGN13 MRGN14 MRGN15 MRGN16 MRGN17
|
||||
do
|
||||
run_tsb85_test
|
||||
|
@ -53,10 +48,6 @@ do
|
|||
run_tsb85_test
|
||||
done
|
||||
|
||||
# MRGX03 is failing because the V.27ter modem says it trained on HDLC
|
||||
# MRGX05 is failing because we don't distinguish MPS immediately after MCF from MPS after
|
||||
# a corrupt image signal.
|
||||
|
||||
for TEST in MRGX01 MRGX02 MRGX03 MRGX04 MRGX05 MRGX06 MRGX07 MRGX08
|
||||
do
|
||||
run_tsb85_test
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Downloading 16khzsound."
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
Outputs="$(ProjectDir)..\sounds\music\16000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
@ -85,7 +85,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Downloading 16khzsound."
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
Outputs="$(ProjectDir)..\sounds\music\16000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
|
|
@ -64,13 +64,13 @@
|
|||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Downloading 16khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\sounds\music\16000;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Downloading 16khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\sounds\music\16000;%(Outputs)</Outputs>
|
||||
|
@ -79,4 +79,4 @@ if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -66,13 +66,13 @@
|
|||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Downloading 16khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\sounds\music\16000;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Downloading 16khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\16000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\sounds\music\16000;%(Outputs)</Outputs>
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Downloading 32khzsound."
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
Outputs="$(ProjectDir)..\sounds\music\32000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
@ -85,7 +85,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Downloading 32khzsound."
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"

"
|
||||
Outputs="$(ProjectDir)..\sounds\music\32000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
|
|
@ -64,13 +64,13 @@
|
|||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Downloading 32khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\sounds\music\32000;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Downloading 32khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\sounds\music\32000;%(Outputs)</Outputs>
|
||||
|
@ -79,4 +79,4 @@ if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -66,13 +66,13 @@
|
|||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Downloading 32khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\sounds\music\32000;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Downloading 32khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\32000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-32000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\sounds\music\32000;%(Outputs)</Outputs>
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Downloading 8khzsound."
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
"
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
"
|
||||
Outputs="$(ProjectDir)..\sounds\music\8000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
@ -85,7 +85,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Downloading 8khzsound."
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
"
|
||||
CommandLine="set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
"
|
||||
Outputs="$(ProjectDir)..\sounds\music\8000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
|
|
@ -63,12 +63,12 @@
|
|||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Downloading 8khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\sounds\music\8000;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Downloading 8khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\sounds\music\8000;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
|
@ -76,4 +76,4 @@ if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)u
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -66,12 +66,12 @@
|
|||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Downloading 8khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\sounds\music\8000;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Downloading 8khzsound.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set /P SOUND_VERSION=<"$(ProjectDir)..\..\build\moh_version.txt"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
if not exist "$(ProjectDir)..\sounds\music\8000" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-%SOUND_VERSION%.tar.gz "$(ProjectDir)..\sounds"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\sounds\music\8000;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
|
|
|
@ -55,7 +55,7 @@ End If
|
|||
' *******************
|
||||
|
||||
Sub WgetSounds(PrimaryName, Freq, DestFolder, VersionFile)
|
||||
BaseURL = "http://files.freeswitch.org/freeswitch-sounds"
|
||||
BaseURL = "http://files.freeswitch.org/releases/sounds/freeswitch-sounds"
|
||||
Set objFSO = CreateObject("Scripting.FileSystemObject")
|
||||
Set objTextFile = objFSO.OpenTextFile(VersionFile,1)
|
||||
Do Until objTextFile.AtEndOfStream
|
||||
|
|
|
@ -9,14 +9,14 @@ wget -c http://svn.freeswitch.org/downloads/libs/openldap-2.4.11.tar.gz
|
|||
wget -c http://svn.freeswitch.org/downloads/libs/pocketsphinx-0.5.99-latest.tar.gz
|
||||
wget -c http://svn.freeswitch.org/downloads/libs/soundtouch-1.3.1.tar.gz
|
||||
wget -c http://svn.freeswitch.org/downloads/libs/sphinxbase-0.4.99-latest.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-music-8000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-music-16000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-music-32000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-music-48000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-en-us-callie-8000-1.0.11.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-en-us-callie-16000-1.0.11.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-en-us-callie-32000-1.0.11.tar.gz
|
||||
wget -c http://files.freeswitch.org/freeswitch-sounds-en-us-callie-48000-1.0.11.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-8000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-16000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-32000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-music-48000-1.0.8.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-en-us-callie-8000-1.0.11.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-en-us-callie-16000-1.0.11.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-en-us-callie-32000-1.0.11.tar.gz
|
||||
wget -c http://files.freeswitch.org/releases/sounds/freeswitch-sounds-en-us-callie-48000-1.0.11.tar.gz
|
||||
wget -c http://svn.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz
|
||||
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ struct switch_runtime {
|
|||
int64_t offset;
|
||||
switch_event_t *global_vars;
|
||||
switch_hash_t *mime_types;
|
||||
switch_hash_t *mime_type_exts;
|
||||
switch_hash_t *ptimes;
|
||||
switch_memory_pool_t *memory_pool;
|
||||
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
|
||||
|
|
|
@ -1574,7 +1574,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init_with_bitrate(switch_codec
|
|||
uint32_t bitrate,
|
||||
uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, switch_memory_pool_t *pool);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec,
|
||||
const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_codec_parse_fmtp(const char *codec_name, const char *fmtp, uint32_t rate, switch_codec_fmtp_t *codec_fmtp);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_codec_reset(switch_codec_t *codec);
|
||||
|
||||
|
@ -2277,6 +2278,7 @@ SWITCH_DECLARE(uint8_t) switch_core_session_compare(switch_core_session_t *a, sw
|
|||
SWITCH_DECLARE(uint8_t) switch_core_session_check_interface(switch_core_session_t *session, const switch_endpoint_interface_t *endpoint_interface);
|
||||
SWITCH_DECLARE(switch_hash_index_t *) switch_core_mime_index(void);
|
||||
SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext);
|
||||
SWITCH_DECLARE(const char *) switch_core_mime_type2ext(const char *type);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_mime_add_type(const char *type, const char *ext);
|
||||
|
||||
SWITCH_DECLARE(switch_loadable_module_interface_t *) switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name);
|
||||
|
|
|
@ -282,7 +282,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se
|
|||
uint32_t channels,
|
||||
uint8_t negotiated);
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_media_check_autoadj(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_rtp_crypto_key_type_t) switch_core_media_crypto_str2type(const char *str);
|
||||
SWITCH_DECLARE(const char *) switch_core_media_crypto_type2str(switch_rtp_crypto_key_type_t type);
|
||||
SWITCH_DECLARE(int) switch_core_media_crypto_keylen(switch_rtp_crypto_key_type_t type);
|
||||
|
|
|
@ -60,6 +60,7 @@ SWITCH_BEGIN_EXTERN_C struct switch_unicast_conninfo {
|
|||
int type;
|
||||
int transport;
|
||||
int stream_id;
|
||||
switch_thread_t *thread;
|
||||
};
|
||||
typedef struct switch_unicast_conninfo switch_unicast_conninfo_t;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
#define SWITCH_URL_UNSAFE "\r\n \"#%&+:;<=>?@[\\]^`{|}"
|
||||
#define SWITCH_URL_UNSAFE "\r\n #%&+:;<=>?@[\\]^`{|}\""
|
||||
|
||||
|
||||
/* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
|
||||
|
|
|
@ -515,7 +515,9 @@ SWITCH_STANDARD_APP(play_and_detect_speech_function)
|
|||
char *grammar = argv[1];
|
||||
char *result = NULL;
|
||||
switch_ivr_play_and_detect_speech(session, file, engine, grammar, &result, 0, NULL);
|
||||
switch_channel_set_variable(channel, "detect_speech_result", result);
|
||||
if (!zstr(result)) {
|
||||
switch_channel_set_variable(channel, "detect_speech_result", result);
|
||||
}
|
||||
} else {
|
||||
/* bad input */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Usage: %s\n", PLAY_AND_DETECT_SPEECH_SYNTAX);
|
||||
|
@ -625,6 +627,28 @@ SWITCH_STANDARD_APP(rename_function)
|
|||
}
|
||||
}
|
||||
|
||||
#define TRANSFER_VARS_SYNTAX "<~variable_prefix|variable>"
|
||||
SWITCH_STANDARD_APP(transfer_vars_function)
|
||||
{
|
||||
char *argv[1] = { 0 };
|
||||
int argc;
|
||||
char *lbuf = NULL;
|
||||
|
||||
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
|
||||
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
|
||||
switch_core_session_t *nsession = NULL;
|
||||
|
||||
switch_core_session_get_partner(session, &nsession);
|
||||
|
||||
if (nsession) {
|
||||
switch_ivr_transfer_variable(session, nsession, argv[0]);
|
||||
switch_core_session_rwunlock(nsession);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", TRANSFER_VARS_SYNTAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SOFT_HOLD_SYNTAX "<unhold key> [<moh_a>] [<moh_b>]"
|
||||
SWITCH_STANDARD_APP(soft_hold_function)
|
||||
{
|
||||
|
@ -5667,7 +5691,112 @@ SWITCH_STANDARD_API(page_api_function)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert DTMF source to human readable string
|
||||
*/
|
||||
static const char *to_dtmf_source_string(switch_dtmf_source_t source)
|
||||
{
|
||||
switch(source) {
|
||||
case SWITCH_DTMF_ENDPOINT: return "SIP INFO";
|
||||
case SWITCH_DTMF_INBAND_AUDIO: return "INBAND";
|
||||
case SWITCH_DTMF_RTP: return "2833";
|
||||
case SWITCH_DTMF_UNKNOWN: return "UNKNOWN";
|
||||
case SWITCH_DTMF_APP: return "APP";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
struct deduplicate_dtmf_filter {
|
||||
int only_rtp;
|
||||
char last_dtmf;
|
||||
switch_dtmf_source_t last_dtmf_source;
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter incoming DTMF and ignore any duplicates
|
||||
*/
|
||||
static switch_status_t deduplicate_recv_dtmf_hook(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
int only_rtp = 0;
|
||||
struct deduplicate_dtmf_filter *filter = switch_channel_get_private(switch_core_session_get_channel(session), "deduplicate_dtmf_filter");
|
||||
|
||||
if (!filter) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Accept %s digit %c: deduplicate filter missing!\n", to_dtmf_source_string(dtmf->source), dtmf->digit);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* remember current state as it might change */
|
||||
only_rtp = filter->only_rtp;
|
||||
|
||||
/* RTP DTMF is preferred over all others- and if it's demonstrated to be available, inband / info detection is disabled */
|
||||
if (only_rtp) {
|
||||
switch (dtmf->source) {
|
||||
case SWITCH_DTMF_ENDPOINT:
|
||||
switch_channel_set_variable(switch_core_session_get_channel(session), "deduplicate_dtmf_seen_endpoint", "true");
|
||||
break;
|
||||
case SWITCH_DTMF_INBAND_AUDIO:
|
||||
switch_channel_set_variable(switch_core_session_get_channel(session), "deduplicate_dtmf_seen_inband", "true");
|
||||
break;
|
||||
case SWITCH_DTMF_RTP:
|
||||
switch_channel_set_variable(switch_core_session_get_channel(session), "deduplicate_dtmf_seen_rtp", "true");
|
||||
/* pass through */
|
||||
case SWITCH_DTMF_UNKNOWN:
|
||||
case SWITCH_DTMF_APP:
|
||||
/* always allow */
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* accept everything except duplicates until RTP digit is detected */
|
||||
switch (dtmf->source) {
|
||||
case SWITCH_DTMF_INBAND_AUDIO:
|
||||
switch_channel_set_variable(switch_core_session_get_channel(session), "deduplicate_dtmf_seen_inband", "true");
|
||||
break;
|
||||
case SWITCH_DTMF_RTP:
|
||||
switch_channel_set_variable(switch_core_session_get_channel(session), "deduplicate_dtmf_seen_rtp", "true");
|
||||
/* change state to only allow RTP events */
|
||||
filter->only_rtp = 1;
|
||||
|
||||
/* stop inband detector */
|
||||
switch_ivr_broadcast(switch_core_session_get_uuid(session), "spandsp_stop_dtmf::", SMF_ECHO_ALEG);
|
||||
break;
|
||||
case SWITCH_DTMF_ENDPOINT:
|
||||
switch_channel_set_variable(switch_core_session_get_channel(session), "deduplicate_dtmf_seen_endpoint", "true");
|
||||
break;
|
||||
case SWITCH_DTMF_UNKNOWN:
|
||||
case SWITCH_DTMF_APP:
|
||||
/* always allow */
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* make sure not a duplicate DTMF */
|
||||
if (filter->last_dtmf_source == dtmf->source || filter->last_dtmf != dtmf->digit) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
filter->last_dtmf = dtmf->digit;
|
||||
filter->last_dtmf_source = dtmf->source;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) %s %s digit %c\n",
|
||||
(only_rtp) ? "ALLOW 2833" : "ALLOW ALL",
|
||||
(status == SWITCH_STATUS_SUCCESS) ? "Accept" : "Ignore", to_dtmf_source_string(dtmf->source), dtmf->digit);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(deduplicate_dtmf_app_function)
|
||||
{
|
||||
struct deduplicate_dtmf_filter *filter = switch_channel_get_private(switch_core_session_get_channel(session), "deduplicate_dtmf_filter");
|
||||
if (!filter) {
|
||||
filter = switch_core_session_alloc(session, sizeof(*filter));
|
||||
filter->only_rtp = !zstr(data) && !strcmp("only_rtp", data);
|
||||
filter->last_dtmf = 0;
|
||||
switch_channel_set_private(switch_core_session_get_channel(session), "deduplicate_dtmf_filter", filter);
|
||||
switch_core_event_hook_add_recv_dtmf(session, deduplicate_recv_dtmf_hook);
|
||||
}
|
||||
}
|
||||
|
||||
#define SPEAK_DESC "Speak text to a channel via the tts interface"
|
||||
#define DISPLACE_DESC "Displace audio from a file to the channels input"
|
||||
|
@ -5897,6 +6026,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||
SWITCH_ADD_APP(app_interface, "media_reset", "Reset all bypass/proxy media flags", "Reset all bypass/proxy media flags", media_reset_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "mkdir", "Create a directory", "Create a directory", mkdir_function, MKDIR_SYNTAX, SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "rename", "Rename file", "Rename file", rename_function, RENAME_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "transfer_vars", "Transfer variables", "Transfer variables", transfer_vars_function, TRANSFER_VARS_SYNTAX,
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "soft_hold", "Put a bridged channel on hold", "Put a bridged channel on hold", soft_hold_function, SOFT_HOLD_SYNTAX,
|
||||
SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "bind_meta_app", "Bind a key to an application", "Bind a key to an application", dtmf_bind_function, BIND_SYNTAX,
|
||||
|
@ -5966,6 +6097,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||
SWITCH_ADD_APP(app_interface, "limit_hash_execute", "Limit", LIMITHASHEXECUTE_DESC, limit_hash_execute_function, LIMITHASHEXECUTE_USAGE, SAF_SUPPORT_NOMEDIA);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "pickup", "Pickup", "Pickup a call", pickup_function, PICKUP_SYNTAX, SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "deduplicate_dtmf", "Prevent duplicate inband + 2833 dtmf", "", deduplicate_dtmf_app_function, "[only_rtp]", SAF_SUPPORT_NOMEDIA);
|
||||
|
||||
|
||||
SWITCH_ADD_DIALPLAN(dp_interface, "inline", inline_dialplan_hunt);
|
||||
|
|
|
@ -2780,12 +2780,7 @@ static switch_status_t locate_url_file(http_file_context_t *context, const char
|
|||
}
|
||||
|
||||
if (zstr(ext) && headers && (ct = switch_event_get_header(headers, "content-type"))) {
|
||||
if (switch_strcasecmp_any(ct, "audio/mpeg", "audio/x-mpeg", "audio/mp3", "audio/x-mp3", "audio/mpeg3",
|
||||
"audio/x-mpeg3", "audio/mpg", "audio/x-mpg", "audio/x-mpegaudio", NULL)) {
|
||||
newext = "mp3";
|
||||
} else if (switch_strcasecmp_any(ct, "audio/x-wav", "audio/x-wave", "audio/wav", "audio/wave", NULL)) {
|
||||
newext = "wav";
|
||||
}
|
||||
newext = switch_core_mime_type2ext(ct);
|
||||
}
|
||||
|
||||
if (newext) {
|
||||
|
|
|
@ -87,6 +87,12 @@ struct cached_url {
|
|||
char *url;
|
||||
/** The path and name of the cached URL */
|
||||
char *filename;
|
||||
/** File extension */
|
||||
char *extension;
|
||||
/** Content-Type of this URL (audio/3gpp) */
|
||||
char *content_type;
|
||||
/** Content-Type parameters (codecs=samr) */
|
||||
const char *content_type_params;
|
||||
/** The size of the cached URL, in bytes */
|
||||
size_t size;
|
||||
/** URL use flag */
|
||||
|
@ -120,6 +126,7 @@ static switch_status_t http_get(url_cache_t *cache, http_profile_t *profile, cac
|
|||
static size_t get_file_callback(void *ptr, size_t size, size_t nmemb, void *get);
|
||||
static size_t get_header_callback(void *ptr, size_t size, size_t nmemb, void *url);
|
||||
static void process_cache_control_header(cached_url_t *url, char *data);
|
||||
static void process_content_type_header(cached_url_t *url, char *data);
|
||||
|
||||
static switch_status_t http_put(url_cache_t *cache, http_profile_t *profile, switch_core_session_t *session, const char *url, const char *filename, int cache_local_file);
|
||||
|
||||
|
@ -479,8 +486,32 @@ static void process_cache_control_header(cached_url_t *url, char *data)
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting max age to %u seconds from now\n", (int)max_age);
|
||||
}
|
||||
|
||||
/**
|
||||
* Content-Type: audio/mpeg; foo=bar
|
||||
*/
|
||||
static void process_content_type_header(cached_url_t *url, char *data)
|
||||
{
|
||||
char *params;
|
||||
|
||||
/* trim whitespace and check if empty */
|
||||
data = trim(data);
|
||||
if (zstr(data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy header, removing any params */
|
||||
url->content_type = strdup(data);
|
||||
params = strchr(url->content_type, ';');
|
||||
if (params) {
|
||||
*params = '\0';
|
||||
url->content_type_params = trim(++params);
|
||||
}
|
||||
}
|
||||
|
||||
#define CACHE_CONTROL_HEADER "cache-control:"
|
||||
#define CACHE_CONTROL_HEADER_LEN (sizeof(CACHE_CONTROL_HEADER) - 1)
|
||||
#define CONTENT_TYPE_HEADER "content-type:"
|
||||
#define CONTENT_TYPE_HEADER_LEN (sizeof(CONTENT_TYPE_HEADER) - 1)
|
||||
/**
|
||||
* Called by libcurl to process headers from HTTP GET response
|
||||
* @param ptr the header data
|
||||
|
@ -508,6 +539,8 @@ static size_t get_header_callback(void *ptr, size_t size, size_t nmemb, void *ge
|
|||
/* check which header this is and process it */
|
||||
if (!strncasecmp(CACHE_CONTROL_HEADER, header, CACHE_CONTROL_HEADER_LEN)) {
|
||||
process_cache_control_header(url, header + CACHE_CONTROL_HEADER_LEN);
|
||||
} else if (!strncasecmp(CONTENT_TYPE_HEADER, header, CONTENT_TYPE_HEADER_LEN)) {
|
||||
process_content_type_header(url, header + CONTENT_TYPE_HEADER_LEN);
|
||||
}
|
||||
|
||||
switch_safe_free(header);
|
||||
|
@ -819,38 +852,51 @@ static http_profile_t *url_cache_http_profile_add(url_cache_t *cache, const char
|
|||
|
||||
/**
|
||||
* Find file extension at end of URL.
|
||||
* @return file extension or NULL if it doesn't exist
|
||||
* @param url to search
|
||||
* @param found_extension
|
||||
* @param found_extension_len
|
||||
*/
|
||||
static const char *find_extension(const char *url)
|
||||
static void find_extension(const char *url, const char **found_extension, size_t *found_extension_len)
|
||||
{
|
||||
const char *ext;
|
||||
size_t ext_len = 0;
|
||||
|
||||
/* find extension on the end of URL */
|
||||
for (ext = &url[strlen(url) - 1]; ext != url; ext--) {
|
||||
if (*ext == '/' || *ext == '\\') {
|
||||
break;
|
||||
}
|
||||
if (*ext == '.') {
|
||||
if (*ext == '?' || *ext == '#') {
|
||||
ext_len = 0;
|
||||
} else if (*ext == '.') {
|
||||
/* found it */
|
||||
return ++ext;
|
||||
*found_extension_len = ext_len;
|
||||
*found_extension = ++ext;
|
||||
break;
|
||||
} else {
|
||||
ext_len++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a cached URL filename.
|
||||
* @param cache the cache
|
||||
* @param extension the filename extension
|
||||
* @param cache
|
||||
* @param url
|
||||
* @param extension if set, extension is duplicated here
|
||||
* @return the cached URL filename. Free when done.
|
||||
*/
|
||||
static char *cached_url_filename_create(url_cache_t *cache, const char *extension)
|
||||
static char *cached_url_filename_create(url_cache_t *cache, const char *url, char **extension)
|
||||
{
|
||||
char *filename;
|
||||
char *dirname;
|
||||
char uuid_dir[3] = { 0 };
|
||||
switch_uuid_t uuid;
|
||||
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
|
||||
const char *found_extension = NULL;
|
||||
size_t found_extension_len = 0;
|
||||
|
||||
find_extension(url, &found_extension, &found_extension_len);
|
||||
|
||||
/* filename is constructed from UUID and is stored in cache dir (first 2 characters of UUID) */
|
||||
switch_uuid_get(&uuid);
|
||||
|
@ -861,15 +907,47 @@ static char *cached_url_filename_create(url_cache_t *cache, const char *extensio
|
|||
/* create sub-directory if it doesn't exist */
|
||||
switch_dir_make_recursive(dirname, SWITCH_DEFAULT_DIR_PERMS, cache->pool);
|
||||
|
||||
if (!zstr(extension)) {
|
||||
filename = switch_mprintf("%s%s%s.%s", dirname, SWITCH_PATH_SEPARATOR, &uuid_str[2], extension);
|
||||
} else {
|
||||
if (!zstr(found_extension) && found_extension_len > 0) {
|
||||
char *found_extension_dup = strndup(found_extension, found_extension_len);
|
||||
filename = switch_mprintf("%s%s%s.%s", dirname, SWITCH_PATH_SEPARATOR, &uuid_str[2], found_extension_dup);
|
||||
if (extension) {
|
||||
*extension = found_extension_dup;
|
||||
} else {
|
||||
free(found_extension_dup);
|
||||
}
|
||||
} else {
|
||||
filename = switch_mprintf("%s%s%s", dirname, SWITCH_PATH_SEPARATOR, &uuid_str[2]);
|
||||
if (extension) {
|
||||
*extension = NULL;
|
||||
}
|
||||
}
|
||||
free(dirname);
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename cached URL with filename extension if one can be determined
|
||||
* @param url the cached URL
|
||||
*/
|
||||
static void cached_url_set_extension_from_content_type(cached_url_t *url, switch_core_session_t *session)
|
||||
{
|
||||
if (!url->extension && url->content_type) {
|
||||
const char *new_extension = switch_core_mime_type2ext(url->content_type);
|
||||
if (new_extension) {
|
||||
char *new_filename = switch_mprintf("%s.%s", url->filename, new_extension);
|
||||
if (rename(url->filename, new_filename) != -1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "renamed cached URL to %s\n", new_filename);
|
||||
free(url->filename);
|
||||
url->filename = new_filename;
|
||||
url->extension = strdup(new_extension);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "rename(%s): %s\n", new_filename, strerror(errno));
|
||||
free(new_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a cached URL entry
|
||||
* @param cache the cache
|
||||
|
@ -889,7 +967,7 @@ static cached_url_t *cached_url_create(url_cache_t *cache, const char *url, cons
|
|||
|
||||
/* intialize cached URL */
|
||||
if (zstr(filename)) {
|
||||
u->filename = cached_url_filename_create(cache, find_extension(url));
|
||||
u->filename = cached_url_filename_create(cache, url, &u->extension);
|
||||
} else {
|
||||
u->filename = strdup(filename);
|
||||
}
|
||||
|
@ -914,6 +992,8 @@ static void cached_url_destroy(cached_url_t *url, switch_memory_pool_t *pool)
|
|||
switch_file_remove(url->filename, pool);
|
||||
}
|
||||
switch_safe_free(url->filename);
|
||||
switch_safe_free(url->extension);
|
||||
switch_safe_free(url->content_type);
|
||||
switch_safe_free(url->url);
|
||||
switch_safe_free(url);
|
||||
}
|
||||
|
@ -1022,6 +1102,9 @@ static switch_status_t http_get(url_cache_t *cache, http_profile_t *profile, cac
|
|||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "URL %s downloaded in %d ms\n", url->url, duration_ms);
|
||||
}
|
||||
if (!url->extension) {
|
||||
cached_url_set_extension_from_content_type(url, session);
|
||||
}
|
||||
} else {
|
||||
url->size = 0; // nothing downloaded or download interrupted
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Received HTTP error %ld trying to fetch %s\n", httpRes, url->url);
|
||||
|
@ -1095,7 +1178,7 @@ SWITCH_STANDARD_API(http_cache_prefetch)
|
|||
|
||||
#define HTTP_GET_SYNTAX "{param=val}<url>"
|
||||
/**
|
||||
* Get a file from the cache, download if it isn't cached
|
||||
* Get a file from the cache, download if it isn' cached
|
||||
*/
|
||||
SWITCH_STANDARD_API(http_cache_get)
|
||||
{
|
||||
|
@ -1564,7 +1647,7 @@ static switch_status_t http_cache_file_open(switch_file_handle_t *handle, const
|
|||
file_flags |= SWITCH_FILE_FLAG_WRITE;
|
||||
context->write_url = switch_core_strdup(handle->memory_pool, path);
|
||||
/* allocate local file in cache */
|
||||
context->local_path = cached_url_filename_create(&gcache, find_extension(context->write_url));
|
||||
context->local_path = cached_url_filename_create(&gcache, context->write_url, NULL);
|
||||
} else {
|
||||
/* READ = HTTP GET */
|
||||
file_flags |= SWITCH_FILE_FLAG_READ;
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
<configuration name="mongo.conf">
|
||||
<settings>
|
||||
<!--
|
||||
<!--
|
||||
connection-string handles different ways to connect to mongo
|
||||
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
|
||||
-->
|
||||
<param name="connection-string" value="mongodb://127.0.0.1:27017/?connectTimeoutMS=5000"/>
|
||||
|
||||
<!-- connection for queries and limit backend -->
|
||||
<param name="connection-string" value="mongodb://127.0.0.1:27017/?connecttimetoutms=5000"/>
|
||||
<!-- connection for limit backend, if different than connection-string (default is value set in connection-string) -->
|
||||
<!--param name="limit-connection-string" value="mongodb://127.0.0.1:27019/?connecttimeoutms=5000"/-->
|
||||
<!-- database name for limit backend (default is limit) -->
|
||||
<!--param name="limit-database" value="limit"/-->
|
||||
<!-- collection name for limit backend (default is mod_mongo) -->
|
||||
<!--param name="limit-collection" value="mod_mongo"/-->
|
||||
<!--
|
||||
<param name="map" value="function() { emit(this.a, 1); }"/>
|
||||
<param name="reduce" value="function(key, values) { return Array.sum(values); }"/>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* Tamas Cseke <cstomi.levlist@gmail.com>
|
||||
* Christopher Rienzo <crienzo@grasshopper.com>
|
||||
*
|
||||
* mod_mongo.c -- API for MongoDB
|
||||
* mod_mongo.c -- API for MongoDB
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
|
@ -49,17 +49,34 @@
|
|||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load);
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown);
|
||||
SWITCH_MODULE_DEFINITION(mod_mongo, mod_mongo_load, mod_mongo_shutdown, NULL);
|
||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_mongo_runtime);
|
||||
SWITCH_MODULE_DEFINITION(mod_mongo, mod_mongo_load, mod_mongo_shutdown, mod_mongo_runtime);
|
||||
|
||||
static struct {
|
||||
int shutdown;
|
||||
const char *map;
|
||||
const char *reduce;
|
||||
const char *finalize;
|
||||
const char *conn_str;
|
||||
mongoc_uri_t *uri;
|
||||
mongoc_client_pool_t *client_pool;
|
||||
const char *limit_database;
|
||||
const char *limit_collection;
|
||||
const char *limit_conn_str;
|
||||
int limit_cleanup_interval_sec;
|
||||
mongoc_client_pool_t *limit_client_pool;
|
||||
switch_mutex_t *mod_mongo_private_mutex;
|
||||
switch_thread_rwlock_t *limit_database_rwlock;
|
||||
switch_thread_rwlock_t *shutdown_rwlock;
|
||||
} globals;
|
||||
|
||||
/**
|
||||
* resources acquired by this session
|
||||
*/
|
||||
struct mod_mongo_private {
|
||||
switch_hash_t *resources;
|
||||
switch_mutex_t *mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param query_options_str
|
||||
* @return query options
|
||||
|
@ -94,11 +111,11 @@ static int parse_query_options(char *query_options_str)
|
|||
/**
|
||||
* @return a new connection to mongodb or NULL if error
|
||||
*/
|
||||
static mongoc_client_t *get_connection(void)
|
||||
static mongoc_client_t *get_connection(mongoc_client_pool_t *client_pool, const char *conn_str)
|
||||
{
|
||||
mongoc_client_t *client = mongoc_client_pool_pop(globals.client_pool);
|
||||
mongoc_client_t *client = mongoc_client_pool_pop(client_pool);
|
||||
if (!client) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to get connection to: %s\n", globals.conn_str);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to get connection to: %s\n", conn_str);
|
||||
return NULL;
|
||||
}
|
||||
/* TODO auth */
|
||||
|
@ -108,12 +125,12 @@ static mongoc_client_t *get_connection(void)
|
|||
/**
|
||||
* Mark connection as finished
|
||||
*/
|
||||
static void connection_done(mongoc_client_t *conn)
|
||||
static void connection_done(mongoc_client_pool_t *client_pool, mongoc_client_t *conn)
|
||||
{
|
||||
mongoc_client_pool_push(globals.client_pool, conn);
|
||||
mongoc_client_pool_push(client_pool, conn);
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(mongo_mapreduce_function)
|
||||
SWITCH_STANDARD_API(mod_mongo_mapreduce_function)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
char *db = NULL, *collection = NULL, *json_query = NULL;
|
||||
|
@ -129,7 +146,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function)
|
|||
}
|
||||
|
||||
if (!zstr(db) && !zstr(collection) && !zstr(json_query)) {
|
||||
mongoc_client_t *conn = get_connection();
|
||||
mongoc_client_t *conn = get_connection(globals.client_pool, globals.conn_str);
|
||||
if (conn) {
|
||||
bson_error_t error;
|
||||
bson_t *query = bson_new_from_json((uint8_t *)json_query, strlen(json_query), &error);
|
||||
|
@ -172,7 +189,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function)
|
|||
} else {
|
||||
stream->write_function(stream, "-ERR\nfailed to parse query!\n");
|
||||
}
|
||||
connection_done(conn);
|
||||
connection_done(globals.client_pool, conn);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR\nfailed to get connection!\n");
|
||||
}
|
||||
|
@ -185,7 +202,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function)
|
|||
return status;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(mongo_find_n_function)
|
||||
SWITCH_STANDARD_API(mod_mongo_find_n_function)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
char *db = NULL, *collection = NULL, *json_query = NULL, *json_fields = NULL, *query_options_str = NULL;
|
||||
|
@ -223,7 +240,7 @@ SWITCH_STANDARD_API(mongo_find_n_function)
|
|||
|
||||
if (!zstr(db) && !zstr(collection) && !zstr(json_query) && !zstr(json_fields)) {
|
||||
bson_error_t error;
|
||||
mongoc_client_t *conn = get_connection();
|
||||
mongoc_client_t *conn = get_connection(globals.client_pool, globals.conn_str);
|
||||
if (conn) {
|
||||
mongoc_collection_t *col = mongoc_client_get_collection(conn, db, collection);
|
||||
if (col) {
|
||||
|
@ -268,7 +285,7 @@ SWITCH_STANDARD_API(mongo_find_n_function)
|
|||
} else {
|
||||
stream->write_function(stream, "-ERR\nunknown collection: %s\n", collection);
|
||||
}
|
||||
connection_done(conn);
|
||||
connection_done(globals.client_pool, conn);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR\nfailed to get connection!\n");
|
||||
}
|
||||
|
@ -281,7 +298,7 @@ SWITCH_STANDARD_API(mongo_find_n_function)
|
|||
return status;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(mongo_find_one_function)
|
||||
SWITCH_STANDARD_API(mod_mongo_find_one_function)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
char *db = NULL, *collection = NULL, *json_query = NULL, *json_fields = NULL, *query_options_str = NULL;
|
||||
|
@ -308,7 +325,7 @@ SWITCH_STANDARD_API(mongo_find_one_function)
|
|||
|
||||
if (!zstr(db) && !zstr(collection) && !zstr(json_query) && !zstr(json_fields)) {
|
||||
bson_error_t error;
|
||||
mongoc_client_t *conn = get_connection();
|
||||
mongoc_client_t *conn = get_connection(globals.client_pool, globals.conn_str);
|
||||
if (conn) {
|
||||
mongoc_collection_t *col = mongoc_client_get_collection(conn, db, collection);
|
||||
if (col) {
|
||||
|
@ -348,7 +365,7 @@ SWITCH_STANDARD_API(mongo_find_one_function)
|
|||
} else {
|
||||
stream->write_function(stream, "-ERR\nunknown collection: %s\n", collection);
|
||||
}
|
||||
connection_done(conn);
|
||||
connection_done(globals.client_pool, conn);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR\nfailed to get connection!\n");
|
||||
}
|
||||
|
@ -361,7 +378,362 @@ SWITCH_STANDARD_API(mongo_find_one_function)
|
|||
return status;
|
||||
}
|
||||
|
||||
static switch_status_t config(switch_memory_pool_t *pool)
|
||||
/**
|
||||
* Calculate resource count from BSON document
|
||||
*/
|
||||
static switch_status_t mod_mongo_get_count(switch_core_session_t *session, const char *key, const bson_t *b, int *new_val_ret, char **resource_ret)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
bson_iter_t iter;
|
||||
if (new_val_ret) {
|
||||
if (bson_iter_init_find(&iter, b, key) && BSON_ITER_HOLDS_INT32(&iter)) {
|
||||
*new_val_ret = bson_iter_int32(&iter);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to get resource count\n");
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
if (resource_ret) {
|
||||
if (bson_iter_init_find(&iter, b, "_id") && BSON_ITER_HOLDS_UTF8(&iter)) {
|
||||
uint32_t len;
|
||||
const char *resource = bson_iter_utf8(&iter, &len);
|
||||
if (!zstr(resource)) {
|
||||
if (bson_utf8_validate(resource, len, 0)) {
|
||||
*resource_ret = strdup(resource);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Resource name is not valid utf8\n");
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Resource name is empty string");
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Resource name not found\n");
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a resource by val
|
||||
* @param session
|
||||
* @param resource name of resource being incremented
|
||||
* @param val number to increment resource by
|
||||
* @param max maximum value of resource allowed
|
||||
* @param new_val_ret new value of resource after increment completed
|
||||
*/
|
||||
static switch_status_t mod_mongo_increment(switch_core_session_t *session, const char *resource, int val, int max, int *new_val_ret)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_GENERR;
|
||||
mongoc_client_t *conn = get_connection(globals.limit_client_pool, globals.limit_conn_str);
|
||||
if (conn) {
|
||||
mongoc_collection_t *col = mongoc_client_get_collection(conn, globals.limit_database, globals.limit_collection);
|
||||
if (col) {
|
||||
int upsert;
|
||||
bson_t *query, *update, reply;
|
||||
bson_error_t error;
|
||||
|
||||
/* construct update query - the counts are stored as:
|
||||
{ _id: "realm_resource", total: 29, "fs-1": 5, "fs-2": 10, "fs-3": 3, "fs-4": 11 }
|
||||
*/
|
||||
if (val >= 0) {
|
||||
if (max > 0) {
|
||||
/* increment if < max */
|
||||
query = BCON_NEW("_id", resource,
|
||||
"total", "{", "$lt", BCON_INT32(max), "}");
|
||||
upsert = 1; /* will fail with duplicate index key error if total condition is not satisfied */
|
||||
} else {
|
||||
/* increment, no restrictions */
|
||||
query = BCON_NEW("_id", resource);
|
||||
upsert = 1;
|
||||
}
|
||||
} else {
|
||||
/* don't allow decrement below 0, don't add fields that don't exist */
|
||||
query = BCON_NEW("_id", resource,
|
||||
"total", "{", "$gte", BCON_INT32(-val), "}",
|
||||
switch_core_get_switchname(), "{", "$gte", BCON_INT32(-val), "}");
|
||||
upsert = 0;
|
||||
}
|
||||
update = BCON_NEW("$inc", "{", "total", BCON_INT32(val), switch_core_get_switchname(), BCON_INT32(val), "}");
|
||||
|
||||
if (!mongoc_collection_find_and_modify(col, query, NULL, update, NULL, false, upsert, true, &reply, &error)) {
|
||||
if (max > 0 && error.code == 11000) {
|
||||
/* duplicate key index error - limit exceeded */
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Usage for %s exceeds maximum rate of %d\n", resource, max);
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Increment %s by %d failed: %s\n", resource, val, error.message);
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
}
|
||||
} else if (new_val_ret) {
|
||||
status = mod_mongo_get_count(session, "total", &reply, new_val_ret, NULL);
|
||||
} else {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bson_destroy(query);
|
||||
bson_destroy(update);
|
||||
bson_destroy(&reply);
|
||||
mongoc_collection_destroy(col);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Increment %s by %d failed: unable to get collection %s from database %s\n", resource, val, globals.limit_collection, globals.limit_database);
|
||||
}
|
||||
connection_done(globals.limit_client_pool, conn);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource usage
|
||||
*/
|
||||
static switch_status_t mod_mongo_get_usage(const char *resource, int *usage)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_GENERR;
|
||||
mongoc_client_t *conn = get_connection(globals.limit_client_pool, globals.limit_conn_str);
|
||||
if (conn) {
|
||||
mongoc_collection_t *col = mongoc_client_get_collection(conn, globals.limit_database, globals.limit_collection);
|
||||
if (col) {
|
||||
bson_t *query = BCON_NEW("_id", resource);
|
||||
bson_t *fields = BCON_NEW("total", BCON_INT32(1));
|
||||
bson_error_t error;
|
||||
mongoc_cursor_t *cursor = mongoc_collection_find(col, 0, 0, 1, 0, query, fields, NULL);
|
||||
if (cursor) {
|
||||
if (!mongoc_cursor_error(cursor, &error)) {
|
||||
/* get result from cursor */
|
||||
const bson_t *result;
|
||||
if (mongoc_cursor_more(cursor) && mongoc_cursor_next(cursor, &result)) {
|
||||
status = mod_mongo_get_count(NULL, "total", result, usage, NULL);
|
||||
}
|
||||
}
|
||||
mongoc_cursor_destroy(cursor);
|
||||
}
|
||||
bson_destroy(query);
|
||||
bson_destroy(fields);
|
||||
mongoc_collection_destroy(col);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Get usage failed: unable to get collection %s from database %s\n", globals.limit_collection, globals.limit_database);
|
||||
}
|
||||
connection_done(globals.limit_client_pool, conn);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all limits on this server
|
||||
*/
|
||||
static switch_status_t mod_mongo_reset(void)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_GENERR;
|
||||
mongoc_client_t *conn = get_connection(globals.limit_client_pool, globals.limit_conn_str);
|
||||
if (conn) {
|
||||
mongoc_collection_t *col = mongoc_client_get_collection(conn, globals.limit_database, globals.limit_collection);
|
||||
if (col) {
|
||||
bson_t *query;
|
||||
//bson_t *fields;
|
||||
mongoc_cursor_t *cursor;
|
||||
bson_error_t error;
|
||||
query = BCON_NEW(switch_core_get_switchname(), "{", "$gt", BCON_INT32(0), "}");
|
||||
//fields = BCON_NEW(switch_core_get_switchname(), "1");
|
||||
|
||||
/* find all docs w/ this server and clear its counts */
|
||||
switch_thread_rwlock_wrlock(globals.limit_database_rwlock); /* prevent increments on this server */
|
||||
cursor = mongoc_collection_find(col, 0, 0, 0, 0, query, NULL, NULL);
|
||||
if (cursor) {
|
||||
if (!mongoc_cursor_error(cursor, &error)) {
|
||||
/* get result from cursor */
|
||||
const bson_t *result;
|
||||
char *resource = NULL;
|
||||
while (mongoc_cursor_more(cursor) && mongoc_cursor_next(cursor, &result)) {
|
||||
int count = 0;
|
||||
if ((status = mod_mongo_get_count(NULL, switch_core_get_switchname(), result, &count, &resource)) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reset %s, -%d\n", resource, count);
|
||||
if (count > 0 && !zstr(resource)) {
|
||||
/* decrement server counts from mongo */
|
||||
if ((status = mod_mongo_increment(NULL, resource, -count, 0, NULL)) == SWITCH_STATUS_GENERR) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Reset done - increment error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch_safe_free(resource);
|
||||
resource = NULL;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reset failed - get count\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch_safe_free(resource);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Reset failed: %s\n", error.message);
|
||||
}
|
||||
mongoc_cursor_destroy(cursor);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Reset failed: NULL cursor returned\n");
|
||||
}
|
||||
switch_thread_rwlock_unlock(globals.limit_database_rwlock);
|
||||
|
||||
bson_destroy(query);
|
||||
//bson_destroy(fields);
|
||||
mongoc_collection_destroy(col);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Reset failed: unable to get collection %s from database %s\n", globals.limit_collection, globals.limit_database);
|
||||
}
|
||||
connection_done(globals.limit_client_pool, conn);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up all entries w/ resource count of 0
|
||||
*/
|
||||
static switch_status_t mod_mongo_cleanup(void)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_GENERR;
|
||||
mongoc_client_t *conn = get_connection(globals.limit_client_pool, globals.limit_conn_str);
|
||||
if (conn) {
|
||||
mongoc_collection_t *col = mongoc_client_get_collection(conn, globals.limit_database, globals.limit_collection);
|
||||
if (col) {
|
||||
bson_t *selector = BCON_NEW("total", BCON_INT32(0));
|
||||
bson_error_t error;
|
||||
if (mongoc_collection_remove(col, 0, selector, NULL, &error)) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cleanup failed: %s\n", error.message);
|
||||
}
|
||||
bson_destroy(selector);
|
||||
mongoc_collection_destroy(col);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cleanup failed: unable to get collection %s from database %s\n", globals.limit_collection, globals.limit_database);
|
||||
}
|
||||
connection_done(globals.limit_client_pool, conn);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enforces limit_mongo restrictions
|
||||
* @param session current session
|
||||
* @param realm limit realm
|
||||
* @param id limit id
|
||||
* @param max maximum count
|
||||
* @param interval interval for rate limiting
|
||||
* @return SWITCH_TRUE if the access is allowed, SWITCH_FALSE if it isn't
|
||||
*/
|
||||
SWITCH_LIMIT_INCR(mod_mongo_limit_incr)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
const char *limit_id = switch_core_session_sprintf(session, "%s_%s", realm, resource);
|
||||
|
||||
/* get session's resource tracking information */
|
||||
struct mod_mongo_private *pvt = switch_channel_get_private(channel, "limit_mongo");
|
||||
if (!pvt) {
|
||||
switch_mutex_lock(globals.mod_mongo_private_mutex); /* prevents concurrent alloc of mod_mongo_private */
|
||||
pvt = switch_channel_get_private(channel, "limit_mongo");
|
||||
if (!pvt) {
|
||||
pvt = (struct mod_mongo_private *) switch_core_session_alloc(session, sizeof(*pvt));
|
||||
switch_core_hash_init(&pvt->resources);
|
||||
switch_mutex_init(&pvt->mutex, SWITCH_MUTEX_UNNESTED, switch_core_session_get_pool(session));
|
||||
switch_channel_set_private(channel, "limit_mongo", pvt);
|
||||
}
|
||||
switch_mutex_unlock(globals.mod_mongo_private_mutex);
|
||||
}
|
||||
|
||||
switch_mutex_lock(pvt->mutex); /* prevents concurrent increment in session */
|
||||
switch_thread_rwlock_rdlock(globals.limit_database_rwlock); /* prevent reset operation on this server */
|
||||
|
||||
/* check if resource is already incremented on this session */
|
||||
if (!switch_core_hash_find(pvt->resources, limit_id)) {
|
||||
/* increment resource usage */
|
||||
if ((status = mod_mongo_increment(session, limit_id, 1, max, NULL)) == SWITCH_STATUS_SUCCESS) {
|
||||
/* remember this resource was incremented */
|
||||
switch_core_hash_insert(pvt->resources, limit_id, limit_id);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s already acquired\n", limit_id);
|
||||
}
|
||||
|
||||
switch_thread_rwlock_unlock(globals.limit_database_rwlock);
|
||||
switch_mutex_unlock(pvt->mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases usage of a limit_mongo-controlled resource
|
||||
*/
|
||||
SWITCH_LIMIT_RELEASE(mod_mongo_limit_release)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
struct mod_mongo_private *pvt = switch_channel_get_private(channel, "limit_mongo");
|
||||
int status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
if (!pvt) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No limit tracking data for channel\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_mutex_lock(pvt->mutex); /* prevents concurrent decrement in session */
|
||||
switch_thread_rwlock_rdlock(globals.limit_database_rwlock); /* prevent reset operation on this server */
|
||||
|
||||
/* no realm / resource = clear all resources */
|
||||
if (realm == NULL && resource == NULL) {
|
||||
/* clear all resources */
|
||||
switch_hash_index_t *hi = NULL;
|
||||
while ((hi = switch_core_hash_first_iter(pvt->resources, hi))) {
|
||||
void *p_val = NULL;
|
||||
const void *p_key;
|
||||
switch_ssize_t keylen;
|
||||
switch_core_hash_this(hi, &p_key, &keylen, &p_val);
|
||||
if (mod_mongo_increment(session, (const char *)p_key, -1, 0, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Couldn't decrement %s\n", (const char *)p_key);
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
break;
|
||||
} else {
|
||||
switch_core_hash_delete(pvt->resources, (const char *) p_key);
|
||||
}
|
||||
}
|
||||
} else if (!zstr(realm) && !zstr(resource)) {
|
||||
/* clear specific resource */
|
||||
const char *limit_id = switch_core_session_sprintf(session, "%s_%s", realm, resource);
|
||||
if (switch_core_hash_find(pvt->resources, limit_id)) {
|
||||
if (mod_mongo_increment(session, limit_id, -1, 0, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Couldn't decrement %s\n", limit_id);
|
||||
} else {
|
||||
switch_core_hash_delete(pvt->resources, limit_id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Missing either realm or resource to release\n");
|
||||
}
|
||||
|
||||
switch_thread_rwlock_unlock(globals.limit_database_rwlock);
|
||||
switch_mutex_unlock(pvt->mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_LIMIT_USAGE(mod_mongo_limit_usage)
|
||||
{
|
||||
char *limit_id = switch_mprintf("%s_%s", realm, resource);
|
||||
int usage = 0;
|
||||
mod_mongo_get_usage(limit_id, &usage);
|
||||
switch_safe_free(limit_id);
|
||||
return usage;
|
||||
}
|
||||
|
||||
SWITCH_LIMIT_RESET(mod_mongo_limit_reset)
|
||||
{
|
||||
return mod_mongo_reset();
|
||||
}
|
||||
|
||||
SWITCH_LIMIT_STATUS(mod_mongo_limit_status)
|
||||
{
|
||||
return strdup("-ERR not supported");
|
||||
}
|
||||
|
||||
static switch_status_t do_config(switch_memory_pool_t *pool)
|
||||
{
|
||||
const char *cf = "mongo.conf";
|
||||
switch_xml_t cfg, xml, settings, param;
|
||||
|
@ -372,8 +744,12 @@ static switch_status_t config(switch_memory_pool_t *pool)
|
|||
globals.reduce = "";
|
||||
globals.finalize = "";
|
||||
globals.conn_str = "";
|
||||
globals.uri = NULL;
|
||||
globals.client_pool = NULL;
|
||||
globals.limit_database = "limit";
|
||||
globals.limit_collection = "mod_mongo";
|
||||
globals.limit_conn_str = "";
|
||||
globals.limit_client_pool = NULL;
|
||||
globals.limit_cleanup_interval_sec = 300;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
|
||||
|
@ -391,21 +767,75 @@ static switch_status_t config(switch_memory_pool_t *pool)
|
|||
status = SWITCH_STATUS_GENERR;
|
||||
goto done;
|
||||
} else {
|
||||
mongoc_uri_t *uri;
|
||||
globals.conn_str = switch_core_strdup(pool, val);
|
||||
globals.uri = mongoc_uri_new(globals.conn_str);
|
||||
if (globals.uri) {
|
||||
globals.client_pool = mongoc_client_pool_new(globals.uri);
|
||||
uri = mongoc_uri_new(globals.conn_str);
|
||||
if (uri) {
|
||||
globals.client_pool = mongoc_client_pool_new(uri);
|
||||
mongoc_uri_destroy(uri);
|
||||
if (!globals.client_pool) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to pool for connection-string: %s\n", globals.conn_str);
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
goto done;
|
||||
}
|
||||
if (!globals.limit_client_pool) {
|
||||
/* use connection-string for limit backend unless overriden by limit-connection-string */
|
||||
globals.limit_client_pool = globals.client_pool;
|
||||
globals.limit_conn_str = globals.conn_str;
|
||||
}
|
||||
} else {
|
||||
mongoc_uri_destroy(uri);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid connection-string: %s\n", globals.conn_str);
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(var, "limit-connection-string")) {
|
||||
if (zstr(val)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missing limit-connection-string - using connection-string instead\n");
|
||||
continue;
|
||||
} else {
|
||||
mongoc_uri_t *uri;
|
||||
globals.limit_conn_str = switch_core_strdup(pool, val);
|
||||
uri = mongoc_uri_new(globals.limit_conn_str);
|
||||
if (uri) {
|
||||
globals.limit_client_pool = mongoc_client_pool_new(uri);
|
||||
mongoc_uri_destroy(uri);
|
||||
if (!globals.limit_client_pool) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to pool for limit-connection-string: %s\n", globals.limit_conn_str);
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
mongoc_uri_destroy(uri);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid limit-connection-string: %s\n", globals.limit_conn_str);
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(var, "limit-database")) {
|
||||
if (zstr(val)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missing limit-database - using '%s'\n", globals.limit_database);
|
||||
} else {
|
||||
globals.limit_database = switch_core_strdup(pool, val);
|
||||
}
|
||||
} else if (!strcmp(var, "limit-collection")) {
|
||||
if (zstr(val)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missing limit-collection - using '%s'\n", globals.limit_collection);
|
||||
} else {
|
||||
globals.limit_collection = switch_core_strdup(pool, val);
|
||||
}
|
||||
} else if (!strcmp(var, "limit-cleanup-interval-sec")) {
|
||||
if (zstr(val) || !switch_is_number(val)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "bad value of limit-cleanup-interval-sec\n");
|
||||
} else {
|
||||
int new_interval = atoi(val);
|
||||
if (new_interval >= 0) {
|
||||
globals.limit_cleanup_interval_sec = new_interval;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "limit-cleanup-interval-sec must be >= 0\n");
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(var, "map")) {
|
||||
if (!zstr(val)) {
|
||||
globals.map = switch_core_strdup(pool, val);
|
||||
|
@ -435,29 +865,69 @@ done:
|
|||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load)
|
||||
{
|
||||
switch_api_interface_t *api_interface;
|
||||
switch_api_interface_t *api_interface = NULL;
|
||||
switch_limit_interface_t *limit_interface = NULL;
|
||||
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
|
||||
if (config(pool) != SWITCH_STATUS_SUCCESS) {
|
||||
if (do_config(pool) != SWITCH_STATUS_SUCCESS) {
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
SWITCH_ADD_API(api_interface, "mongo_find_one", "findOne", mongo_find_one_function, FIND_ONE_SYNTAX);
|
||||
SWITCH_ADD_API(api_interface, "mongo_find_n", "find", mongo_find_n_function, FIND_N_SYNTAX);
|
||||
SWITCH_ADD_API(api_interface, "mongo_mapreduce", "Map/Reduce", mongo_mapreduce_function, MAPREDUCE_SYNTAX);
|
||||
switch_mutex_init(&globals.mod_mongo_private_mutex, SWITCH_MUTEX_UNNESTED, pool);
|
||||
switch_thread_rwlock_create(&globals.limit_database_rwlock, pool);
|
||||
switch_thread_rwlock_create(&globals.shutdown_rwlock, pool);
|
||||
|
||||
/* clear all entries */
|
||||
mod_mongo_reset();
|
||||
|
||||
SWITCH_ADD_API(api_interface, "mongo_find_one", "findOne", mod_mongo_find_one_function, FIND_ONE_SYNTAX);
|
||||
SWITCH_ADD_API(api_interface, "mongo_find_n", "find", mod_mongo_find_n_function, FIND_N_SYNTAX);
|
||||
SWITCH_ADD_API(api_interface, "mongo_mapreduce", "Map/Reduce", mod_mongo_mapreduce_function, MAPREDUCE_SYNTAX);
|
||||
|
||||
SWITCH_ADD_LIMIT(limit_interface, "mongo", mod_mongo_limit_incr, mod_mongo_limit_release, mod_mongo_limit_usage, mod_mongo_limit_reset, mod_mongo_limit_status, NULL);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Periodically cleanup mongo limit counters
|
||||
*/
|
||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_mongo_runtime)
|
||||
{
|
||||
switch_interval_time_t cleanup_time = switch_micro_time_now() + (globals.limit_cleanup_interval_sec * 1000 * 1000);
|
||||
switch_thread_rwlock_rdlock(globals.shutdown_rwlock);
|
||||
while(!globals.shutdown && globals.limit_cleanup_interval_sec) {
|
||||
switch_micro_sleep(1 * 1000 * 1000);
|
||||
if (!globals.shutdown && switch_micro_time_now() > cleanup_time) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cleanup\n");
|
||||
mod_mongo_cleanup();
|
||||
cleanup_time = switch_micro_time_now() + (globals.limit_cleanup_interval_sec * 1000 * 1000);
|
||||
}
|
||||
}
|
||||
switch_thread_rwlock_unlock(globals.shutdown_rwlock);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown)
|
||||
{
|
||||
globals.shutdown = 1;
|
||||
switch_thread_rwlock_wrlock(globals.shutdown_rwlock);
|
||||
switch_thread_rwlock_unlock(globals.shutdown_rwlock);
|
||||
if (globals.limit_client_pool && globals.limit_client_pool != globals.client_pool) {
|
||||
mongoc_client_pool_destroy(globals.limit_client_pool);
|
||||
globals.limit_client_pool = NULL;
|
||||
}
|
||||
if (globals.client_pool) {
|
||||
mongoc_client_pool_destroy(globals.client_pool);
|
||||
globals.client_pool = NULL;
|
||||
}
|
||||
if (globals.mod_mongo_private_mutex) {
|
||||
switch_mutex_destroy(globals.mod_mongo_private_mutex);
|
||||
globals.mod_mongo_private_mutex = NULL;
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,11 @@ int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len)
|
|||
do {
|
||||
if ((stat = decode_length(buf, len, &ptr, &count)) < 0)
|
||||
return -1;
|
||||
if ((total_count + count) >= 16) {
|
||||
/* There is too much stuff here to be real, and it would overflow the bufs array
|
||||
if we continue */
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i]) != 0)
|
||||
return -1;
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -137,7 +137,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -152,7 +152,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -170,7 +170,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -186,7 +186,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -203,7 +203,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -218,7 +218,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -235,7 +235,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -145,7 +145,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -160,7 +160,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -178,7 +178,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>APT_LIB_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -194,7 +194,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -211,7 +211,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -226,7 +226,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -243,7 +243,7 @@
|
|||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-1.5.4/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../../libs/flite-2.0.0/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
|
|
@ -5,7 +5,7 @@ VERSION=201501231218
|
|||
|
||||
if ISLINUX
|
||||
|
||||
G729INSTALLER = $(top_srcdir)/libs/fsg729-$(VERSION)-installer
|
||||
G729INSTALLER = $(top_srcdir)/libs/fs-$(VERSION)-installer
|
||||
LICSERVER=/usr/sbin/freeswitch_licence_server
|
||||
VALIDATOR=$(bindir)/validator
|
||||
MOD=$(moddir)/mod_com_g729.so
|
||||
|
|
|
@ -72,7 +72,8 @@ static opus_codec_settings_t default_codec_settings = {
|
|||
struct opus_context {
|
||||
OpusEncoder *encoder_object;
|
||||
OpusDecoder *decoder_object;
|
||||
int frame_size;
|
||||
uint32_t enc_frame_size;
|
||||
uint32_t dec_frame_size;
|
||||
};
|
||||
|
||||
struct {
|
||||
|
@ -237,7 +238,8 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
context->frame_size = codec->implementation->samples_per_packet;
|
||||
context->enc_frame_size = codec->implementation->actual_samples_per_second * (codec->implementation->microseconds_per_packet / 1000) / 1000;
|
||||
|
||||
|
||||
memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
|
||||
codec_fmtp.private_info = &opus_codec_settings;
|
||||
|
@ -373,16 +375,13 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec,
|
|||
struct opus_context *context = codec->private_info;
|
||||
int bytes = 0;
|
||||
int len = (int) *encoded_data_len;
|
||||
|
||||
|
||||
if (!context) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (len > 2880) len = 2880;
|
||||
|
||||
bytes = opus_encode(context->encoder_object, (void *) decoded_data,
|
||||
decoded_data_len / 2 / codec->implementation->number_of_channels, (unsigned char *) encoded_data, len);
|
||||
|
||||
|
||||
bytes = opus_encode(context->encoder_object, (void *) decoded_data, context->enc_frame_size, (unsigned char *) encoded_data, len);
|
||||
|
||||
if (bytes > 0) {
|
||||
*encoded_data_len = (uint32_t) bytes;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
@ -548,7 +547,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
|||
}
|
||||
|
||||
|
||||
samples = 80;
|
||||
samples = 480;
|
||||
bytes = 160;
|
||||
mss = 10000;
|
||||
rate = 8000;
|
||||
|
@ -600,7 +599,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
|||
switch_opus_destroy); /* deinitalize a codec handle using this implementation */
|
||||
|
||||
bytes += 160;
|
||||
samples += 80;
|
||||
samples += 480;
|
||||
mss += 10000;
|
||||
|
||||
}
|
||||
|
|
|
@ -647,7 +647,6 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE);
|
||||
is_proxy = (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA));
|
||||
is_3pcc = (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC));
|
||||
|
@ -665,15 +664,16 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
/* This if statement check and handles the 3pcc proxy mode */
|
||||
if (is_3pcc) {
|
||||
|
||||
switch_channel_set_flag(channel, CF_3PCC);
|
||||
if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY))) {
|
||||
switch_channel_set_flag(channel, CF_3PCC);
|
||||
}
|
||||
|
||||
if(!is_proxy) {
|
||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||
tech_pvt->mparams.local_sdp_str = NULL;
|
||||
if (!is_proxy) {
|
||||
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE);
|
||||
tech_pvt->mparams.local_sdp_str = NULL;
|
||||
|
||||
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||
switch_core_session_set_ice(session);
|
||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
||||
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
||||
} else {
|
||||
switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE);
|
||||
|
||||
|
|
|
@ -4303,9 +4303,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
|||
}
|
||||
} else if (!strcasecmp(var, "tls-always-nat")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_TCP_ALWAYS_NAT);
|
||||
sofia_set_pflag(profile, PFLAG_TLS_ALWAYS_NAT);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_TCP_ALWAYS_NAT);
|
||||
sofia_clear_pflag(profile, PFLAG_TLS_ALWAYS_NAT);
|
||||
}
|
||||
} else if (!strcasecmp(var, "presence-proto-lookup")) {
|
||||
if (switch_true(val)) {
|
||||
|
@ -6111,6 +6111,10 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
|||
switch_ivr_session_transfer(a_session, p_contact->m_url->url_user, sip_redirect_dialplan, sip_redirect_context);
|
||||
}
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION);
|
||||
} else if( !p_contact->m_url->url_host ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Received redirect with invalid URI\n");
|
||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "REDIRECT_ERROR");
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
} else if ((!strcmp(profile->sipip, p_contact->m_url->url_host))
|
||||
|| (profile->extsipip && !strcmp(profile->extsipip, p_contact->m_url->url_host))
|
||||
|| (switch_xml_locate_domain(p_contact->m_url->url_host, NULL, &root, &domain) == SWITCH_STATUS_SUCCESS)) {
|
||||
|
|
|
@ -167,6 +167,9 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
|
|||
tech_pvt->mparams.rtp_timeout_sec = profile->rtp_timeout_sec;
|
||||
tech_pvt->mparams.rtp_hold_timeout_sec = profile->rtp_hold_timeout_sec;
|
||||
|
||||
if (profile->rtp_digit_delay) {
|
||||
tech_pvt->mparams.dtmf_delay = profile->rtp_digit_delay;
|
||||
}
|
||||
|
||||
switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
|
||||
switch_media_handle_set_media_flags(tech_pvt->media_handle, tech_pvt->profile->media_flags);
|
||||
|
@ -696,6 +699,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
|||
char *record_route = NULL;
|
||||
const char *recover_via = NULL;
|
||||
int require_timer = 1;
|
||||
uint8_t is_t38 = 0;
|
||||
|
||||
if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING)) {
|
||||
const char *recover_contact = switch_channel_get_variable(tech_pvt->channel, "sip_recover_contact");
|
||||
|
@ -1235,9 +1239,14 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
|||
|
||||
|
||||
|
||||
if (switch_channel_get_private(tech_pvt->channel, "t38_options")) {
|
||||
if ((switch_channel_get_private(tech_pvt->channel, "t38_options")) ||
|
||||
((sofia_test_flag(tech_pvt, TFLAG_INB_NOMEDIA) ||
|
||||
sofia_test_flag(tech_pvt, TFLAG_PROXY_MEDIA) ||
|
||||
switch_true(switch_channel_get_variable(tech_pvt->channel, SWITCH_BYPASS_MEDIA_VARIABLE)) )
|
||||
&& switch_stristr("m=image", tech_pvt->mparams.local_sdp_str))) {
|
||||
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
|
||||
}
|
||||
is_t38 = 1;
|
||||
}
|
||||
|
||||
if (sofia_use_soa(tech_pvt)) {
|
||||
nua_invite(tech_pvt->nh,
|
||||
|
@ -1272,7 +1281,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
|||
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_ADDRESS(tech_pvt->mparams.adv_sdp_audio_ip)),
|
||||
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)),
|
||||
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_REUSE_REJECTED(1)),
|
||||
TAG_IF(switch_channel_get_private(tech_pvt->channel, "t38_options"), SOATAG_ORDERED_USER(1)),
|
||||
TAG_IF(is_t38, SOATAG_ORDERED_USER(1)),
|
||||
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)),
|
||||
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)),
|
||||
TAG_IF(rep, SIPTAG_REPLACES_STR(rep)),
|
||||
|
|
|
@ -2201,9 +2201,23 @@ static void _send_presence_notify(sofia_profile_t *profile,
|
|||
path = sofia_glue_get_path_from_contact((char *) o_contact);
|
||||
}
|
||||
|
||||
tmp = (char *)o_contact;
|
||||
o_contact_dup = sofia_glue_get_url_from_contact(tmp, 1);
|
||||
dst = sofia_glue_get_destination((char *) o_contact);
|
||||
switch_assert(dst);
|
||||
|
||||
if (!zstr(dst->contact)) {
|
||||
contact = sofia_glue_get_url_from_contact(dst->contact, 1);
|
||||
} else {
|
||||
contact = strdup(o_contact);
|
||||
}
|
||||
|
||||
if (dst->route_uri) {
|
||||
route_uri = sofia_glue_strip_uri(dst->route_uri);
|
||||
tmp = (char *)route_uri;
|
||||
} else {
|
||||
tmp = (char *)o_contact;
|
||||
}
|
||||
|
||||
o_contact_dup = sofia_glue_get_url_from_contact(tmp, 1);
|
||||
|
||||
if ((tp = switch_stristr("transport=", o_contact_dup))) {
|
||||
tp += 10;
|
||||
|
@ -2272,19 +2286,6 @@ static void _send_presence_notify(sofia_profile_t *profile,
|
|||
free(to_uri);
|
||||
}
|
||||
|
||||
dst = sofia_glue_get_destination((char *) o_contact);
|
||||
switch_assert(dst);
|
||||
|
||||
if (!zstr(dst->contact)) {
|
||||
contact = sofia_glue_get_url_from_contact(dst->contact, 1);
|
||||
} else {
|
||||
contact = strdup(o_contact);
|
||||
}
|
||||
|
||||
if (dst->route_uri) {
|
||||
route_uri = sofia_glue_strip_uri(dst->route_uri);
|
||||
}
|
||||
|
||||
if (expires) {
|
||||
long ltmp = atol(expires);
|
||||
|
||||
|
@ -4023,7 +4024,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||
char *sticky = NULL;
|
||||
char *contactstr = profile->url, *cs = NULL;
|
||||
char *p = NULL, *new_contactstr = NULL;
|
||||
|
||||
sofia_transport_t transport;
|
||||
|
||||
if (np.is_nat) {
|
||||
char params[128] = "";
|
||||
|
@ -4040,20 +4041,23 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||
contactstr = profile->url;
|
||||
}
|
||||
|
||||
if (sip->sip_via) {
|
||||
transport = sofia_glue_via2transport(sip->sip_via);
|
||||
} else {
|
||||
transport = sofia_glue_url2transport(contact->m_url);
|
||||
}
|
||||
|
||||
if (switch_stristr("port=tcp", contact->m_url->url_params)) {
|
||||
if (transport == SOFIA_TRANSPORT_TCP) {
|
||||
if (np.is_auto_nat) {
|
||||
cs = profile->tcp_public_contact;
|
||||
} else {
|
||||
cs = profile->tcp_contact;
|
||||
}
|
||||
} else if (switch_stristr("port=tls", contact->m_url->url_params)) {
|
||||
} else if (transport == SOFIA_TRANSPORT_TCP_TLS) {
|
||||
if (np.is_auto_nat) {
|
||||
cs = sofia_test_pflag(profile, PFLAG_TLS) ?
|
||||
profile->tls_public_contact : profile->tcp_public_contact;
|
||||
cs = sofia_test_pflag(profile, PFLAG_TLS) ? profile->tls_public_contact : profile->tcp_public_contact;
|
||||
} else {
|
||||
cs = sofia_test_pflag(profile, PFLAG_TLS) ?
|
||||
profile->tls_contact : profile->tcp_contact;
|
||||
cs = sofia_test_pflag(profile, PFLAG_TLS) ? profile->tls_contact : profile->tcp_contact;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -932,6 +932,10 @@ static switch_bool_t check_auth(jsock_t *jsock, cJSON *params, int *code, char *
|
|||
|
||||
}
|
||||
|
||||
if (jsock->profile->register_domain) {
|
||||
domain = jsock->profile->register_domain;
|
||||
}
|
||||
|
||||
if (!(id && domain)) {
|
||||
*code = CODE_AUTH_FAILED;
|
||||
switch_snprintf(message, mlen, "Missing or improper credentials");
|
||||
|
@ -953,9 +957,6 @@ static switch_bool_t check_auth(jsock_t *jsock, cJSON *params, int *code, char *
|
|||
switch_event_add_header_string(req_params, SWITCH_STACK_BOTTOM, i->string, i->valuestring);
|
||||
}
|
||||
}
|
||||
|
||||
DUMP_EVENT(req_params);
|
||||
|
||||
}
|
||||
|
||||
switch_event_add_header_string(req_params, SWITCH_STACK_BOTTOM, "action", "jsonrpc-authenticate");
|
||||
|
@ -4226,6 +4227,8 @@ static switch_status_t parse_config(const char *cf)
|
|||
profile->mcast_port = (switch_port_t) atoi(val);
|
||||
} else if (!strcasecmp(var, "timer-name") && !zstr(var)) {
|
||||
profile->timer_name = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "force-register-domain") && !zstr(val)) {
|
||||
profile->register_domain = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "local-network") && !zstr(val)) {
|
||||
profile->local_network = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "apply-candidate-acl")) {
|
||||
|
|
|
@ -249,6 +249,8 @@ struct verto_profile_s {
|
|||
|
||||
verto_vhost_t *vhosts;
|
||||
|
||||
char *register_domain;
|
||||
|
||||
struct verto_profile_s *next;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
include $(top_srcdir)/build/modmake.rulesam
|
||||
MODNAME=mod_amqp
|
||||
|
||||
if HAVE_AMQP
|
||||
|
||||
mod_LTLIBRARIES = mod_amqp.la
|
||||
mod_amqp_la_SOURCES = mod_amqp_utils.c mod_amqp_connection.c mod_amqp_producer.c mod_amqp_command.c mod_amqp.c
|
||||
mod_amqp_la_CFLAGS = $(AM_CFLAGS) $(AMQP_CFLAGS)
|
||||
mod_amqp_la_LIBADD = $(switch_builddir)/libfreeswitch.la
|
||||
mod_amqp_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(AMQP_LIBS) $(SWITCH_AM_LDFLAGS)
|
||||
|
||||
else
|
||||
install: error
|
||||
all: error
|
||||
error:
|
||||
$(error You must install librabbitmq1 and librabbitmq-dev to build this module)
|
||||
endif
|
|
@ -0,0 +1,121 @@
|
|||
_
|
||||
_ __ ___ ___ __| | __ _ _ __ ___ __ _ _ __
|
||||
| '_ ` _ \ / _ \ / _` | / _` | '_ ` _ \ / _` | '_ \
|
||||
| | | | | | (_) | (_| | | (_| | | | | | | (_| | |_) |
|
||||
|_| |_| |_|\___/ \__,_|___\__,_|_| |_| |_|\__, | .__/
|
||||
|_____| |_|_| by Aeriandi
|
||||
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
1. Features
|
||||
2. How to build and install
|
||||
3. Configuration
|
||||
4. Usage
|
||||
5. Trouleshooting
|
||||
|
||||
6. Notes
|
||||
|
||||
|
||||
|
||||
1. Features
|
||||
-----------
|
||||
|
||||
* Authenticates with an AMQP broker such as RabbitMQ.
|
||||
* If the broker disconnects, the connection is retried.
|
||||
* Routing keys can include values from Freeswitch message headers.
|
||||
* The rate of messages pulished can be limited by filtering event types.
|
||||
* Messages are sent asynchronously so as not to block the Freeswitch core.
|
||||
* Pulishing can be temporarily suspended on the event of "back pressure" from the AMQP broker.
|
||||
|
||||
|
||||
|
||||
2. How to build and install
|
||||
---------------------------
|
||||
|
||||
Requires librabbitmq1 to build. Debian Jessie comes with the correct version.
|
||||
|
||||
|
||||
3. Configuration
|
||||
----------------
|
||||
|
||||
All configuration is done within the amqp.conf.xml file located in the freeswitch/autoload_configs folder, which is usually in /etc/ for linux based machines.
|
||||
|
||||
The file is of the format:
|
||||
|
||||
<configuration name="amqp.conf" description="mod_amqp">
|
||||
<settings>
|
||||
<param name="parameter1" value="value1"/>
|
||||
<param name="parameter2" value="value2"/>
|
||||
...etc.
|
||||
</settings>
|
||||
</configuration>
|
||||
|
||||
|
||||
Available parameters are as follows:
|
||||
|
||||
+------------------------------+-----------------------------------+
|
||||
| name | default value (units) |
|
||||
|------------------------------+-----------------------------------|
|
||||
| amqpHostnames | localhost |
|
||||
| amqpVirtualHost | / |
|
||||
| amqpPort | 5672 |
|
||||
| amqpUsername | guest |
|
||||
| amqpPassword | guest |
|
||||
| amqpHeartbeatSeconds | 0 (s) |
|
||||
| eventExchange | TAP.Events |
|
||||
| eventExchangetype | topic |
|
||||
| eventRoutingKeyFormat | %s.%s.%s.%s |
|
||||
| eventRoutingKeyFormatFields | FreeSWITCH-Hostname,Event-Name, |
|
||||
| | Event-Subclass,Unique-ID |
|
||||
| eventFilter | SWITCH_EVENT_CHANNEL_CREATE, |
|
||||
| | SWITCH_EVENT_CHANNEL_DESTROY, |
|
||||
| | SWITCH_EVENT_HEARTBEAT, |
|
||||
| | SWITCH_EVENT_DTMF |
|
||||
| commandExchange | TAP.Commands |
|
||||
| commandExchangeType | topic |
|
||||
| commandBindingKey | TapCommands |
|
||||
| amqpSendQueueSize | 500 (events) |
|
||||
| amqpCircuitBreakerTimeout | 10000 (ms) |
|
||||
| amqpReconnectInterval | 1000 (ms) |
|
||||
+------------------------------+-----------------------------------+
|
||||
|
||||
Set the amqpHostname and amqpPort to point to the AMQP broker, and set valid login credentials using amqpUsername and amqpPassword.
|
||||
|
||||
The routing key is made from the eventRoutingKeyFormat format string using the freeswitch event header values specified in the eventRoutingKeyFormatFields. See the manpage printf(1) for more information about format strings. The numer of percent marks in the format string must match the number of comma-separated header names in the format fields string.
|
||||
|
||||
mod_amqp has an internal buffer for events so that it can send them asynchronously and also cope with the connection going down for a short amount of time. The size of this buffer is set by amqpSendQueueSize. If this buffer ever becomes full, then mod_amqp will drop event messages for the period of time specified by amqpCircuitBreakerTimeout (in milliseconds).
|
||||
|
||||
If the connection to the AMQP broker is severed, mod_amqp will attempt to reconnect regularly according to the amqpReconnectInterval (in milliseconds). It will cycle through the hostnames provided in amqpHostnames.
|
||||
|
||||
The eventFilter parameter specifies which events will be sent to the AMQP broker, a full list of available options can be found in src/include/switch_types.h. The special event name SWITCH_EVENT_ALL causes all events to be sent, effectively disabling the filter.
|
||||
|
||||
|
||||
4. Usage
|
||||
--------
|
||||
|
||||
Usually, mod_amqp will be loaded automatically when Freeswitch starts. To establish whether the module has been loaded, you can execute "module_exists mod_amqp" in fs_cli.
|
||||
|
||||
If the module is not set to load with Freeswitch, it can be loaded on he fly by executing "load mod_amqp" from fs_cli. You'll see a few lines of status messages as the module loads and tries to connect to the AMQP roker. Conversely, the module can be unloaded using "unload mod_amqp".
|
||||
|
||||
To effect new settings having edited the config file, the module should be unloaded then loaded again.
|
||||
|
||||
|
||||
|
||||
5. Trouleshooting
|
||||
-----------------
|
||||
|
||||
Any errors or warnings will be reported using Freeswitch logging, so check for errors using fs_cli with the loglevel is set to be sufficiently verbose, or with your selected logging module; for example, the syslog logger.
|
||||
|
||||
Typically, messages not being received by the AMQP broker is due to network connectivity or failed authentication with the broker.
|
||||
|
||||
If mod_amqp experiences back-pressure from the AMQP broker, its internal buffer of events to send fills up. When this buffer is half full, warning messages are logged, and when the queue is completely full the circuit breaker will be triggered, logging an error and dropping events for the predefined amount of time.
|
||||
|
||||
|
||||
|
||||
6. Notes
|
||||
--------
|
||||
|
||||
The SHA for the revision of librabbitmq-c1 that is included is 1c213703c9fdd747bc71ea4f64943c3b4269f8cf.
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2012, 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.
|
||||
*
|
||||
* Based on mod_skel by
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Daniel Bryars <danb@aeriandi.com>
|
||||
* Tim Brown <tim.brown@aeriandi.com>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
* Mike Jerris <mike@jerris.com>
|
||||
*
|
||||
* mod_amqp.c -- Sends FreeSWITCH events to an AMQP broker
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mod_amqp.h"
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_amqp_shutdown);
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_amqp_load);
|
||||
SWITCH_MODULE_DEFINITION(mod_amqp, mod_amqp_load, mod_amqp_shutdown, NULL);
|
||||
|
||||
SWITCH_STANDARD_API(amqp_reload)
|
||||
{
|
||||
return mod_amqp_do_config(SWITCH_TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------
|
||||
Startup
|
||||
------------------------------
|
||||
*/
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_amqp_load)
|
||||
{
|
||||
switch_api_interface_t *api_interface;
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
globals.pool = pool;
|
||||
switch_core_hash_init(&(globals.producer_hash));
|
||||
switch_core_hash_init(&(globals.command_hash));
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "mod_apqp loading: Version %s\n", switch_version_full());
|
||||
|
||||
/* Create producer profiles */
|
||||
if ( mod_amqp_do_config(SWITCH_FALSE) != SWITCH_STATUS_SUCCESS ){
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
SWITCH_ADD_API(api_interface, "amqp", "amqp API", amqp_reload, "syntax");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ------------------------------
|
||||
Shutdown
|
||||
------------------------------
|
||||
*/
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_amqp_shutdown)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
mod_amqp_producer_profile_t *producer;
|
||||
mod_amqp_command_profile_t *command;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mod starting shutting down\n");
|
||||
switch_event_unbind_callback(mod_amqp_producer_event_handler);
|
||||
|
||||
while ((hi = switch_core_hash_first(globals.producer_hash))) {
|
||||
switch_core_hash_this(hi, NULL, NULL, (void **)&producer);
|
||||
mod_amqp_producer_destroy(&producer);
|
||||
}
|
||||
|
||||
while ((hi = switch_core_hash_first(globals.command_hash))) {
|
||||
switch_core_hash_this(hi, NULL, NULL, (void **)&command);
|
||||
mod_amqp_command_destroy(&command);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mod finished shutting down\n");
|
||||
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,168 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2012, 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.
|
||||
*
|
||||
* Based on mod_skel by
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Daniel Bryars <danb@aeriandi.com>
|
||||
* Tim Brown <tim.brown@aeriandi.com>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
* Mike Jerris <mike@jerris.com>
|
||||
*
|
||||
* mod_amqp.c -- Sends FreeSWITCH events to an AMQP broker
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MOD_AMQP_H
|
||||
#define MOD_AMQP_H
|
||||
|
||||
#include <switch.h>
|
||||
#include <amqp.h>
|
||||
#include <amqp_framing.h>
|
||||
#include <amqp_tcp_socket.h>
|
||||
#include <strings.h>
|
||||
|
||||
#define MAX_LOG_MESSAGE_SIZE 1024
|
||||
#define AMQP_MAX_HOSTS 4
|
||||
|
||||
/* If you change MAX_ROUTING_KEY_FORMAT_FIELDS then you must change the implementation of makeRoutingKey where it formats the routing key using sprintf */
|
||||
#define MAX_ROUTING_KEY_FORMAT_FIELDS 10
|
||||
#define MAX_AMQP_ROUTING_KEY_LENGTH 255
|
||||
|
||||
#define TIME_STATS_TO_AGGREGATE 1024
|
||||
#define MOD_AMQP_DEBUG_TIMING 0
|
||||
|
||||
|
||||
typedef struct {
|
||||
char routing_key[MAX_AMQP_ROUTING_KEY_LENGTH];
|
||||
char *pjson;
|
||||
} mod_amqp_message_t;
|
||||
|
||||
typedef struct mod_amqp_connection_s {
|
||||
char *name;
|
||||
char *hostname;
|
||||
char *virtualhost;
|
||||
char *username;
|
||||
char *password;
|
||||
unsigned int port;
|
||||
unsigned int heartbeat; /* in seconds */
|
||||
amqp_connection_state_t state;
|
||||
|
||||
struct mod_amqp_connection_s *next;
|
||||
} mod_amqp_connection_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
||||
char *exchange;
|
||||
char *exchange_type;
|
||||
char *format_fields[MAX_ROUTING_KEY_FORMAT_FIELDS+1];
|
||||
|
||||
/* Array to store the possible event subscriptions */
|
||||
int event_subscriptions;
|
||||
switch_event_node_t *event_nodes[SWITCH_EVENT_ALL];
|
||||
switch_event_types_t event_ids[SWITCH_EVENT_ALL];
|
||||
switch_event_node_t *eventNode;
|
||||
|
||||
|
||||
/* Because only the 'running' thread will be reading or writing to the two connection pointers
|
||||
* this does not 'yet' need a read/write lock. Before these structures can be destroyed,
|
||||
* the running thread must be joined first.
|
||||
*/
|
||||
mod_amqp_connection_t *conn_root;
|
||||
mod_amqp_connection_t *conn_active;
|
||||
|
||||
/* Rabbit connections are not thread safe so one connection per thread.
|
||||
Communicate with sender thread using a queue */
|
||||
switch_thread_t *producer_thread;
|
||||
switch_queue_t *send_queue;
|
||||
unsigned int send_queue_size;
|
||||
|
||||
int reconnect_interval_ms;
|
||||
int circuit_breaker_ms;
|
||||
switch_time_t circuit_breaker_reset_time;
|
||||
switch_bool_t enable_fallback_format_fields;
|
||||
|
||||
switch_bool_t running;
|
||||
switch_memory_pool_t *pool;
|
||||
char *custom_attr;
|
||||
} mod_amqp_producer_profile_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
||||
char *exchange;
|
||||
char *binding_key;
|
||||
|
||||
/* Note: The AMQP channel is not reentrant this MUTEX serializes sending events. */
|
||||
mod_amqp_connection_t *conn_root;
|
||||
mod_amqp_connection_t *conn_active;
|
||||
|
||||
int reconnect_interval_ms;
|
||||
|
||||
/* Listener thread */
|
||||
switch_thread_t *command_thread;
|
||||
|
||||
switch_mutex_t *mutex;
|
||||
switch_bool_t running;
|
||||
switch_memory_pool_t *pool;
|
||||
char *custom_attr;
|
||||
} mod_amqp_command_profile_t;
|
||||
|
||||
struct {
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
switch_hash_t *producer_hash;
|
||||
switch_hash_t *command_hash;
|
||||
} globals;
|
||||
|
||||
/* utils */
|
||||
switch_status_t mod_amqp_do_config(switch_bool_t reload);
|
||||
int mod_amqp_log_if_amqp_error(amqp_rpc_reply_t x, char const *context);
|
||||
int mod_amqp_count_chars(const char* string, char ch);
|
||||
|
||||
/* connection */
|
||||
switch_status_t mod_amqp_connection_create(mod_amqp_connection_t **conn, switch_xml_t cfg, switch_memory_pool_t *pool);
|
||||
void mod_amqp_connection_destroy(mod_amqp_connection_t **conn);
|
||||
void mod_amqp_connection_close(mod_amqp_connection_t *connection);
|
||||
switch_status_t mod_amqp_connection_open(mod_amqp_connection_t *connections, mod_amqp_connection_t **active, char *profile_name, char *custom_attr);
|
||||
|
||||
/* command */
|
||||
switch_status_t mod_amqp_command_destroy(mod_amqp_command_profile_t **profile);
|
||||
switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg);
|
||||
void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void *data);
|
||||
|
||||
/* producer */
|
||||
void mod_amqp_producer_event_handler(switch_event_t* evt);
|
||||
switch_status_t mod_amqp_producer_routing_key(mod_amqp_producer_profile_t *profile, char routingKey[MAX_AMQP_ROUTING_KEY_LENGTH],
|
||||
switch_event_t* evt, char* routingKeyEventHeaderNames[]);
|
||||
switch_status_t mod_amqp_producer_destroy(mod_amqp_producer_profile_t **profile);
|
||||
switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg);
|
||||
void * SWITCH_THREAD_FUNC mod_amqp_producer_thread(switch_thread_t *thread, void *data);
|
||||
|
||||
|
||||
#endif /* MOD_AMQP_H */
|
||||
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2012, 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.
|
||||
*
|
||||
* Based on mod_skel by
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Daniel Bryars <danb@aeriandi.com>
|
||||
* Tim Brown <tim.brown@aeriandi.com>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
* Mike Jerris <mike@jerris.com>
|
||||
*
|
||||
* mod_amqp.c -- Sends FreeSWITCH events to an AMQP broker
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mod_amqp.h"
|
||||
|
||||
switch_status_t mod_amqp_command_destroy(mod_amqp_command_profile_t **prof)
|
||||
{
|
||||
switch_status_t ret;
|
||||
mod_amqp_connection_t *conn = NULL, *conn_next = NULL;
|
||||
switch_memory_pool_t *pool;
|
||||
mod_amqp_command_profile_t *profile;
|
||||
|
||||
if (!prof || !*prof) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
profile = *prof;
|
||||
pool = profile->pool;
|
||||
|
||||
if (profile->name) {
|
||||
switch_core_hash_delete(globals.command_hash, profile->name);
|
||||
}
|
||||
|
||||
profile->running = 0;
|
||||
|
||||
if (profile->command_thread) {
|
||||
switch_thread_join(&ret, profile->command_thread);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Profile[%s] closing AMQP socket...\n", profile->name);
|
||||
|
||||
for (conn = profile->conn_root; conn; conn = conn_next) {
|
||||
mod_amqp_connection_destroy(&conn);
|
||||
}
|
||||
|
||||
profile->conn_active = NULL;
|
||||
profile->conn_root = NULL;
|
||||
|
||||
if (pool) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
|
||||
*prof = NULL;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg)
|
||||
{
|
||||
mod_amqp_command_profile_t *profile = NULL;
|
||||
switch_xml_t params, param, connections, connection;
|
||||
switch_threadattr_t *thd_attr = NULL;
|
||||
switch_memory_pool_t *pool;
|
||||
char *exchange = NULL, *binding_key = NULL;
|
||||
|
||||
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
profile = switch_core_alloc(pool, sizeof(mod_amqp_command_profile_t));
|
||||
|
||||
profile->pool = pool;
|
||||
profile->name = switch_core_strdup(profile->pool, name);
|
||||
profile->running = 1;
|
||||
profile->reconnect_interval_ms = 1000;
|
||||
|
||||
if ((params = switch_xml_child(cfg, "params")) != NULL) {
|
||||
for (param = switch_xml_child(params, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
|
||||
if (!var) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param missing 'name' attribute\n", profile->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param[%s] missing 'value' attribute\n", profile->name, var);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strncmp(var, "reconnect_interval_ms", 21)) {
|
||||
int interval = atoi(val);
|
||||
if ( interval && interval > 0 ) {
|
||||
profile->reconnect_interval_ms = interval;
|
||||
}
|
||||
} else if (!strncmp(var, "exchange", 8)) {
|
||||
exchange = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strncmp(var, "binding_key", 11)) {
|
||||
binding_key = switch_core_strdup(profile->pool, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle defaults of string types */
|
||||
profile->exchange = exchange ? exchange : switch_core_strdup(profile->pool, "TAP.Commands");
|
||||
profile->binding_key = binding_key ? binding_key : switch_core_strdup(profile->pool, "commandBindingKey");
|
||||
|
||||
if ((connections = switch_xml_child(cfg, "connections")) != NULL) {
|
||||
for (connection = switch_xml_child(connections, "connection"); connection; connection = connection->next) {
|
||||
if ( ! profile->conn_root ) { /* Handle first root node */
|
||||
if (mod_amqp_connection_create(&(profile->conn_root), connection, profile->pool) != SWITCH_STATUS_SUCCESS) {
|
||||
/* Handle connection create failure */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create connection\n", profile->name);
|
||||
continue;
|
||||
}
|
||||
profile->conn_active = profile->conn_root;
|
||||
} else {
|
||||
if (mod_amqp_connection_create(&(profile->conn_active->next), connection, profile->pool) != SWITCH_STATUS_SUCCESS) {
|
||||
/* Handle connection create failure */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create connection\n", profile->name);
|
||||
continue;
|
||||
}
|
||||
profile->conn_active = profile->conn_active->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
profile->conn_active = NULL;
|
||||
|
||||
if ( mod_amqp_connection_open(profile->conn_root, &(profile->conn_active), profile->name, profile->custom_attr) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] was unable to connect to any connection\n", profile->name);
|
||||
}
|
||||
|
||||
/* Start the worker threads */
|
||||
switch_threadattr_create(&thd_attr, profile->pool);
|
||||
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
||||
|
||||
if (switch_thread_create(&profile->command_thread, thd_attr, mod_amqp_command_thread, profile, profile->pool)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create 'amqp event sender' thread!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ( switch_core_hash_insert(globals.command_hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new profile [%s] into mod_amqp profile hash\n", name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
err:
|
||||
/* Cleanup */
|
||||
mod_amqp_command_destroy(&profile);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
|
||||
void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void *data)
|
||||
{
|
||||
mod_amqp_command_profile_t *profile = (mod_amqp_command_profile_t *) data;
|
||||
|
||||
while (profile->running) {
|
||||
amqp_queue_declare_ok_t *recv_queue;
|
||||
amqp_bytes_t queueName = { 0, NULL };
|
||||
|
||||
/* Ensure we have an AMQP connection */
|
||||
if (!profile->conn_active) {
|
||||
switch_status_t status;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Amqp no connection- reconnecting...\n");
|
||||
|
||||
status = mod_amqp_connection_open(profile->conn_root, &(profile->conn_active), profile->name, profile->custom_attr);
|
||||
if ( status != SWITCH_STATUS_SUCCESS ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to connect with code(%d), sleeping for %dms\n",
|
||||
profile->name, status, profile->reconnect_interval_ms);
|
||||
switch_sleep(profile->reconnect_interval_ms * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ensure we have a queue */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating command queue");
|
||||
recv_queue = amqp_queue_declare(profile->conn_active->state, // state
|
||||
1, // channel
|
||||
amqp_empty_bytes, // queue name
|
||||
0, 0, // passive, durable
|
||||
0, 1, // exclusive, auto-delete
|
||||
amqp_empty_table); // args
|
||||
|
||||
if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Declaring queue")) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to connect with code(%d), sleeping for %dms\n",
|
||||
profile->name, status, profile->reconnect_interval_ms);
|
||||
switch_sleep(profile->reconnect_interval_ms * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (queueName.bytes) {
|
||||
amqp_bytes_free(queueName);
|
||||
}
|
||||
|
||||
queueName = amqp_bytes_malloc_dup(recv_queue->queue);
|
||||
|
||||
if (!queueName.bytes) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory while copying queue name");
|
||||
break;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Created command queue %.*s", (int)queueName.len, (char *)queueName.bytes);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Binding command queue to exchange %s", profile->exchange);
|
||||
|
||||
/* Bind the queue to the exchange */
|
||||
amqp_queue_bind(profile->conn_active->state, // state
|
||||
1, // channel
|
||||
queueName, // queue
|
||||
amqp_cstring_bytes(profile->exchange), // exchange
|
||||
amqp_cstring_bytes(profile->binding_key), // routing key
|
||||
amqp_empty_table); // args
|
||||
|
||||
if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Binding queue")) {
|
||||
mod_amqp_connection_close(profile->conn_active);
|
||||
profile->conn_active = NULL;
|
||||
switch_sleep(profile->reconnect_interval_ms * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Amqp reconnect successful- connected\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start a command
|
||||
amqp_basic_consume(profile->conn_active->state, // state
|
||||
1, // channel
|
||||
queueName, // queue
|
||||
amqp_empty_bytes, // command tag
|
||||
0, 1, 0, // no_local, no_ack, exclusive
|
||||
amqp_empty_table); // args
|
||||
|
||||
if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Creating a command")) {
|
||||
mod_amqp_connection_close(profile->conn_active);
|
||||
profile->conn_active = NULL;
|
||||
switch_sleep(profile->reconnect_interval_ms * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (profile->running && profile->conn_active) {
|
||||
amqp_rpc_reply_t res;
|
||||
amqp_envelope_t envelope;
|
||||
struct timeval timeout = {0};
|
||||
char command[1024];
|
||||
enum ECommandFormat {
|
||||
COMMAND_FORMAT_UNKNOWN,
|
||||
COMMAND_FORMAT_PLAINTEXT
|
||||
} commandFormat = COMMAND_FORMAT_PLAINTEXT;
|
||||
|
||||
amqp_maybe_release_buffers(profile->conn_active->state);
|
||||
|
||||
timeout.tv_usec = 500 * 1000;
|
||||
res = amqp_consume_message(profile->conn_active->state, &envelope, &timeout, 0);
|
||||
|
||||
if (res.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION) {
|
||||
if (res.library_error == AMQP_STATUS_UNEXPECTED_STATE) {
|
||||
/* Unexpected frame. Discard it then continue */
|
||||
amqp_frame_t decoded_frame;
|
||||
amqp_simple_wait_frame(profile->conn_active->state, &decoded_frame);
|
||||
}
|
||||
|
||||
if (res.library_error == AMQP_STATUS_SOCKET_ERROR) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "A socket error occurred. Tearing down and reconnecting\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (res.library_error == AMQP_STATUS_CONNECTION_CLOSED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMQP connection was closed. Tearing down and reconnecting\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (res.library_error == AMQP_STATUS_TCP_ERROR) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "A TCP error occurred. Tearing down and reconnecting\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (res.library_error == AMQP_STATUS_TIMEOUT) {
|
||||
// nop
|
||||
}
|
||||
|
||||
/* Try consuming again */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res.reply_type != AMQP_RESPONSE_NORMAL) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Delivery:%u, exchange:%.*s routingkey:%.*s\n",
|
||||
(unsigned) envelope.delivery_tag, (int) envelope.exchange.len, (char *) envelope.exchange.bytes,
|
||||
(int) envelope.routing_key.len, (char *) envelope.routing_key.bytes);
|
||||
|
||||
if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Content-type: %.*s\n",
|
||||
(int) envelope.message.properties.content_type.len, (char *) envelope.message.properties.content_type.bytes);
|
||||
|
||||
if (strncasecmp("text/plain", envelope.message.properties.content_type.bytes, strlen("text/plain")) == 0) {
|
||||
commandFormat = COMMAND_FORMAT_PLAINTEXT;
|
||||
} else {
|
||||
commandFormat = COMMAND_FORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
if (commandFormat == COMMAND_FORMAT_PLAINTEXT) {
|
||||
switch_stream_handle_t stream = { 0 }; /* Collects the command output */
|
||||
|
||||
/* Convert amqp bytes to c-string */
|
||||
snprintf(command, sizeof(command), "%.*s", (int) envelope.message.body.len, (char *) envelope.message.body.bytes);
|
||||
|
||||
/* Execute the command */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Executing: %s\n", command);
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
if (switch_console_execute(command, 0, &stream) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Remote command failed:\n%s\n", (char *) stream.data);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote command succeeded:\n%s\n", (char *) stream.data);
|
||||
}
|
||||
switch_safe_free(stream.data);
|
||||
}
|
||||
|
||||
/* Tidy up */
|
||||
amqp_destroy_envelope(&envelope);
|
||||
}
|
||||
|
||||
amqp_bytes_free(queueName);
|
||||
queueName.bytes = NULL;
|
||||
|
||||
mod_amqp_connection_close(profile->conn_active);
|
||||
profile->conn_active = NULL;
|
||||
|
||||
if (profile->running) {
|
||||
/* We'll reconnect, but sleep to avoid hammering resources */
|
||||
switch_sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the thread */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Command listener thread stopped\n");
|
||||
switch_thread_exit(thread, SWITCH_STATUS_SUCCESS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
*/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue