Merge branch 'master' into v1.4 and bump rev
Conflicts: configure.ac
2
.gitignore
vendored
@ -111,7 +111,7 @@ Release/
|
|||||||
|
|
||||||
/libs/curl/lib/ca-bundle.h
|
/libs/curl/lib/ca-bundle.h
|
||||||
/libs/esl/fs_cli
|
/libs/esl/fs_cli
|
||||||
/libs/esl/ivrd
|
/libs/esl/fs_ivrd
|
||||||
/libs/esl/testclient
|
/libs/esl/testclient
|
||||||
/libs/esl/testserver
|
/libs/esl/testserver
|
||||||
/libs/freetdm/detect_dtmf
|
/libs/freetdm/detect_dtmf
|
||||||
|
@ -4132,11 +4132,13 @@ Global
|
|||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|Win32.ActiveCfg = Debug|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|Win32.Build.0 = Debug|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|x64.ActiveCfg = Debug|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|x64.ActiveCfg = Debug|Win32
|
||||||
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|x64.Build.0 = Debug|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|x64 Setup.ActiveCfg = Debug|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|x64 Setup.ActiveCfg = Debug|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|x86 Setup.ActiveCfg = Debug|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Debug|x86 Setup.ActiveCfg = Debug|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|Win32.ActiveCfg = Release|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|Win32.Build.0 = Release|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|Win32.Build.0 = Release|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|x64.ActiveCfg = Release|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|x64.ActiveCfg = Release|Win32
|
||||||
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|x64.Build.0 = Release|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|x64 Setup.ActiveCfg = Release|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|x64 Setup.ActiveCfg = Release|Win32
|
||||||
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|x86 Setup.ActiveCfg = Release|Win32
|
{5BE9A596-F11F-4379-928C-412F81AE182B}.Release|x86 Setup.ActiveCfg = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
@ -644,7 +644,9 @@ pa-reconf:
|
|||||||
|
|
||||||
srtp-reconf:
|
srtp-reconf:
|
||||||
cd libs/srtp && $(MAKE) clean
|
cd libs/srtp && $(MAKE) clean
|
||||||
cd libs/srtp && sh ./configure.gnu
|
cd libs/srtp && sh ./config.status --recheck
|
||||||
|
cd libs/srtp && sh ./config.status
|
||||||
|
|
||||||
|
|
||||||
iks-reconf:
|
iks-reconf:
|
||||||
cd libs/iksemel && $(MAKE) clean
|
cd libs/iksemel && $(MAKE) clean
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
#
|
#
|
||||||
FSPREFIX=/usr/local/freeswitch
|
FSPREFIX=/usr/local/freeswitch
|
||||||
PREFIX=/opt/fs-libs
|
PREFIX=/opt/fs-libs
|
||||||
|
DOWNLOAD=http://files.freeswitch.org/downloads/libs
|
||||||
JPEG=v8d
|
JPEG=v8d
|
||||||
OPENSSL=1.0.1g
|
OPENSSL=1.0.1h
|
||||||
SQLITE=autoconf-3080403
|
SQLITE=autoconf-3080403
|
||||||
PCRE=8.35
|
PCRE=8.35
|
||||||
CURL=7.36.0
|
CURL=7.35.0
|
||||||
SPEEX=1.2rc1
|
SPEEX=1.2rc1
|
||||||
LIBEDIT=20140213-3.1
|
LIBEDIT=20140618-3.1
|
||||||
LDNS=1.6.17
|
LDNS=1.6.17
|
||||||
|
|
||||||
freeswitch: deps has-git freeswitch.git/Makefile
|
freeswitch: deps has-git freeswitch.git/Makefile
|
||||||
@ -33,60 +34,66 @@ freeswitch.git/bootstrap.sh: has-git
|
|||||||
install: freeswitch
|
install: freeswitch
|
||||||
cd freeswitch.git && make install
|
cd freeswitch.git && make install
|
||||||
|
|
||||||
install-git:
|
install-git: .done
|
||||||
rpm -i http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
|
.done:
|
||||||
|
rpm -i http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm || true
|
||||||
yum update -y
|
yum update -y
|
||||||
yum install -y git gcc-c++ wget ncurses-devel zlib-devel e2fsprogs-devel libtool automake autoconf
|
yum install -y git gcc-c++ wget ncurses-devel zlib-devel e2fsprogs-devel libtool automake autoconf
|
||||||
|
touch .done
|
||||||
|
|
||||||
has-git:
|
has-git:
|
||||||
@git --version || (echo "please install git by running 'make install-git'" && false)
|
@git --version || (echo "please install git by running 'make install-git'" && false)
|
||||||
|
|
||||||
libjpeg: jpeg-8d/Makefile
|
clean:
|
||||||
|
@rm -rf openssl* ldns* jpeg* pcre* perl* pkg-config* speex* sqlite* libedit* curl* *~
|
||||||
|
(cd freeswitch.git && git clean -fdx && git reset --hard HEAD && git pull)
|
||||||
|
|
||||||
jpeg-8d/Makefile:
|
libjpeg: jpeg-8d/.done
|
||||||
(test -d jpeg-8d) || (wget -4 -O jpegsrc.$(JPEG).tar.gz http://www.ijg.org/files/jpegsrc.$(JPEG).tar.gz && tar zxfv jpegsrc.$(JPEG).tar.gz)
|
|
||||||
(cd jpeg-8d && ./configure --prefix=$(PREFIX) && make && sudo make install)
|
|
||||||
|
|
||||||
openssl: openssl-$(OPENSSL)
|
jpeg-8d/.done:
|
||||||
|
(test -d jpeg-8d) || (wget -4 -O jpegsrc.$(JPEG).tar.gz $(DOWNLOAD)/jpegsrc.$(JPEG).tar.gz && tar zxfv jpegsrc.$(JPEG).tar.gz)
|
||||||
|
(cd jpeg-8d && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done)
|
||||||
|
|
||||||
|
openssl: openssl-$(OPENSSL)/.done
|
||||||
|
openssl-$(OPENSSL)/.done: openssl-$(OPENSSL)
|
||||||
openssl-$(OPENSSL):
|
openssl-$(OPENSSL):
|
||||||
(test -d $@) || (wget -4 -O $@.tar.gz http://www.openssl.org/source/$@.tar.gz && tar zxfv $@.tar.gz)
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
(cd $@ && ./Configure --prefix=$(PREFIX) linux-x86_64 shared && make && sudo make install)
|
(cd $@ && ./Configure --prefix=$(PREFIX) linux-x86_64 shared && make && sudo make install && touch .done)
|
||||||
|
|
||||||
sqlite: sqlite-$(SQLITE)
|
|
||||||
|
|
||||||
|
sqlite: sqlite-$(SQLITE)/.done
|
||||||
|
sqlite-$(SQLITE)/.done: sqlite-$(SQLITE)
|
||||||
sqlite-$(SQLITE):
|
sqlite-$(SQLITE):
|
||||||
(test -d $@) || (wget -4 -O $@.tar.gz http://www.sqlite.org/2014/$@.tar.gz && tar zxfv $@.tar.gz)
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install)
|
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done_sqlite && touch .done)
|
||||||
|
|
||||||
pcre: pcre-$(PCRE)
|
|
||||||
|
|
||||||
|
pcre: pcre-$(PCRE)/.done
|
||||||
|
pcre-$(PCRE)/.done: pcre-$(PCRE)
|
||||||
pcre-$(PCRE):
|
pcre-$(PCRE):
|
||||||
(test -d $@) || (wget -4 -O $@.tar.gz http://downloads.sourceforge.net/project/pcre/pcre/$(PCRE)/$@.tar.gz && tar zxfv $@.tar.gz)
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install)
|
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done)
|
||||||
|
|
||||||
curl: curl-$(CURL)
|
|
||||||
|
|
||||||
|
curl: curl-$(CURL)/.done
|
||||||
|
curl-$(CURL)/.done: curl-$(CURL)
|
||||||
curl-$(CURL):
|
curl-$(CURL):
|
||||||
(test -d $@) || (wget -4 -O $@.tar.gz http://curl.haxx.se/download/$@.tar.gz && tar zxfv $@.tar.gz)
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install)
|
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done)
|
||||||
|
|
||||||
speex: speex-$(SPEEX)
|
|
||||||
|
|
||||||
|
speex: speex-$(SPEEX)/.done
|
||||||
|
speex-$(SPEEX)/.done: speex-$(SPEEX)
|
||||||
speex-$(SPEEX):
|
speex-$(SPEEX):
|
||||||
(test -d $@) || (wget -4 -O $@.tar.gz http://downloads.xiph.org/releases/speex/$@.tar.gz && tar zxfv $@.tar.gz)
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install)
|
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done)
|
||||||
|
|
||||||
libedit: libedit-$(LIBEDIT)
|
|
||||||
|
|
||||||
|
libedit: libedit-$(LIBEDIT)/.done
|
||||||
|
libedit-$(LIBEDIT)/.done: libedit-$(LIBEDIT)
|
||||||
libedit-$(LIBEDIT):
|
libedit-$(LIBEDIT):
|
||||||
(test -d $@) || (wget -4 -O $@.tar.gz http://thrysoee.dk/editline/$@.tar.gz && tar zxfv $@.tar.gz)
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install)
|
(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done)
|
||||||
|
|
||||||
ldns: ldns-$(LDNS)
|
ldns: ldns-$(LDNS)/.done
|
||||||
|
ldns-$(LDNS)/.done: ldns-$(LDNS)
|
||||||
ldns-$(LDNS): openssl
|
ldns-$(LDNS):
|
||||||
(test -d $@) || (wget -4 -O $@.tar.gz http://www.nlnetlabs.nl/downloads/ldns/$@.tar.gz && tar zxfv $@.tar.gz)
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
(cd $@ && ./configure --with-ssl=$(PREFIX) --prefix=$(PREFIX) && make && sudo make install)
|
(cd $@ && ./configure --with-ssl=$(PREFIX) --prefix=$(PREFIX) && make && sudo make install && touch .done)
|
||||||
|
|
||||||
deps: libjpeg openssl sqlite pcre curl speex libedit ldns
|
deps: libjpeg openssl sqlite pcre curl speex libedit ldns
|
||||||
|
110
build/Makefile.solaris11
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#
|
||||||
|
# FreeSWITCH auto-build Makefile (Solaris 11.1 64bit Tonka Truck Edition)
|
||||||
|
# http://www.freeswitch.org
|
||||||
|
# put this file anywhere and type gmake to
|
||||||
|
# create a fully-built freeswitch.git from scratch
|
||||||
|
# in that same directory.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
FSPREFIX=/usr/local/freeswitch
|
||||||
|
PREFIX=/usr/local/
|
||||||
|
DOWNLOAD=http://files.freeswitch.org/downloads/libs
|
||||||
|
JP=v8d
|
||||||
|
SSL=1.0.1h
|
||||||
|
SQLITE=autoconf-3080403
|
||||||
|
PCRE=8.35
|
||||||
|
CURL=7.35.0
|
||||||
|
SPEEX=1.2rc1
|
||||||
|
LIBEDIT=20140618-3.1
|
||||||
|
LDNS=1.6.17
|
||||||
|
PKGCFG=0.28
|
||||||
|
PERL=5.18.2
|
||||||
|
|
||||||
|
freeswitch: deps has-git freeswitch.git/Makefile
|
||||||
|
cd freeswitch.git && gmake
|
||||||
|
|
||||||
|
freeswitch.git/Makefile: freeswitch.git/configure
|
||||||
|
export PATH=$PATH:$(PREFIX)/bin
|
||||||
|
cd freeswitch.git && PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig ./configure --enable-64 LDFLAGS='-L$(PREFIX)/lib -Wl,-rpath=$(PREFIX)/lib' CFLAGS='-I$(PREFIX)/include' --prefix=$(FSPREFIX)
|
||||||
|
|
||||||
|
freeswitch.git/configure: freeswitch.git/bootstrap.sh
|
||||||
|
cd freeswitch.git && sh bootstrap.sh
|
||||||
|
|
||||||
|
freeswitch.git/bootstrap.sh: has-git
|
||||||
|
test -d freeswitch.git || git clone git://git.freeswitch.org/freeswitch.git freeswitch.git
|
||||||
|
|
||||||
|
install: freeswitch
|
||||||
|
cd freeswitch.git && gmake install
|
||||||
|
|
||||||
|
install-git:
|
||||||
|
pkg install git autoconf automake libtool libjpeg gcc-45 wget
|
||||||
|
|
||||||
|
has-git:
|
||||||
|
@git --version || (echo "please install git by running 'gmake install-git'" && false)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf openssl* ldns* jpeg* pcre* perl* pkg-config* speex* sqlite* libedit* curl* *~
|
||||||
|
(cd freeswitch.git && git clean -fdx && git reset --hard HEAD && git pull)
|
||||||
|
|
||||||
|
libjpeg: jpeg-8d/.done
|
||||||
|
|
||||||
|
jpeg-8d/.done:
|
||||||
|
(test -d jpeg-8d) || (wget -4 -O jpegsrc.$(JP).tar.gz $(DOWNLOAD)/jpegsrc.$(JP).tar.gz && tar zxfv jpegsrc.$(JP).tar.gz)
|
||||||
|
(cd jpeg-8d && CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
openssl: openssl-$(SSL)/.done
|
||||||
|
openssl-$(SSL)/.done: openssl-$(SSL)
|
||||||
|
openssl-$(SSL):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./Configure --prefix=$(PREFIX) solaris64-x86_64-gcc shared && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
sqlite: sqlite-$(SQLITE)/.done
|
||||||
|
sqlite-$(SQLITE)/.done: sqlite-$(SQLITE)
|
||||||
|
sqlite-$(SQLITE):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
pcre: pcre-$(PCRE)/.done
|
||||||
|
pcre-$(PCRE)/.done: pcre-$(PCRE)
|
||||||
|
pcre-$(PCRE):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CXXFLAGS=-m64 CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
curl: curl-$(CURL)/.done
|
||||||
|
curl-$(CURL)/.done: curl-$(CURL)
|
||||||
|
curl-$(CURL):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
speex: speex-$(SPEEX)/.done
|
||||||
|
speex-$(SPEEX)/.done: speex-$(SPEEX)
|
||||||
|
speex-$(SPEEX):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
libedit: libedit-$(LIBEDIT)/.done
|
||||||
|
libedit-$(LIBEDIT)/.done: libedit-$(LIBEDIT)
|
||||||
|
libedit-$(LIBEDIT):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
ldns: openssl ldns-$(LDNS)/.done
|
||||||
|
ldns-$(LDNS)/.done: ldns-$(LDNS)
|
||||||
|
ldns-$(LDNS):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --with-ssl=$(PREFIX) --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
pkg-config: openssl pkg-config-$(PKGCFG)/.done
|
||||||
|
pkg-config-$(PKGCFG)/.done: pkg-config-$(PKGCFG)
|
||||||
|
pkg-config-$(PKGCFG):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --with-internal-glib --prefix=$(PREFIX) && sudo gmake uninstall && gmake && sudo gmake install && \
|
||||||
|
touch .done)
|
||||||
|
|
||||||
|
perl: openssl perl-$(PERL)/.done
|
||||||
|
perl-$(PERL)/.done: perl-$(PERL)
|
||||||
|
perl-$(PERL):
|
||||||
|
(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
|
||||||
|
(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure.gnu -Dcc=gcc --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
|
||||||
|
|
||||||
|
deps: has-git libjpeg openssl sqlite pcre curl speex libedit ldns pkg-config perl
|
@ -15,14 +15,14 @@ echo
|
|||||||
here=`pwd`
|
here=`pwd`
|
||||||
|
|
||||||
cd $mods
|
cd $mods
|
||||||
files=`ls *.dylib *.so 2>/dev/null`
|
files=`ls *.so 2>/dev/null`
|
||||||
cd $here
|
cd $here
|
||||||
|
|
||||||
for i in $files ; do
|
for i in $files ; do
|
||||||
mod=${i%%.*}
|
mod=${i%%.*}
|
||||||
|
|
||||||
infile=`grep ^.*$mod\$ ../modules.conf`
|
infile=`grep ^.*$mod\$ ../modules.conf | grep -v ftmod_`
|
||||||
commented=`grep ^\#.*$mod\$ ../modules.conf`
|
commented=`grep ^\#.*$mod\$ ../modules.conf | grep -v ftmod_`
|
||||||
|
|
||||||
if [ -z "$infile" ] ; then
|
if [ -z "$infile" ] ; then
|
||||||
echo "${on}WARNING: installed module: $i was not installed by this build. It is not present in modules.conf.${off}"
|
echo "${on}WARNING: installed module: $i was not installed by this build. It is not present in modules.conf.${off}"
|
||||||
|
@ -83,6 +83,7 @@ dialplans/mod_dialplan_xml
|
|||||||
#endpoints/mod_h323
|
#endpoints/mod_h323
|
||||||
#endpoints/mod_khomp
|
#endpoints/mod_khomp
|
||||||
endpoints/mod_rtc
|
endpoints/mod_rtc
|
||||||
|
endpoints/mod_verto
|
||||||
endpoints/mod_loopback
|
endpoints/mod_loopback
|
||||||
#endpoints/mod_opal
|
#endpoints/mod_opal
|
||||||
#endpoints/mod_portaudio
|
#endpoints/mod_portaudio
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<configuration name="spidermonkey.conf" description="Spider Monkey JavaScript Plug-Ins">
|
|
||||||
<modules>
|
|
||||||
<load module="mod_spidermonkey_teletone"/>
|
|
||||||
<load module="mod_spidermonkey_core_db"/>
|
|
||||||
<load module="mod_spidermonkey_socket"/>
|
|
||||||
<!--<load module="mod_spidermonkey_odbc"/>-->
|
|
||||||
</modules>
|
|
||||||
</configuration>
|
|
@ -1,8 +0,0 @@
|
|||||||
<configuration name="spidermonkey.conf" description="Spider Monkey JavaScript Plug-Ins">
|
|
||||||
<modules>
|
|
||||||
<load module="mod_spidermonkey_teletone"/>
|
|
||||||
<load module="mod_spidermonkey_core_db"/>
|
|
||||||
<load module="mod_spidermonkey_socket"/>
|
|
||||||
<!--<load module="mod_spidermonkey_odbc"/>-->
|
|
||||||
</modules>
|
|
||||||
</configuration>
|
|
27
conf/vanilla/autoload_configs/verto.conf.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<configuration name="verto.conf" description="HTML5 Verto Endpoint">
|
||||||
|
|
||||||
|
<settings>
|
||||||
|
<param name="debug" value="0"/>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile name="mine">
|
||||||
|
<param name="bind-local" value="0.0.0.0:8081"/>
|
||||||
|
<param name="bind-local" value="0.0.0.0:8082" secure="true"/>
|
||||||
|
<param name="secure-combined" value="/usr/local/freeswitch/certs/wss.pem"/>
|
||||||
|
<param name="secure-chain" value="/usr/local/freeswitch/certs/wss.pem"/>
|
||||||
|
<param name="userauth" value="true"/>
|
||||||
|
<param name="mcast-ip" value="224.1.1.1"/>
|
||||||
|
<param name="mcast-port" value="1337"/>
|
||||||
|
<param name="rtp-ip" value="$${local_ip_v4}"/>
|
||||||
|
<!-- <param name="ext-rtp-ip" value=""/> -->
|
||||||
|
<param name="local-network" value="localnet.auto"/>
|
||||||
|
<param name="outbound-codec-string" value="opus,vp8"/>
|
||||||
|
<param name="inbound-codec-string" value="opus,vp8"/>
|
||||||
|
<param name="apply-candidate-acl" value="wan.auto"/>
|
||||||
|
<param name="timer-name" value="soft"/>
|
||||||
|
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
</configuration>
|
@ -126,6 +126,14 @@
|
|||||||
<condition field="${call_debug}" expression="^true$" break="never">
|
<condition field="${call_debug}" expression="^true$" break="never">
|
||||||
<action application="info"/>
|
<action application="info"/>
|
||||||
</condition>
|
</condition>
|
||||||
|
|
||||||
|
<condition field="${default_password}" expression="^1234$" break="never">
|
||||||
|
<action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
|
||||||
|
<action application="log" data="CRIT Open ${base_dir}/conf/vars.xml and change the default_password."/>
|
||||||
|
<action application="log" data="CRIT Once changed type 'reloadxml' at the console."/>
|
||||||
|
<action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
|
||||||
|
<action application="sleep" data="10000"/>
|
||||||
|
</condition>
|
||||||
<!--
|
<!--
|
||||||
This is an example of how to auto detect if telephone-event is missing and activate inband detection
|
This is an example of how to auto detect if telephone-event is missing and activate inband detection
|
||||||
-->
|
-->
|
||||||
|
@ -7,17 +7,17 @@
|
|||||||
The special applications:
|
The special applications:
|
||||||
- skinny-process tells skinny to process the call (route, set call forwarding, ...)
|
- skinny-process tells skinny to process the call (route, set call forwarding, ...)
|
||||||
- skinny-drop tells skinny to drop the call
|
- skinny-drop tells skinny to drop the call
|
||||||
- skinny-wait tells skinny to wait for more digits
|
- skinny-wait tells skinny to wait 'data' seconds for more numbers before drop
|
||||||
-->
|
-->
|
||||||
<!-- http://wiki.freeswitch.org/wiki/Mod_skinny -->
|
<!-- http://wiki.freeswitch.org/wiki/Mod_skinny -->
|
||||||
<include>
|
<include>
|
||||||
<context name="skinny-patterns">
|
<context name="skinny-patterns">
|
||||||
<!--
|
<!--
|
||||||
Wait for another digit by default
|
Wait 10 seconds for another digit by default, if data not specified, uses profile default
|
||||||
-->
|
-->
|
||||||
<extension name="Default">
|
<extension name="Default">
|
||||||
<condition>
|
<condition>
|
||||||
<action application="skinny-wait" />
|
<action application="skinny-wait" data="10"/>
|
||||||
</condition>
|
</condition>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
|
96
conf/vanilla/sip_profiles/external-ipv6.xml
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<profile name="external-ipv6">
|
||||||
|
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
|
||||||
|
<!-- This profile is only for outbound registrations to providers -->
|
||||||
|
<gateways>
|
||||||
|
<X-PRE-PROCESS cmd="include" data="external/*.xml"/>
|
||||||
|
</gateways>
|
||||||
|
|
||||||
|
<aliases>
|
||||||
|
<!--
|
||||||
|
<alias name="outbound"/>
|
||||||
|
<alias name="nat"/>
|
||||||
|
-->
|
||||||
|
</aliases>
|
||||||
|
|
||||||
|
<domains>
|
||||||
|
<domain name="all" alias="false" parse="true"/>
|
||||||
|
</domains>
|
||||||
|
|
||||||
|
<settings>
|
||||||
|
<param name="debug" value="0"/>
|
||||||
|
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
|
||||||
|
<!-- <param name="shutdown-on-fail" value="true"/> -->
|
||||||
|
<param name="sip-trace" value="no"/>
|
||||||
|
<param name="sip-capture" value="no"/>
|
||||||
|
<param name="rfc2833-pt" value="101"/>
|
||||||
|
<!-- RFC 5626 : Send reg-id and sip.instance -->
|
||||||
|
<!--<param name="enable-rfc-5626" value="true"/> -->
|
||||||
|
<param name="sip-port" value="$${external_sip_port}"/>
|
||||||
|
<param name="dialplan" value="XML"/>
|
||||||
|
<param name="context" value="public"/>
|
||||||
|
<param name="dtmf-duration" value="2000"/>
|
||||||
|
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
|
||||||
|
<param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/>
|
||||||
|
<param name="hold-music" value="$${hold_music}"/>
|
||||||
|
<param name="rtp-timer-name" value="soft"/>
|
||||||
|
<!--<param name="enable-100rel" value="true"/>-->
|
||||||
|
<!--<param name="disable-srv503" value="true"/>-->
|
||||||
|
<!-- This could be set to "passive" -->
|
||||||
|
<param name="local-network-acl" value="localnet.auto"/>
|
||||||
|
<param name="manage-presence" value="false"/>
|
||||||
|
|
||||||
|
<!-- used to share presence info across sofia profiles
|
||||||
|
manage-presence needs to be set to passive on this profile
|
||||||
|
if you want it to behave as if it were the internal profile
|
||||||
|
for presence.
|
||||||
|
-->
|
||||||
|
<!-- Name of the db to use for this profile -->
|
||||||
|
<!--<param name="dbname" value="share_presence"/>-->
|
||||||
|
<!--<param name="presence-hosts" value="$${domain}"/>-->
|
||||||
|
<!--<param name="force-register-domain" value="$${domain}"/>-->
|
||||||
|
<!--all inbound reg will stored in the db using this domain -->
|
||||||
|
<!--<param name="force-register-db-domain" value="$${domain}"/>-->
|
||||||
|
<!-- ************************************************* -->
|
||||||
|
|
||||||
|
<!--<param name="aggressive-nat-detection" value="true"/>-->
|
||||||
|
<param name="inbound-codec-negotiation" value="generous"/>
|
||||||
|
<param name="nonce-ttl" value="60"/>
|
||||||
|
<param name="auth-calls" value="false"/>
|
||||||
|
<param name="inbound-late-negotiation" value="true"/>
|
||||||
|
<param name="inbound-zrtp-passthru" value="true"/> <!-- (also enables late negotiation) -->
|
||||||
|
<!--
|
||||||
|
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
|
||||||
|
-->
|
||||||
|
<param name="rtp-ip" value="$${local_ip_v6}"/>
|
||||||
|
<param name="sip-ip" value="$${local_ip_v6}"/>
|
||||||
|
<param name="ext-rtp-ip" value="auto-nat"/>
|
||||||
|
<param name="ext-sip-ip" value="auto-nat"/>
|
||||||
|
<param name="rtp-timeout-sec" value="300"/>
|
||||||
|
<param name="rtp-hold-timeout-sec" value="1800"/>
|
||||||
|
<!--<param name="enable-3pcc" value="true"/>-->
|
||||||
|
|
||||||
|
<!-- TLS: disabled by default, set to "true" to enable -->
|
||||||
|
<param name="tls" value="$${external_ssl_enable}"/>
|
||||||
|
<!-- Set to true to not bind on the normal sip-port but only on the TLS port -->
|
||||||
|
<param name="tls-only" value="false"/>
|
||||||
|
<!-- additional bind parameters for TLS -->
|
||||||
|
<param name="tls-bind-params" value="transport=tls"/>
|
||||||
|
<!-- Port to listen on for TLS requests. (5081 will be used if unspecified) -->
|
||||||
|
<param name="tls-sip-port" value="$${external_tls_port}"/>
|
||||||
|
<!-- Location of the agent.pem and cafile.pem ssl certificates (needed for TLS server) -->
|
||||||
|
<!--<param name="tls-cert-dir" value=""/>-->
|
||||||
|
<!-- Optionally set the passphrase password used by openSSL to encrypt/decrypt TLS private key files -->
|
||||||
|
<param name="tls-passphrase" value=""/>
|
||||||
|
<!-- Verify the date on TLS certificates -->
|
||||||
|
<param name="tls-verify-date" value="true"/>
|
||||||
|
<!-- TLS verify policy, when registering/inviting gateways with other servers (outbound) or handling inbound registration/invite requests how should we verify their certificate -->
|
||||||
|
<!-- set to 'in' to only verify incoming connections, 'out' to only verify outgoing connections, 'all' to verify all connections, also 'in_subjects', 'out_subjects' and 'all_subjects' for subject validation. Multiple policies can be split with a '|' pipe -->
|
||||||
|
<param name="tls-verify-policy" value="none"/>
|
||||||
|
<!-- Certificate max verify depth to use for validating peer TLS certificates when the verify policy is not none -->
|
||||||
|
<param name="tls-verify-depth" value="2"/>
|
||||||
|
<!-- If the tls-verify-policy is set to subjects_all or subjects_in this sets which subjects are allowed, multiple subjects can be split with a '|' pipe -->
|
||||||
|
<param name="tls-verify-in-subjects" value=""/>
|
||||||
|
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
|
||||||
|
<param name="tls-version" value="$${sip_tls_version}"/>
|
||||||
|
</settings>
|
||||||
|
</profile>
|
@ -12,6 +12,9 @@
|
|||||||
<param name="odbc-dsn" value=""/>
|
<param name="odbc-dsn" value=""/>
|
||||||
<param name="debug" value="4"/>
|
<param name="debug" value="4"/>
|
||||||
<param name="auto-restart" value="true"/>
|
<param name="auto-restart" value="true"/>
|
||||||
|
|
||||||
|
<!-- timeout to wait for another digit in milliseconds -->
|
||||||
|
<param name="digit-timeout" value="10000"/>
|
||||||
</settings>
|
</settings>
|
||||||
<soft-key-set-sets>
|
<soft-key-set-sets>
|
||||||
<soft-key-set-set name="default">
|
<soft-key-set-set name="default">
|
||||||
|
34
configure.ac
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
# Must change all of the below together
|
# Must change all of the below together
|
||||||
# For a release, set revision for that tagged release as well and uncomment
|
# For a release, set revision for that tagged release as well and uncomment
|
||||||
AC_INIT([freeswitch], [1.4.6], bugs@freeswitch.org)
|
AC_INIT([freeswitch], [1.4.7], bugs@freeswitch.org)
|
||||||
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
|
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
|
||||||
AC_SUBST(SWITCH_VERSION_MINOR, [4])
|
AC_SUBST(SWITCH_VERSION_MINOR, [4])
|
||||||
AC_SUBST(SWITCH_VERSION_MICRO, [6])
|
AC_SUBST(SWITCH_VERSION_MICRO, [7])
|
||||||
AC_SUBST(SWITCH_VERSION_REVISION, [])
|
AC_SUBST(SWITCH_VERSION_REVISION, [])
|
||||||
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
|
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
|
||||||
|
|
||||||
@ -493,6 +493,10 @@ AC_ARG_ENABLE(srtp,
|
|||||||
|
|
||||||
AM_CONDITIONAL([ENABLE_SRTP],[test "${enable_srtp}" = "yes"])
|
AM_CONDITIONAL([ENABLE_SRTP],[test "${enable_srtp}" = "yes"])
|
||||||
|
|
||||||
|
have_openal=no
|
||||||
|
AC_CHECK_LIB(openal, alMidiGainSOFT, [have_openal="yes"])
|
||||||
|
AM_CONDITIONAL([HAVE_OPENAL],[test "${have_openal}" = "yes"])
|
||||||
|
|
||||||
AC_ARG_ENABLE(zrtp,
|
AC_ARG_ENABLE(zrtp,
|
||||||
[AS_HELP_STRING([--enable-zrtp], [Compile with zrtp Support])],,[enable_zrtp="no"])
|
[AS_HELP_STRING([--enable-zrtp], [Compile with zrtp Support])],,[enable_zrtp="no"])
|
||||||
if test "x$enable_zrtp" = "xyes" ; then
|
if test "x$enable_zrtp" = "xyes" ; then
|
||||||
@ -1230,16 +1234,29 @@ AM_CONDITIONAL([HAVE_MYSQL],[test "$found_mysql" = "yes"])
|
|||||||
#
|
#
|
||||||
|
|
||||||
AC_CHECK_PROG(PERL,perl,[ac_cv_have_perl=yes],[ac_cv_have_perl=no])
|
AC_CHECK_PROG(PERL,perl,[ac_cv_have_perl=yes],[ac_cv_have_perl=no])
|
||||||
AM_CONDITIONAL([HAVE_PERL],[test "x$ac_cv_have_perl" != "xno"])
|
|
||||||
|
|
||||||
if test "x$ac_cv_have_perl" != "xno" ; then
|
# -a "x$ac_cv_have_EXTERN_h" != "xno"
|
||||||
|
|
||||||
|
if test "x$ac_cv_have_perl" != "xno"; then
|
||||||
PERL=perl
|
PERL=perl
|
||||||
PERL_SITEDIR="`$PERL -MConfig -e 'print $Config{sitelibexp}'`"
|
PERL_SITEDIR="`$PERL -MConfig -e 'print $Config{archlib}'`"
|
||||||
PERL_LIBDIR="-L`$PERL -MConfig -e 'print $Config{archlib}'`/CORE"
|
PERL_LIBDIR="-L`$PERL -MConfig -e 'print $Config{archlib}'`/CORE"
|
||||||
PERL_LIBS="`$PERL -MConfig -e 'print $Config{libs}'`"
|
PERL_LIBS="`$PERL -MConfig -e 'print $Config{libs}'`"
|
||||||
PERL_CFLAGS="-w -DMULTIPLICITY `$PERL -MExtUtils::Embed -e ccopts` -DEMBED_PERL"
|
PERL_CFLAGS="-w -DMULTIPLICITY `$PERL -MExtUtils::Embed -e ccopts | sed -e 's|-arch x86_64 -arch i386||'` -DEMBED_PERL"
|
||||||
PERL_LDFLAGS="`$PERL -MExtUtils::Embed -e ldopts` `$PERL -MConfig -e 'print $Config{libs}'`"
|
PERL_LDFLAGS="`$PERL -MExtUtils::Embed -e ldopts| sed -e 's|-arch x86_64 -arch i386||'`"
|
||||||
PERL_INC="`$PERL -MExtUtils::Embed -e perl_inc`"
|
PERL_INC="`$PERL -MExtUtils::Embed -e perl_inc`"
|
||||||
|
|
||||||
|
save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$PERL_CFLAGS"
|
||||||
|
AC_CHECK_HEADER([EXTERN.h], [ac_cv_have_EXTERN_h=yes], [ac_cv_have_EXTERN_h=no], [[#include <EXTERN.h>
|
||||||
|
# include <perl.h>]])
|
||||||
|
CFLAGS="$save_CFLAGS"
|
||||||
|
|
||||||
|
save_LDFLAGS="$LDFLAGS"
|
||||||
|
LDFLAGS="$PERL_LDFLAGS"
|
||||||
|
AC_CHECK_LIB([perl], [perl_alloc], ac_cv_use_libperl=yes, ac_cv_use_libperl=no)
|
||||||
|
LDFLAGS="$save_LDFLAGS"
|
||||||
|
|
||||||
AC_SUBST(PERL_SITEDIR)
|
AC_SUBST(PERL_SITEDIR)
|
||||||
AC_SUBST(PERL_LIBDIR)
|
AC_SUBST(PERL_LIBDIR)
|
||||||
AC_SUBST(PERL_LIBS)
|
AC_SUBST(PERL_LIBS)
|
||||||
@ -1248,6 +1265,8 @@ if test "x$ac_cv_have_perl" != "xno" ; then
|
|||||||
AC_SUBST(PERL_INC)
|
AC_SUBST(PERL_INC)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL([HAVE_PERL],[test "x$ac_cv_have_perl" != "xno" -a "x$ac_cv_have_EXTERN_h" != "xno" -a "x$ac_cv_use_libperl" != "xno"])
|
||||||
|
|
||||||
#
|
#
|
||||||
# php checks
|
# php checks
|
||||||
#
|
#
|
||||||
@ -1500,6 +1519,7 @@ AC_CONFIG_FILES([Makefile
|
|||||||
src/mod/endpoints/mod_sofia/Makefile
|
src/mod/endpoints/mod_sofia/Makefile
|
||||||
src/mod/endpoints/mod_unicall/Makefile
|
src/mod/endpoints/mod_unicall/Makefile
|
||||||
src/mod/endpoints/mod_rtc/Makefile
|
src/mod/endpoints/mod_rtc/Makefile
|
||||||
|
src/mod/endpoints/mod_verto/Makefile
|
||||||
src/mod/event_handlers/mod_cdr_csv/Makefile
|
src/mod/event_handlers/mod_cdr_csv/Makefile
|
||||||
src/mod/event_handlers/mod_cdr_mongodb/Makefile
|
src/mod/event_handlers/mod_cdr_mongodb/Makefile
|
||||||
src/mod/event_handlers/mod_cdr_pg_csv/Makefile
|
src/mod/event_handlers/mod_cdr_pg_csv/Makefile
|
||||||
|
17
debian/bootstrap.sh
vendored
@ -28,7 +28,6 @@ avoid_mods=(
|
|||||||
endpoints/mod_reference
|
endpoints/mod_reference
|
||||||
endpoints/mod_unicall
|
endpoints/mod_unicall
|
||||||
languages/mod_managed
|
languages/mod_managed
|
||||||
languages/mod_perl
|
|
||||||
sdk/autotools
|
sdk/autotools
|
||||||
xml_int/mod_xml_ldap
|
xml_int/mod_xml_ldap
|
||||||
xml_int/mod_xml_radius
|
xml_int/mod_xml_radius
|
||||||
@ -69,6 +68,7 @@ freeswitch-init
|
|||||||
freeswitch-sysvinit
|
freeswitch-sysvinit
|
||||||
freeswitch-systemd
|
freeswitch-systemd
|
||||||
freeswitch-lang
|
freeswitch-lang
|
||||||
|
freeswitch-timezones
|
||||||
)
|
)
|
||||||
|
|
||||||
err () {
|
err () {
|
||||||
@ -361,6 +361,7 @@ Recommends:
|
|||||||
freeswitch-mod-commands (= \${binary:Version}),
|
freeswitch-mod-commands (= \${binary:Version}),
|
||||||
freeswitch-init (= \${binary:Version}),
|
freeswitch-init (= \${binary:Version}),
|
||||||
freeswitch-lang (= \${binary:Version}),
|
freeswitch-lang (= \${binary:Version}),
|
||||||
|
freeswitch-timezones (= \${binary:Version}),
|
||||||
freeswitch-music,
|
freeswitch-music,
|
||||||
freeswitch-sounds
|
freeswitch-sounds
|
||||||
Suggests:
|
Suggests:
|
||||||
@ -394,6 +395,7 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
|||||||
Recommends:
|
Recommends:
|
||||||
freeswitch-init (= \${binary:Version}),
|
freeswitch-init (= \${binary:Version}),
|
||||||
freeswitch-lang (= \${binary:Version}),
|
freeswitch-lang (= \${binary:Version}),
|
||||||
|
freeswitch-timezones (= \${binary:Version}),
|
||||||
freeswitch-meta-codecs (= \${binary:Version}),
|
freeswitch-meta-codecs (= \${binary:Version}),
|
||||||
freeswitch-music,
|
freeswitch-music,
|
||||||
freeswitch-sounds
|
freeswitch-sounds
|
||||||
@ -449,6 +451,7 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
|||||||
Recommends:
|
Recommends:
|
||||||
freeswitch-init (= \${binary:Version}),
|
freeswitch-init (= \${binary:Version}),
|
||||||
freeswitch-lang (= \${binary:Version}),
|
freeswitch-lang (= \${binary:Version}),
|
||||||
|
freeswitch-timezones (= \${binary:Version}),
|
||||||
freeswitch-music,
|
freeswitch-music,
|
||||||
freeswitch-sounds,
|
freeswitch-sounds,
|
||||||
freeswitch-conf-vanilla (= \${binary:Version}),
|
freeswitch-conf-vanilla (= \${binary:Version}),
|
||||||
@ -464,6 +467,7 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
|||||||
Recommends:
|
Recommends:
|
||||||
freeswitch-init (= \${binary:Version}),
|
freeswitch-init (= \${binary:Version}),
|
||||||
freeswitch-lang (= \${binary:Version}),
|
freeswitch-lang (= \${binary:Version}),
|
||||||
|
freeswitch-timezones (= \${binary:Version}),
|
||||||
freeswitch-meta-codecs (= \${binary:Version}),
|
freeswitch-meta-codecs (= \${binary:Version}),
|
||||||
freeswitch-music,
|
freeswitch-music,
|
||||||
freeswitch-sounds,
|
freeswitch-sounds,
|
||||||
@ -547,6 +551,7 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
|||||||
Recommends:
|
Recommends:
|
||||||
freeswitch-init (= \${binary:Version}),
|
freeswitch-init (= \${binary:Version}),
|
||||||
freeswitch-lang (= \${binary:Version}),
|
freeswitch-lang (= \${binary:Version}),
|
||||||
|
freeswitch-timezones (= \${binary:Version}),
|
||||||
freeswitch-meta-codecs (= \${binary:Version}),
|
freeswitch-meta-codecs (= \${binary:Version}),
|
||||||
freeswitch-meta-conf (= \${binary:Version}),
|
freeswitch-meta-conf (= \${binary:Version}),
|
||||||
freeswitch-meta-lang (= \${binary:Version}),
|
freeswitch-meta-lang (= \${binary:Version}),
|
||||||
@ -833,6 +838,16 @@ Description: Language files for FreeSWITCH
|
|||||||
This is a metapackage which depends on the default language packages
|
This is a metapackage which depends on the default language packages
|
||||||
for FreeSWITCH.
|
for FreeSWITCH.
|
||||||
|
|
||||||
|
## timezones
|
||||||
|
|
||||||
|
Package: freeswitch-timezones
|
||||||
|
Architecture: all
|
||||||
|
Depends: \${misc:Depends}
|
||||||
|
Description: Timezone files for FreeSWITCH
|
||||||
|
$(debian_wrap "${fs_description}")
|
||||||
|
.
|
||||||
|
$(debian_wrap "This package includes the timezone files for FreeSWITCH.")
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
debian/control-modules
vendored
@ -411,6 +411,10 @@ Module: endpoints/mod_reference
|
|||||||
Description: mod_reference
|
Description: mod_reference
|
||||||
Adds mod_reference.
|
Adds mod_reference.
|
||||||
|
|
||||||
|
Module: endpoints/mod_rtc
|
||||||
|
Description: Adds mod_rtc.
|
||||||
|
Adds mod_rtc.
|
||||||
|
|
||||||
Module: endpoints/mod_rtmp
|
Module: endpoints/mod_rtmp
|
||||||
Description: mod_rtmp
|
Description: mod_rtmp
|
||||||
Adds mod_rtmp.
|
Adds mod_rtmp.
|
||||||
@ -432,6 +436,11 @@ Module: endpoints/mod_unicall
|
|||||||
Description: mod_unicall
|
Description: mod_unicall
|
||||||
Adds mod_unicall.
|
Adds mod_unicall.
|
||||||
|
|
||||||
|
Module: endpoints/mod_verto
|
||||||
|
Description: Adds mod_verto.
|
||||||
|
Adds mod_verto.
|
||||||
|
Build-Depends: libperl-dev
|
||||||
|
|
||||||
## mod/event_handlers
|
## mod/event_handlers
|
||||||
|
|
||||||
Module: event_handlers/mod_cdr_csv
|
Module: event_handlers/mod_cdr_csv
|
||||||
@ -584,14 +593,14 @@ Module: loggers/mod_console
|
|||||||
Description: mod_console
|
Description: mod_console
|
||||||
Adds mod_console.
|
Adds mod_console.
|
||||||
|
|
||||||
Module: loggers/mod_logfile
|
|
||||||
Description: mod_logfile
|
|
||||||
Adds mod_logfile.
|
|
||||||
|
|
||||||
Module: loggers/mod_graylog2
|
Module: loggers/mod_graylog2
|
||||||
Description: mod_graylog2
|
Description: mod_graylog2
|
||||||
Adds mod_greylog2.
|
Adds mod_greylog2.
|
||||||
|
|
||||||
|
Module: loggers/mod_logfile
|
||||||
|
Description: mod_logfile
|
||||||
|
Adds mod_logfile.
|
||||||
|
|
||||||
Module: loggers/mod_syslog
|
Module: loggers/mod_syslog
|
||||||
Description: mod_syslog
|
Description: mod_syslog
|
||||||
Adds mod_syslog.
|
Adds mod_syslog.
|
||||||
|
2
debian/freeswitch-systemd.freeswitch.service
vendored
@ -11,7 +11,7 @@ PIDFile=/run/freeswitch/freeswitch.pid
|
|||||||
PermissionsStartOnly=true
|
PermissionsStartOnly=true
|
||||||
ExecStartPre=/bin/mkdir -p /run/freeswitch
|
ExecStartPre=/bin/mkdir -p /run/freeswitch
|
||||||
ExecStartPre=/bin/chown freeswitch:freeswitch /run/freeswitch
|
ExecStartPre=/bin/chown freeswitch:freeswitch /run/freeswitch
|
||||||
ExecStart=/usr/bin/freeswitch -nc -nonat
|
ExecStart=/usr/bin/freeswitch -ncwait -nonat
|
||||||
TimeoutSec=45s
|
TimeoutSec=45s
|
||||||
Restart=always
|
Restart=always
|
||||||
; exec
|
; exec
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
# /etc/default/freeswitch
|
# /etc/default/freeswitch
|
||||||
DAEMON_OPTS="-rp -nonat"
|
DAEMON_OPTS="-nonat"
|
||||||
|
2
debian/freeswitch-sysvinit.freeswitch.init
vendored
@ -18,9 +18,9 @@ PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
|||||||
DESC=freeswitch
|
DESC=freeswitch
|
||||||
NAME=freeswitch
|
NAME=freeswitch
|
||||||
DAEMON=/usr/bin/freeswitch
|
DAEMON=/usr/bin/freeswitch
|
||||||
DAEMON_ARGS="-u freeswitch -g freeswitch -nc"
|
|
||||||
USER=freeswitch
|
USER=freeswitch
|
||||||
GROUP=freeswitch
|
GROUP=freeswitch
|
||||||
|
DAEMON_ARGS="-u $USER -g $GROUP -ncwait"
|
||||||
CONFDIR=/etc/$NAME
|
CONFDIR=/etc/$NAME
|
||||||
RUNDIR=/var/run/$NAME
|
RUNDIR=/var/run/$NAME
|
||||||
PIDFILE=$RUNDIR/$NAME.pid
|
PIDFILE=$RUNDIR/$NAME.pid
|
||||||
|
1
debian/freeswitch-timezones.install
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
conf/vanilla/autoload_configs/timezones.conf.xml /usr/share/freeswitch/tz
|
11
debian/util.sh
vendored
@ -295,12 +295,15 @@ build_debs () {
|
|||||||
}
|
}
|
||||||
if ! [ -d $cow_img ]; then
|
if ! [ -d $cow_img ]; then
|
||||||
announce "Creating base $distro-$arch image..."
|
announce "Creating base $distro-$arch image..."
|
||||||
cow --create
|
local x=30
|
||||||
|
while ! cow --create; do
|
||||||
|
[ $x -lt 1 ] && break; sleep 120; x=$((x-1))
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
announce "Updating base $distro-$arch image..."
|
announce "Updating base $distro-$arch image..."
|
||||||
local x=5
|
local x=30
|
||||||
while ! cow --update; do
|
while ! cow --update --override-config; do
|
||||||
[ $x -lt 1 ] && break; sleep 60; x=$((x-1))
|
[ $x -lt 1 ] && break; sleep 120; x=$((x-1))
|
||||||
done
|
done
|
||||||
announce "Building $distro-$arch DEBs from $dsc..."
|
announce "Building $distro-$arch DEBs from $dsc..."
|
||||||
if $debug_hook; then
|
if $debug_hook; then
|
||||||
|
@ -77,7 +77,7 @@ message might look like this:
|
|||||||
> After appropriate amounts of frobbing have been done, a new variable
|
> After appropriate amounts of frobbing have been done, a new variable
|
||||||
> `frobbing_done` is set in the caller's channel.
|
> `frobbing_done` is set in the caller's channel.
|
||||||
>
|
>
|
||||||
> FS-XXXX --resolve
|
> FS-XXXX #resolve
|
||||||
|
|
||||||
Patches Related to JIRA Issues
|
Patches Related to JIRA Issues
|
||||||
------------------------------
|
------------------------------
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
#
|
#
|
||||||
# freeswitch-config-rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
# freeswitch-config-rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||||
# Copyright (C) 2013, Grasshopper
|
# Copyright (C) 2013-2014, Grasshopper
|
||||||
#
|
#
|
||||||
# Version: MPL 1.1
|
# Version: MPL 1.1
|
||||||
#
|
#
|
||||||
@ -75,7 +75,7 @@ Group: System/Libraries
|
|||||||
Packager: Chris Rienzo
|
Packager: Chris Rienzo
|
||||||
URL: http://www.freeswitch.org/
|
URL: http://www.freeswitch.org/
|
||||||
Source0: freeswitch-%{version}.tar.bz2
|
Source0: freeswitch-%{version}.tar.bz2
|
||||||
Requires: freeswitch = %{version}
|
Requires: freeswitch
|
||||||
Requires: freeswitch-application-conference
|
Requires: freeswitch-application-conference
|
||||||
Requires: freeswitch-application-esf
|
Requires: freeswitch-application-esf
|
||||||
Requires: freeswitch-application-expr
|
Requires: freeswitch-application-expr
|
||||||
@ -94,14 +94,8 @@ Requires: freeswitch-format-mod-shout
|
|||||||
Requires: freeswitch-format-shell-stream
|
Requires: freeswitch-format-shell-stream
|
||||||
Requires: freeswitch-format-ssml
|
Requires: freeswitch-format-ssml
|
||||||
Requires: freeswitch-sounds-music-8000
|
Requires: freeswitch-sounds-music-8000
|
||||||
Requires: freeswitch-sounds-music-16000
|
|
||||||
Requires: freeswitch-sounds-music-32000
|
|
||||||
Requires: freeswitch-sounds-music-48000
|
|
||||||
Requires: freeswitch-lang-en
|
Requires: freeswitch-lang-en
|
||||||
Requires: freeswitch-sounds-en-us-callie-8000
|
Requires: freeswitch-sounds-en-us-callie-8000
|
||||||
Requires: freeswitch-sounds-en-us-callie-16000
|
|
||||||
Requires: freeswitch-sounds-en-us-callie-32000
|
|
||||||
Requires: freeswitch-sounds-en-us-callie-48000
|
|
||||||
BuildRequires: bash
|
BuildRequires: bash
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
@ -171,6 +165,9 @@ FreeSWITCH rayo server implementation.
|
|||||||
#
|
#
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jun 10 2014 crienzo@grasshopper.com
|
||||||
|
- Remove dependency to high resolution music and sounds files
|
||||||
|
- Remove dependency to specific FreeSWITCH package version
|
||||||
* Mon Jun 03 2013 - crienzo@grasshopper.com
|
* Mon Jun 03 2013 - crienzo@grasshopper.com
|
||||||
- Added users and internal profile for softphone testing
|
- Added users and internal profile for softphone testing
|
||||||
* Wed May 08 2013 - crienzo@grasshopper.com
|
* Wed May 08 2013 - crienzo@grasshopper.com
|
||||||
|
3
html5/verto/README
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This needs to be fleshed out more.
|
||||||
|
It would be nice to develop a web app here that implements a web phone.
|
||||||
|
Do not base it on the demo because it was just tossed together.
|
BIN
html5/verto/demo/css/images/ajax-loader.gif
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
html5/verto/demo/css/images/icons-18-black.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
html5/verto/demo/css/images/icons-18-white.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
html5/verto/demo/css/images/icons-36-black.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
html5/verto/demo/css/images/icons-36-white.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
html5/verto/demo/css/images/loading.gif
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
html5/verto/demo/css/images/login.gif
Normal file
After Width: | Height: | Size: 19 KiB |
12
html5/verto/demo/css/jquery.mobile-1.3.2.min.css
vendored
Normal file
65
html5/verto/demo/css/jsontable.css
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
.nthChildTest > div:nth-child(odd) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable > thead > tr > th {
|
||||||
|
|
||||||
|
border-width:4px;
|
||||||
|
padding: 2px;
|
||||||
|
font-size:10pt;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable > thead > tr > th.notSortable {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable > tbody > tr > td {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
padding: 2px;
|
||||||
|
vertical-align: middle;
|
||||||
|
height:25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable {
|
||||||
|
font-family: verdana;
|
||||||
|
font-size:10pt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable > tbody > tr:nth-child(odd),
|
||||||
|
.jsDataTable > tbody > tr.odd {
|
||||||
|
background-color: #ffffee;
|
||||||
|
}
|
||||||
|
.jsDataTable > tbody > tr:nth-child(even),
|
||||||
|
.jsDataTable > tbody > tr.even {
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable > thead th.sortAsc,
|
||||||
|
.jsDataTable > thead th.sortDesc {
|
||||||
|
color:ffffff;
|
||||||
|
|
||||||
|
background-color: #7777ff;
|
||||||
|
background-position: right center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable > thead th.sortAsc {
|
||||||
|
background-image: url(/images/table/asc.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable > thead th.sortDesc {
|
||||||
|
background-image: url(/images/table/desc.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable.clickable > tbody > tr,
|
||||||
|
.clickable > .jsDataTable > tbody > tr {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsDataTable.clickable > tbody > tr.nonDataRow,
|
||||||
|
.clickable > .jsDataTable > tbody > tr.nonDataRow {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
BIN
html5/verto/demo/favicon.ico
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
html5/verto/demo/images/ajax-loader.gif
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
html5/verto/demo/images/icons-18-black.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
html5/verto/demo/images/icons-18-white.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
html5/verto/demo/images/icons-36-black.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
html5/verto/demo/images/icons-36-white.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
html5/verto/demo/images/loading.gif
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
html5/verto/demo/images/login.gif
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
html5/verto/demo/img/cc_banner2014.gif
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
html5/verto/demo/img/cc_banner2014.jpg
Normal file
After Width: | Height: | Size: 773 KiB |
BIN
html5/verto/demo/img/logo.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
html5/verto/demo/img/logo_big.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
html5/verto/demo/img/logo_med.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
html5/verto/demo/img/verto_black_web.gif
Normal file
After Width: | Height: | Size: 11 KiB |
281
html5/verto/demo/index.html
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="css/jquery.mobile-1.3.2.min.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/jsontable.css" />
|
||||||
|
<link rel="shortcut icon" href="favicon.ico" />
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>FreeSWITCH Verto™ Demo</title>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.pageheader {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: normal;
|
||||||
|
height: 27px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctlbtn {
|
||||||
|
border: 0px;
|
||||||
|
color: #eeeeee;
|
||||||
|
background-color: #0000ae;
|
||||||
|
font-face: arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctlbtn:hover {
|
||||||
|
color: #ffffae;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div data-role="page" id="page-login" align="center">
|
||||||
|
<div data-role="header" class="page-header">
|
||||||
|
FreeSWITCH Verto™ Demo
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<a target="_CC2104" href="https://www.cluecon.com"><img border="0" width="300" src="img/cc_banner2014.gif"></a>
|
||||||
|
|
||||||
|
<div data-role="fieldcontain">
|
||||||
|
<label for="name">Login</label>
|
||||||
|
<input type="text" size="20" id="login"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="fieldcontain">
|
||||||
|
<label for="name">Password</label>
|
||||||
|
<input type="password" size="20" id="passwd"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="fieldcontain">
|
||||||
|
<label for="name">CID Name</label>
|
||||||
|
<input type="text" size="30" id="name"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="fieldcontain">
|
||||||
|
<label for="name">CID Number</label>
|
||||||
|
<input type="text" size="20" id="cid"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="fieldcontain">
|
||||||
|
<label for="name">Hostname</label>
|
||||||
|
<input type="text" size="20" id="hostName"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="fieldcontain">
|
||||||
|
<label for="name">Websocket URL</label>
|
||||||
|
<input type="text" size="20" id="wsURL"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<img src="img/verto_black_web.gif" width="300">
|
||||||
|
<br><br>
|
||||||
|
<button data-inline="true" id="loginbtn">Log In</button>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="page" id="page-incall" align="center">
|
||||||
|
<div data-role="header" id="calltitle" class="pageheader">
|
||||||
|
Verto™ IN CALL
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<a target="_CC2104" href="https://www.cluecon.com"><img border="0" width="300" src="img/cc_banner2014.gif"></a>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<div id="conf">
|
||||||
|
<div style="color:black;font-family: verdana" align="center" id="conf_count"></div>
|
||||||
|
<table width="800" cellspacing="0" cellpadding="0" border="0" align="center" id="conf_list" class="jsDataTable">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="display" style="font-weight:bold;font-size:18px"></div>
|
||||||
|
<br>
|
||||||
|
<div data-role="fieldcontain" id="xferdiv">
|
||||||
|
<input data-mini="true" type="text" id="xferto"><br>
|
||||||
|
<button data-inline="true" id="cancelxferbtn">Cancel Transfer</button>
|
||||||
|
<button data-inline="true" class="startxferbtn">Complete Transfer</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id=keypad>
|
||||||
|
<button class="dtmf" data-inline="true">1</button>
|
||||||
|
<button class="dtmf" data-inline="true">2</button>
|
||||||
|
<button class="dtmf" data-inline="true">3</button>
|
||||||
|
<br>
|
||||||
|
<button class="dtmf" data-inline="true">4</button>
|
||||||
|
<button class="dtmf" data-inline="true">5</button>
|
||||||
|
<button class="dtmf" data-inline="true">6</button>
|
||||||
|
<br>
|
||||||
|
<button class="dtmf" data-inline="true">7</button>
|
||||||
|
<button class="dtmf" data-inline="true">8</button>
|
||||||
|
<button class="dtmf" data-inline="true">9</button>
|
||||||
|
<br>
|
||||||
|
<button class="dtmf" data-inline="true">*</button>
|
||||||
|
<button class="dtmf" data-inline="true">0</button>
|
||||||
|
<button class="dtmf" data-inline="true">#</button>
|
||||||
|
</div>
|
||||||
|
<div id="conf_mod"></div>
|
||||||
|
<div style="color:blue" id="conf_display"></div>
|
||||||
|
|
||||||
|
<button data-inline="true" id="hold">HOLD</button>
|
||||||
|
<button data-inline="true" id="hupbtn">End Call</button>
|
||||||
|
<button data-inline="true" class="startxferbtn">Transfer</button>
|
||||||
|
<br><br>
|
||||||
|
<img src="img/verto_black_web.gif" width="300"><br><br>
|
||||||
|
<div id="media">
|
||||||
|
<video width=800 id="webcam" autoplay="autoplay" hidden="true"></video>
|
||||||
|
</div>
|
||||||
|
<br><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="page" id="page-main" align="center">
|
||||||
|
<div data-role="header" class="pageheader">
|
||||||
|
FreeSWITCH Verto™ Demo
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<a target="_CC2104" href="https://www.cluecon.com"><img border="0" width="300" src="img/cc_banner2014.gif"></a>
|
||||||
|
|
||||||
|
<div id="offline">
|
||||||
|
<h2>LOGGING IN</h2>
|
||||||
|
<img src="images/login.gif"></img>
|
||||||
|
<div id="errordisplay" style="font-weight:bold;font-size:18px;color:#ae0000"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="online" align="center">
|
||||||
|
<div id="text"></div>
|
||||||
|
<div data-role="fieldcontain">
|
||||||
|
<input type="text" id="ext"/><br>
|
||||||
|
<div id="dialpad">
|
||||||
|
<button class="dialbtn" data-inline="true">1</button>
|
||||||
|
<button class="dialbtn" data-inline="true">2</button>
|
||||||
|
<button class="dialbtn" data-inline="true">3</button>
|
||||||
|
<br>
|
||||||
|
<button class="dialbtn" data-inline="true">4</button>
|
||||||
|
<button class="dialbtn" data-inline="true">5</button>
|
||||||
|
<button class="dialbtn" data-inline="true">6</button>
|
||||||
|
<br>
|
||||||
|
<button class="dialbtn" data-inline="true">7</button>
|
||||||
|
<button class="dialbtn" data-inline="true">8</button>
|
||||||
|
<button class="dialbtn" data-inline="true">9</button>
|
||||||
|
<br>
|
||||||
|
<button class="dialbtn" data-inline="true">*</button>
|
||||||
|
<button class="dialbtn" data-inline="true">0</button>
|
||||||
|
<button class="dialbtn" data-inline="true">#</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button data-inline="true" id="clearbtn">Clear</button>
|
||||||
|
<button data-inline="true" id="callbtn">Call</button>
|
||||||
|
<br><br>
|
||||||
|
<div style="color:blue" id="main_info"> </div><br><br>
|
||||||
|
<img src="img/verto_black_web.gif" width="300"><br><br>
|
||||||
|
<button data-inline="true"id="logoutbtn">Log Out</button>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<label><input id="use_vid" type="checkbox" value="foo" > Use Video</label>
|
||||||
|
<label><input id="use_stereo" type="checkbox" value="foo" > Stereo Audio</label>
|
||||||
|
<br>
|
||||||
|
<!--
|
||||||
|
<b>TEXT</b><br>To: <input type="text" size="20" id="textto"/> MSG: <input type="text" size="40" id="textmsg"/>
|
||||||
|
<button id="vtxtbtn">Send</button>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table width=500 style="font-size:11pt;font-face:arial">
|
||||||
|
<tr><td align=center colspan=2><b>FreeSWITCH VERTO™ WebRTC Demo Directory<Br><br></td></tr>
|
||||||
|
<tr><td width=100><b>Dial</b></td><td><b>Desc</b></td></tr>
|
||||||
|
<tr><td align=left colspan=2><hr></td></tr>
|
||||||
|
|
||||||
|
<tr><td>3d1</td><td> 3D sound demo #1</td></tr>
|
||||||
|
<tr><td>3d2</td><td> 3D sound demo #2</td></tr>
|
||||||
|
|
||||||
|
<tr><td>stereo1</td><td> Stereo sound demo #1</td></tr>
|
||||||
|
<tr><td>stereo2</td><td> Stereo sound demo #2</td></tr>
|
||||||
|
<tr><td>stereo3</td><td> Stereo sound demo #3</td></tr>
|
||||||
|
<tr><td>3500</td><td>Local 48k Stereo Conference</td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
<tr><td>cluecon</td><td> ClueCon Hotline</td></tr>
|
||||||
|
<tr><td><number></td><td>Call a US/Canda Number</td></tr>
|
||||||
|
|
||||||
|
<tr><td>vuc</td><td>VoIP Users Conference</td></tr>
|
||||||
|
<tr><td>888</td><td>FreeSWITCH Community Conference</td></tr>
|
||||||
|
|
||||||
|
<tr><td>3300</td><td>Local 48k Conference</td></tr>
|
||||||
|
<tr><td>5000</td><td>Try the Demo IVR</td></tr>
|
||||||
|
<tr><td>9664</td><td>Listen to Hold Music</td></tr>
|
||||||
|
<tr><td>9386</td><td>Funny Prompts</td></tr>
|
||||||
|
<tr><td>9198</td><td>Tetris (tone generator)</td></tr>
|
||||||
|
<tr><td colspan=2><Br>
|
||||||
|
<center>
|
||||||
|
<br><br><br>
|
||||||
|
</td></tr>
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div><!-- /page -->
|
||||||
|
|
||||||
|
<div data-role="page" id="dialog-logout" data-close-btn="none">
|
||||||
|
<div data-role="header">
|
||||||
|
<h2>Logged Out</h2>
|
||||||
|
</div>
|
||||||
|
<div data-role="content">
|
||||||
|
<p>You have been logged out or disconnected from the server.</p>
|
||||||
|
|
||||||
|
<button onclick="$('#dialog-logout').dialog('close')">OK</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="page" id="dialog-login-error" data-close-btn="none">
|
||||||
|
<div data-role="header">
|
||||||
|
<h2>Login Error</h2>
|
||||||
|
</div>
|
||||||
|
<div data-role="content">
|
||||||
|
<p>Error logging in</p>
|
||||||
|
|
||||||
|
<button onclick="$('#dialog-login-error').dialog('close')">OK</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="page" id="dialog-hold" data-close-btn="none">
|
||||||
|
<div data-role="header">
|
||||||
|
<h2>Call On hold</h2>
|
||||||
|
</div>
|
||||||
|
<div data-role="content">
|
||||||
|
<p>The call is on hold</p>
|
||||||
|
|
||||||
|
<button onclick="$('#dialog-hold').dialog('close');cur_call.toggleHold();">Resume Call</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="page" id="dialog-incoming-call" data-close-btn="none">
|
||||||
|
<div data-role="header">
|
||||||
|
<h2>Incoming Call</h2>
|
||||||
|
</div>
|
||||||
|
<div data-role="content">
|
||||||
|
<div id="dialog-incoming-call-txt"><p>Incoming Call</p></div>
|
||||||
|
<button id="ansbtn">Answer</button>
|
||||||
|
<div id="vansdiv"><button id="vansbtn">Answer Video</button></div>
|
||||||
|
<button id="declinebtn">Decline</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/jquery-2.0.3.min.js"></script>
|
||||||
|
<script type="text/javascript" src="js/jquery.mobile-1.3.2.min.js"></script>
|
||||||
|
<script type="text/javascript" src="js/jquery.json-2.4.min.js"></script>
|
||||||
|
<script type="text/javascript" src="js/jquery.cookie.js"></script>
|
||||||
|
<script type="text/javascript" src="js/jquery.dataTables.js"></script>
|
||||||
|
<script type="text/javascript" src="js/verto-min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="verto.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
6
html5/verto/demo/js/jquery-2.0.3.min.js
vendored
Normal file
90
html5/verto/demo/js/jquery.cookie.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*!
|
||||||
|
* jQuery Cookie Plugin v1.3.1
|
||||||
|
* https://github.com/carhartl/jquery-cookie
|
||||||
|
*
|
||||||
|
* Copyright 2013 Klaus Hartl
|
||||||
|
* Released under the MIT license
|
||||||
|
*/
|
||||||
|
(function ($, document, undefined) {
|
||||||
|
|
||||||
|
var pluses = /\+/g;
|
||||||
|
|
||||||
|
function raw(s) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function decoded(s) {
|
||||||
|
return unRfc2068(decodeURIComponent(s.replace(pluses, ' ')));
|
||||||
|
}
|
||||||
|
|
||||||
|
function unRfc2068(value) {
|
||||||
|
if (value.indexOf('"') === 0) {
|
||||||
|
// This is a quoted cookie as according to RFC2068, unescape
|
||||||
|
value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromJSON(value) {
|
||||||
|
return config.json ? JSON.parse(value) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = $.cookie = function (key, value, options) {
|
||||||
|
|
||||||
|
// write
|
||||||
|
if (value !== undefined) {
|
||||||
|
options = $.extend({}, config.defaults, options);
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
options.expires = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof options.expires === 'number') {
|
||||||
|
var days = options.expires, t = options.expires = new Date();
|
||||||
|
t.setDate(t.getDate() + days);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = config.json ? JSON.stringify(value) : String(value);
|
||||||
|
|
||||||
|
return (document.cookie = [
|
||||||
|
encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value),
|
||||||
|
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
||||||
|
options.path ? '; path=' + options.path : '',
|
||||||
|
options.domain ? '; domain=' + options.domain : '',
|
||||||
|
options.secure ? '; secure' : ''
|
||||||
|
].join(''));
|
||||||
|
}
|
||||||
|
|
||||||
|
// read
|
||||||
|
var decode = config.raw ? raw : decoded;
|
||||||
|
var cookies = document.cookie.split('; ');
|
||||||
|
var result = key ? null : {};
|
||||||
|
for (var i = 0, l = cookies.length; i < l; i++) {
|
||||||
|
var parts = cookies[i].split('=');
|
||||||
|
var name = decode(parts.shift());
|
||||||
|
var cookie = decode(parts.join('='));
|
||||||
|
|
||||||
|
if (key && key === name) {
|
||||||
|
result = fromJSON(cookie);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
result[name] = fromJSON(cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.defaults = {};
|
||||||
|
|
||||||
|
$.removeCookie = function (key, options) {
|
||||||
|
if ($.cookie(key) !== null) {
|
||||||
|
$.cookie(key, null, options);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery, document);
|
12099
html5/verto/demo/js/jquery.dataTables.js
vendored
Normal file
23
html5/verto/demo/js/jquery.json-2.4.min.js
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*! jQuery JSON plugin 2.4.0 | code.google.com/p/jquery-json */
|
||||||
|
(function($){'use strict';var escape=/["\\\x00-\x1f\x7f-\x9f]/g,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},hasOwn=Object.prototype.hasOwnProperty;$.toJSON=typeof JSON==='object'&&JSON.stringify?JSON.stringify:function(o){if(o===null){return'null';}
|
||||||
|
var pairs,k,name,val,type=$.type(o);if(type==='undefined'){return undefined;}
|
||||||
|
if(type==='number'||type==='boolean'){return String(o);}
|
||||||
|
if(type==='string'){return $.quoteString(o);}
|
||||||
|
if(typeof o.toJSON==='function'){return $.toJSON(o.toJSON());}
|
||||||
|
if(type==='date'){var month=o.getUTCMonth()+1,day=o.getUTCDate(),year=o.getUTCFullYear(),hours=o.getUTCHours(),minutes=o.getUTCMinutes(),seconds=o.getUTCSeconds(),milli=o.getUTCMilliseconds();if(month<10){month='0'+month;}
|
||||||
|
if(day<10){day='0'+day;}
|
||||||
|
if(hours<10){hours='0'+hours;}
|
||||||
|
if(minutes<10){minutes='0'+minutes;}
|
||||||
|
if(seconds<10){seconds='0'+seconds;}
|
||||||
|
if(milli<100){milli='0'+milli;}
|
||||||
|
if(milli<10){milli='0'+milli;}
|
||||||
|
return'"'+year+'-'+month+'-'+day+'T'+
|
||||||
|
hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}
|
||||||
|
pairs=[];if($.isArray(o)){for(k=0;k<o.length;k++){pairs.push($.toJSON(o[k])||'null');}
|
||||||
|
return'['+pairs.join(',')+']';}
|
||||||
|
if(typeof o==='object'){for(k in o){if(hasOwn.call(o,k)){type=typeof k;if(type==='number'){name='"'+k+'"';}else if(type==='string'){name=$.quoteString(k);}else{continue;}
|
||||||
|
type=typeof o[k];if(type!=='function'&&type!=='undefined'){val=$.toJSON(o[k]);pairs.push(name+':'+val);}}}
|
||||||
|
return'{'+pairs.join(',')+'}';}};$.evalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(str){return eval('('+str+')');};$.secureEvalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(str){var filtered=str.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered)){return eval('('+str+')');}
|
||||||
|
throw new SyntaxError('Error parsing JSON, source is not valid.');};$.quoteString=function(str){if(str.match(escape)){return'"'+str.replace(escape,function(a){var c=meta[a];if(typeof c==='string'){return c;}
|
||||||
|
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
|
||||||
|
return'"'+str+'"';};}(jQuery));
|
9
html5/verto/demo/js/jquery.mobile-1.3.2.min.js
vendored
Normal file
215
html5/verto/demo/js/verto-min.js
vendored
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
|
||||||
|
(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);}
|
||||||
|
function findLineInRange(sdpLines,startLine,endLine,prefix,substr){var realEndLine=(endLine!=-1)?endLine:sdpLines.length;for(var i=startLine;i<realEndLine;++i){if(sdpLines[i].indexOf(prefix)===0){if(!substr||sdpLines[i].toLowerCase().indexOf(substr.toLowerCase())!==-1){return i;}}}
|
||||||
|
return null;}
|
||||||
|
function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+');var result=sdpLine.match(pattern);return(result&&result.length==2)?result[1]:null;}
|
||||||
|
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,videoParams:{},callbacks:{onICEComplete:function(){},onICE:function(){},onOfferSDP:function(){}}},options);this.mediaData={SDP:null,profile:{},candidateList:[]};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;self.constraints.mandatory.OfferToReceiveVideo=true;}else{self.options.useVideo=null;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){console.log('There has been a problem retrieving the streams - did you allow access?');}
|
||||||
|
function onStreamSuccess(self){console.log("Stream Success");}
|
||||||
|
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");}
|
||||||
|
function onChannelError(self,e){console.error("Channel Error",e);doCallback(self,"onError",e);}
|
||||||
|
function onICESDP(self,sdp){self.mediaData.SDP=self.stereoHack(sdp.sdp);console.log("ICE SDP");doCallback(self,"onICESDP");}
|
||||||
|
function onAnswerSDP(self,sdp){self.answer.SDP=self.stereoHack(sdp.sdp);console.log("ICE ANSWER SDP");doCallback(self,"onAnswerSDP",self.answer.SDP);}
|
||||||
|
function onMessage(self,msg){console.log("Message");doCallback(self,"onICESDP",msg);}
|
||||||
|
function onRemoteStream(self,stream){if(self.options.useVideo){self.options.useVideo.style.display='block';}
|
||||||
|
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';}
|
||||||
|
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,offerSDP:{type:"offer",sdp:self.remoteSDP}});onStreamSuccess(self);}
|
||||||
|
function onError(){onStreamError(self);}
|
||||||
|
getUserMedia({constraints:{audio:true,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});onStreamSuccess(self);}
|
||||||
|
function onError(){onStreamError(self);}
|
||||||
|
getUserMedia({constraints:{audio:true,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={iceServers:options.iceServers||[STUN]};if(!moz&&!options.iceServers){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}];}
|
||||||
|
var peer=new PeerConnection(iceServers,optional);openOffererChannel();var x=0;peer.onicecandidate=function(event){if(event.candidate){options.onICE(event.candidate);}else{if(options.onICEComplete){options.onICEComplete();}
|
||||||
|
if(options.type=="offer"){if(!moz&&!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}else{if(!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}}};if(options.attachStream)peer.addStream(options.attachStream);if(options.attachStreams&&options.attachStream.length){var streams=options.attachStreams;for(var i=0;i<streams.length;i++){peer.addStream(streams[i]);}}
|
||||||
|
peer.onaddstream=function(event){var remoteMediaStream=event.stream;remoteMediaStream.onended=function(){if(options.onRemoteStreamEnded)options.onRemoteStreamEnded(remoteMediaStream);};if(options.onRemoteStream)options.onRemoteStream(remoteMediaStream);};var constraints=options.constraints||{optional:[],mandatory:{OfferToReceiveAudio:true,OfferToReceiveVideo:true}};function createOffer(){if(!options.onOfferSDP)return;peer.createOffer(function(sessionDescription){sessionDescription.sdp=serializeSdp(sessionDescription.sdp);peer.setLocalDescription(sessionDescription);options.onOfferSDP(sessionDescription);if(moz&&options.onICESDP){options.onICESDP(sessionDescription);}},onSdpError,constraints);}
|
||||||
|
function createAnswer(){if(options.type!="answer")return;peer.setRemoteDescription(new SessionDescription(options.offerSDP),onSdpSuccess,onSdpError);peer.createAnswer(function(sessionDescription){sessionDescription.sdp=serializeSdp(sessionDescription.sdp);peer.setLocalDescription(sessionDescription);if(options.onAnswerSDP){options.onAnswerSDP(sessionDescription);}},onSdpError,constraints);}
|
||||||
|
if((options.onChannelMessage&&!moz)||!options.onChannelMessage){createOffer();createAnswer();}
|
||||||
|
function setBandwidth(sdp){sdp=sdp.replace(/b=AS([^\r\n]+\r\n)/g,'');sdp=sdp.replace(/a=mid:data\r\n/g,'a=mid:data\r\nb=AS:1638400\r\n');return sdp;}
|
||||||
|
function getInteropSDP(sdp){var chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''),extractedChars='';function getChars(){extractedChars+=chars[parseInt(Math.random()*40)]||'';if(extractedChars.length<40)getChars();return extractedChars;}
|
||||||
|
if(options.onAnswerSDP)sdp=sdp.replace(/(a=crypto:0 AES_CM_128_HMAC_SHA1_32)(.*?)(\r\n)/g,'');var inline=getChars()+'\r\n'+(extractedChars='');sdp=sdp.indexOf('a=crypto')==-1?sdp.replace(/c=IN/g,'a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:'+inline+'c=IN'):sdp;return sdp;}
|
||||||
|
function serializeSdp(sdp){return sdp;}
|
||||||
|
var channel;function openOffererChannel(){if(!options.onChannelMessage||(moz&&!options.onOfferSDP))return;_openOffererChannel();if(!moz)return;navigator.mozGetUserMedia({audio:true,fake:true},function(stream){peer.addStream(stream);createOffer();},useless);}
|
||||||
|
function _openOffererChannel(){channel=peer.createDataChannel(options.channel||'RTCDataChannel',moz?{}:{reliable:false});if(moz)channel.binaryType='blob';setChannelEvents();}
|
||||||
|
function setChannelEvents(){channel.onmessage=function(event){if(options.onChannelMessage)options.onChannelMessage(event);};channel.onopen=function(){if(options.onChannelOpened)options.onChannelOpened(channel);};channel.onclose=function(event){if(options.onChannelClosed)options.onChannelClosed(event);console.warn('WebRTC DataChannel closed',event);};channel.onerror=function(event){if(options.onChannelError)options.onChannelError(event);console.error('WebRTC DataChannel error',event);};}
|
||||||
|
if(options.onAnswerSDP&&moz&&options.onChannelMessage)openAnswererChannel();function openAnswererChannel(){peer.ondatachannel=function(event){channel=event.channel;channel.binaryType='blob';setChannelEvents();};if(!moz)return;navigator.mozGetUserMedia({audio:true,fake:true},function(stream){peer.addStream(stream);createAnswer();},useless);}
|
||||||
|
function useless(){log('Error in fake:true');}
|
||||||
|
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);}
|
||||||
|
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,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);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={};}
|
||||||
|
if(this.options.sessid){params.sessid=this.options.sessid;}
|
||||||
|
var request={jsonrpc:'2.0',method:method,params:params,id:this._current_id++};if(!success_cb){success_cb=function(e){console.log("Success: ",e);};}
|
||||||
|
if(!error_cb){error_cb=function(e){console.log("Error: ",e);};}
|
||||||
|
var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this._wsCall(socket,request,success_cb,error_cb);return;}
|
||||||
|
if(this.options.ajaxUrl===null){throw"$.JsonRpcClient.call used with no websocket and no http endpoint.";}
|
||||||
|
$.ajax({type:'POST',url:this.options.ajaxUrl,data:$.toJSON(request),dataType:'json',cache:false,success:function(data){if('error'in data)error_cb(data.error,this);success_cb(data.result,this);},error:function(jqXHR,textStatus,errorThrown){try{var response=$.parseJSON(jqXHR.responseText);if('console'in window)console.log(response);error_cb(response.error,this);}
|
||||||
|
catch(err){error_cb({error:jqXHR.responseText},this);}}});};$.JsonRpcClient.prototype.notify=function(method,params){if(this.options.sessid){params.sessid=this.options.sessid;}
|
||||||
|
var request={jsonrpc:'2.0',method:method,params:params};var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this._wsCall(socket,request);return;}
|
||||||
|
if(this.options.ajaxUrl===null){throw"$.JsonRpcClient.notify used with no websocket and no http endpoint.";}
|
||||||
|
$.ajax({type:'POST',url:this.options.ajaxUrl,data:$.toJSON(request),dataType:'json',cache:false});};$.JsonRpcClient.prototype.batch=function(callback,all_done_cb,error_cb){var batch=new $.JsonRpcClient._batchObject(this,all_done_cb,error_cb);callback(batch);batch._execute();};$.JsonRpcClient.prototype.socketReady=function(){if(this._ws_socket===null||this._ws_socket.readyState>1){return false;}
|
||||||
|
return true;}
|
||||||
|
$.JsonRpcClient.prototype.closeSocket=function(){if(self.socketReady()){this._ws_socket.onclose=function(w){console.log("Closing Socket")}
|
||||||
|
this._ws_socket.close();}}
|
||||||
|
$.JsonRpcClient.prototype.loginData=function(params){self.options.login=params.login;self.options.passwd=params.passwd;}
|
||||||
|
$.JsonRpcClient.prototype.connectSocket=function(onmessage_cb){var self=this;if(!self.socketReady()){self.authing=false;this._ws_socket=new WebSocket(this.options.socketUrl);if(this._ws_socket){this._ws_socket.onmessage=onmessage_cb;this._ws_socket.onclose=function(w){if(!self.ws_sleep){self.ws_sleep=2;}
|
||||||
|
self.ws_cnt=0;if(self.options.onWSClose){self.options.onWSClose(self);}
|
||||||
|
console.error("Websocket Lost sleep: "+self.ws_sleep+"sec");setTimeout(function(){console.log("Attempting Reconnection....");self.connectSocket(onmessage_cb);},self.ws_sleep*1000);if(++self.ws_cnt>=150){self.ws_sleep=30;}}
|
||||||
|
this._ws_socket.onopen=function(){this.ws_sleep=2;this.ws_cnt=0;if(self.options.onWSConnect){self.options.onWSConnect(self);}
|
||||||
|
var req;while(req=$.JsonRpcClient.q.pop()){self._ws_socket.send(req);}}}}
|
||||||
|
return this._ws_socket?true:false;}
|
||||||
|
$.JsonRpcClient.prototype._getSocket=function(onmessage_cb){if(this.options.socketUrl===null||!("WebSocket"in window))return null;this.connectSocket(onmessage_cb);return this._ws_socket;};$.JsonRpcClient.q=[];$.JsonRpcClient.prototype._wsCall=function(socket,request,success_cb,error_cb){var request_json=$.toJSON(request);if(socket.readyState<1){self=this;$.JsonRpcClient.q.push(request_json);}
|
||||||
|
else{socket.send(request_json);}
|
||||||
|
if('id'in request&&typeof success_cb!=='undefined'){this._ws_callbacks[request.id]={request:request_json,request_obj:request,success_cb:success_cb,error_cb:error_cb};}};$.JsonRpcClient.prototype._wsOnMessage=function(event){var response;try{response=$.parseJSON(event.data);if(typeof response==='object'&&'jsonrpc'in response&&response.jsonrpc==='2.0'){if('result'in response&&this._ws_callbacks[response.id]){var success_cb=this._ws_callbacks[response.id].success_cb;delete this._ws_callbacks[response.id];success_cb(response.result,this);return;}
|
||||||
|
else if('error'in response&&this._ws_callbacks[response.id]){var error_cb=this._ws_callbacks[response.id].error_cb;var orig_req=this._ws_callbacks[response.id].request;if(!self.authing&&response.error.code==-32000&&self.options.login&&self.options.passwd){self.authing=true;this.call("login",{login:self.options.login,passwd:self.options.passwd},this._ws_callbacks[response.id].request_obj.method=="login"?function(e){self.authing=false;console.log("logged in");delete self._ws_callbacks[response.id];if(self.options.onWSLogin){self.options.onWSLogin(true,self);}}:function(e){self.authing=false;console.log("logged in, resending request id: "+response.id);var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send(orig_req);}
|
||||||
|
if(self.options.onWSLogin){self.options.onWSLogin(true,self);}},function(e){console.log("error logging in, request id:",response.id);delete self._ws_callbacks[response.id];error_cb(response.error,this);if(self.options.onWSLogin){self.options.onWSLogin(false,self);}});return;}
|
||||||
|
delete this._ws_callbacks[response.id];error_cb(response.error,this);return;}}}
|
||||||
|
catch(err){console.log("ERROR: "+err);return;}
|
||||||
|
if(typeof this.options.onmessage==='function'){event.eventData=response;if(!event.eventData){event.eventData={};}
|
||||||
|
var reply=this.options.onmessage(event);if(reply&&typeof reply==="object"&&event.eventData.id){var msg={jsonrpc:"2.0",id:event.eventData.id,result:reply};var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send($.toJSON(msg));}}}};$.JsonRpcClient._batchObject=function(jsonrpcclient,all_done_cb,error_cb){this._requests=[];this.jsonrpcclient=jsonrpcclient;this.all_done_cb=all_done_cb;this.error_cb=typeof error_cb==='function'?error_cb:function(){};};$.JsonRpcClient._batchObject.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};}
|
||||||
|
if(this.options.sessid){params.sessid=this.options.sessid;}
|
||||||
|
if(!success_cb){success_cb=function(e){console.log("Success: ",e);};}
|
||||||
|
if(!error_cb){error_cb=function(e){console.log("Error: ",e);};}
|
||||||
|
this._requests.push({request:{jsonrpc:'2.0',method:method,params:params,id:this.jsonrpcclient._current_id++},success_cb:success_cb,error_cb:error_cb});};$.JsonRpcClient._batchObject.prototype.notify=function(method,params){if(this.options.sessid){params.sessid=this.options.sessid;}
|
||||||
|
this._requests.push({request:{jsonrpc:'2.0',method:method,params:params}});};$.JsonRpcClient._batchObject.prototype._execute=function(){var self=this;if(this._requests.length===0)return;var batch_request=[];var handlers={};var socket=self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage);if(socket!==null){for(var i=0;i<this._requests.length;i++){var call=this._requests[i];var success_cb=('success_cb'in call)?call.success_cb:undefined;var error_cb=('error_cb'in call)?call.error_cb:undefined;self.jsonrpcclient._wsCall(socket,call.request,success_cb,error_cb);}
|
||||||
|
if(typeof all_done_cb==='function')all_done_cb(result);return;}
|
||||||
|
for(var i=0;i<this._requests.length;i++){var 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};}}
|
||||||
|
var 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:{},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,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.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();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++;}
|
||||||
|
if(!msg.body){console.error("Missing Body");err++;}
|
||||||
|
if(err){return false;}
|
||||||
|
verto.sendMethod("verto.info",{msg:msg});return true;};$.verto.prototype.processReply=function(method,success,e){var verto=this;var i;console.log("Response: "+method,success,e);switch(method){case"verto.subscribe":for(i in e.unauthorizedChannels){drop_bad(verto,e.unauthorizedChannels[i]);}
|
||||||
|
for(i in e.subscribedChannels){mark_ready(verto,e.subscribedChannels[i]);}
|
||||||
|
break;case"verto.unsubscribe":break;}};$.verto.prototype.sendMethod=function(method,params){var verto=this;verto.rpcClient.call(method,params,function(e){verto.processReply(method,true,e);},function(e){verto.processReply(method,false,e);});};function do_sub(verto,channel,obj){}
|
||||||
|
function drop_bad(verto,channel){console.error("drop unauthorized channel: "+channel);delete verto.eventSUBS[channel];}
|
||||||
|
function mark_ready(verto,channel){for(var j in verto.eventSUBS[channel]){verto.eventSUBS[channel][j].ready=true;console.log("subscribed to channel: "+channel);if(verto.eventSUBS[channel][j].readyHandler){verto.eventSUBS[channel][j].readyHandler(verto,channel);}}}
|
||||||
|
var SERNO=1;function do_subscribe(verto,channel,subChannels,sparams){var params=sparams||{};var local=params.local;var obj={eventChannel:channel,userData:params.userData,handler:params.handler,ready:false,readyHandler:params.readyHandler,serno:SERNO++};var isnew=false;if(!verto.eventSUBS[channel]){verto.eventSUBS[channel]=[];subChannels.push(channel);isnew=true;}
|
||||||
|
verto.eventSUBS[channel].push(obj);if(local){obj.ready=true;obj.local=true;}
|
||||||
|
if(!isnew&&verto.eventSUBS[channel][0].ready){obj.ready=true;if(obj.readyHandler){obj.readyHandler(verto,channel);}}
|
||||||
|
return{serno:obj.serno,eventChannel:channel};}
|
||||||
|
$.verto.prototype.subscribe=function(channel,sparams){var verto=this;var r=[];var subChannels=[];var params=sparams||{};if(typeof(channel)==="string"){r.push(do_subscribe(verto,channel,subChannels,params));}else{for(var i in channel){r.push(do_subscribe(verto,channel,subChannels,params));}}
|
||||||
|
if(subChannels.length){verto.sendMethod("verto.subscribe",{eventChannel:subChannels.length==1?subChannels[0]:subChannels,subParams:params.subParams});}
|
||||||
|
return r;};$.verto.prototype.unsubscribe=function(handle){var verto=this;var i;if(!handle){for(i in verto.eventSUBS){if(verto.eventSUBS[i]){verto.unsubscribe(verto.eventSUBS[i]);}}}else{var unsubChannels={};var sendChannels=[];var channel;if(typeof(handle)=="string"){delete verto.eventSUBS[handle];unsubChannels[handle]++;}else{for(i in handle){if(typeof(handle[i])=="string"){channel=handle[i];delete verto.eventSUBS[channel];unsubChannels[channel]++;}else{var repl=[];channel=handle[i].eventChannel;for(var j in verto.eventSUBS[channel]){if(verto.eventSUBS[channel][j].serno==handle[i].serno){}else{repl.push(verto.eventSUBS[channel][j]);}}
|
||||||
|
verto.eventSUBS[channel]=repl;if(verto.eventSUBS[channel].length===0){delete verto.eventSUBS[channel];unsubChannels[channel]++;}}}}
|
||||||
|
for(var u in unsubChannels){console.log("Sending Unsubscribe for: ",u);sendChannels.push(u);}
|
||||||
|
if(sendChannels.length){verto.sendMethod("verto.unsubscribe",{eventChannel:sendChannels.length==1?sendChannels[0]:sendChannels});}}};$.verto.prototype.broadcast=function(channel,params){var verto=this;var msg={eventChannel:channel,data:{}};for(var i in params){msg.data[i]=params[i];}
|
||||||
|
verto.sendMethod("verto.broadcast",msg);};$.verto.prototype.purge=function(callID){var verto=this;var x=0;var i;for(i in verto.dialogs){if(!x){console.log("purging dialogs");}
|
||||||
|
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.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",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);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;}
|
||||||
|
dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);break;default:console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED");break;}}
|
||||||
|
return{method:data.method};}else{switch(data.method){case'verto.event':var list=null;var key=null;if(data.params){key=data.params.eventChannel;}
|
||||||
|
if(key){list=verto.eventSUBS[key];if(!list){list=verto.eventSUBS[key.split(".")[0]];}}
|
||||||
|
if(!list&&key&&key===verto.sessid){if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.pvtEvent,data.params);}}else if(!list&&key&&verto.dialogs[key]){verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent,data.params);}else if(!list){if(!key){key="UNDEFINED";}
|
||||||
|
console.error("UNSUBBED or invalid EVENT "+key+" IGNORED");}else{for(var i in list){var sub=list[i];if(!sub||!sub.ready){console.error("invalid EVENT for "+key+" IGNORED");}else if(sub.handler){sub.handler(verto,data.params,sub.userData);}else if(verto.callbacks.onEvent){verto.callbacks.onEvent(verto,data.params,sub.userData);}else{console.log("EVENT:",data.params);}}}
|
||||||
|
break;case"verto.info":if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.info,data.params.msg);}
|
||||||
|
console.error(data);console.debug("MESSAGE from: "+data.params.msg.from,data.params.msg.body);break;default:console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED",data.method);break;}}};var del_array=function(array,name){var r=[];var len=array.length;for(var i=0;i<len;i++){if(array[i]!=name){r.push(array[i]);}}
|
||||||
|
return r;};var hashArray=function(){var vha=this;var hash={};var array=[];vha.reorder=function(a){array=a;var h=hash;hash={};var len=array.length;for(var i=0;i<len;i++){var key=array[i];if(h[key]){hash[key]=h[key];delete h[key];}}
|
||||||
|
h=undefined;};vha.clear=function(){hash=undefined;array=undefined;hash={};array=[];};vha.add=function(name,val,insertAt){var redraw=false;if(!hash[name]){if(insertAt===undefined||insertAt<0||insertAt>=array.length){array.push(name);}else{var x=0;var n=[];var len=array.length;for(var i=0;i<len;i++){if(x++==insertAt){n.push(name);}
|
||||||
|
n.push(array[i]);}
|
||||||
|
array=undefined;array=n;n=undefined;redraw=true;}}
|
||||||
|
hash[name]=val;return redraw;};vha.del=function(name){var r=false;if(hash[name]){array=del_array(array,name);delete hash[name];r=true;}else{console.error("can't del nonexistant key "+name);}
|
||||||
|
return r;};vha.get=function(name){return hash[name];};vha.order=function(){return array;};vha.hash=function(){return hash;};vha.indexOf=function(name){var len=array.length;for(var i=0;i<len;i++){if(array[i]==name){return i;}}};vha.arrayLen=function(){return array.length;};vha.asArray=function(){var r=[];var len=array.length;for(var i=0;i<len;i++){var key=array[i];r.push(hash[key]);}
|
||||||
|
return r;};vha.each=function(cb){var len=array.length;for(var i=0;i<len;i++){cb(array[i],hash[array[i]]);}};vha.dump=function(html){var str="";vha.each(function(name,val){str+="name: "+name+" val: "+JSON.stringify(val)+(html?"<br>":"\n");});return str;};};$.verto.liveArray=function(verto,context,name,config){var la=this;var lastSerno=0;var binding=null;var user_obj=config.userObj;var local=false;hashArray.call(la);la._add=la.add;la._del=la.del;la._reorder=la.reorder;la._clear=la.clear;la.context=context;la.name=name;la.user_obj=user_obj;la.verto=verto;la.broadcast=function(channel,obj){verto.broadcast(channel,obj);};la.errs=0;la.clear=function(){la._clear();lastSerno=0;if(la.onChange){la.onChange(la,{action:"clear"});}};la.checkSerno=function(serno){if(serno<0){return true;}
|
||||||
|
if(lastSerno>0&&serno!=(lastSerno+1)){if(la.onErr){la.onErr(la,{lastSerno:lastSerno,serno:serno});}
|
||||||
|
la.errs++;console.debug(la.errs);if(la.errs<3){la.bootstrap(la.user_obj);}
|
||||||
|
return false;}else{lastSerno=serno;return true;}};la.reorder=function(serno,a){if(la.checkSerno(serno)){la._reorder(a);if(la.onChange){la.onChange(la,{serno:serno,action:"reorder"});}}};la.init=function(serno,val,key,index){if(key===null||key===undefined){key=serno;}
|
||||||
|
if(la.checkSerno(serno)){if(la.onChange){la.onChange(la,{serno:serno,action:"init",index:index,key:key,data:val});}}};la.bootObj=function(serno,val){if(la.checkSerno(serno)){for(var i in val){la._add(val[i][0],val[i][1]);}
|
||||||
|
if(la.onChange){la.onChange(la,{serno:serno,action:"bootObj",data:val,redraw:true});}}};la.add=function(serno,val,key,index){if(key===null||key===undefined){key=serno;}
|
||||||
|
if(la.checkSerno(serno)){var redraw=la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"add",index:index,key:key,data:val,redraw:redraw});}}};la.modify=function(serno,val,key,index){if(key===null||key===undefined){key=serno;}
|
||||||
|
if(la.checkSerno(serno)){la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"modify",key:key,data:val,index:index});}}};la.del=function(serno,key,index){if(key===null||key===undefined){key=serno;}
|
||||||
|
if(la.checkSerno(serno)){if(index===null||index<0||index===undefined){index=la.indexOf(key);}
|
||||||
|
var ok=la._del(key);if(ok&&la.onChange){la.onChange(la,{serno:serno,action:"del",key:key,index:index});}}};var eventHandler=function(v,e,la){var packet=e.data;console.error("READ:",packet);if(packet.name!=la.name){return;}
|
||||||
|
switch(packet.action){case"init":la.init(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"bootObj":la.bootObj(packet.wireSerno,packet.data);break;case"add":la.add(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"modify":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.modify(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);}
|
||||||
|
break;case"del":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.del(packet.wireSerno,packet.hashKey,packet.arrIndex);}
|
||||||
|
break;case"clear":la.clear();break;case"reorder":la.reorder(packet.wireSerno,packet.order);break;default:if(la.checkSerno(packet.wireSerno)){if(la.onChange){la.onChange(la,{serno:packet.wireSerno,action:packet.action,data:packet.data});}}
|
||||||
|
break;}};if(la.context){binding=la.verto.subscribe(la.context,{handler:eventHandler,userData:la,subParams:config.subParams});}
|
||||||
|
la.destroy=function(){la._clear();la.verto.unsubscribe(binding);};la.sendCommand=function(cmd,obj){var self=la;self.broadcast(self.context,{liveArray:{command:cmd,context:self.context,name:self.name,obj:obj}});};la.bootstrap=function(obj){var self=la;la.sendCommand("bootstrap",obj);};la.changepage=function(obj){var self=la;self.clear();self.broadcast(self.context,{liveArray:{command:"changepage",context:la.context,name:la.name,obj:obj}});};la.heartbeat=function(obj){var self=la;var callback=function(){self.heartbeat.call(self,obj);};self.broadcast(self.context,{liveArray:{command:"heartbeat",context:self.context,name:self.name,obj:obj}});self.hb_pid=setTimeout(callback,30000);};la.bootstrap(la.user_obj);};$.verto.liveTable=function(verto,context,name,jq,config){var dt;var la=new $.verto.liveArray(verto,context,name,{subParams:config.subParams});var lt=this;lt.liveArray=la;lt.dataTable=dt;lt.verto=verto;lt.destroy=function(){if(dt){dt.fnDestroy();}
|
||||||
|
if(la){la.destroy();}
|
||||||
|
dt=null;la=null;};la.onErr=function(obj,args){console.error("Error: ",obj,args);};la.onChange=function(obj,args){var index=0;var iserr=0;if(!dt){if(!config.aoColumns){if(args.action!="init"){return;}
|
||||||
|
config.aoColumns=[];for(var i in args.data){config.aoColumns.push({"sTitle":args.data[i]});}}
|
||||||
|
dt=jq.dataTable(config);}
|
||||||
|
if(dt&&(args.action=="del"||args.action=="modify")){index=args.index;if(index===undefined&&args.key){index=la.indexOf(args.key);}
|
||||||
|
if(index===undefined){console.error("INVALID PACKET Missing INDEX\n",args);return;}}
|
||||||
|
if(config.onChange){config.onChange(obj,args);}
|
||||||
|
try{switch(args.action){case"bootObj":if(!args.data){console.error("missing data");return;}
|
||||||
|
dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;}
|
||||||
|
if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);}
|
||||||
|
dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;}
|
||||||
|
console.debug(args,index);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;conf
|
||||||
|
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 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>"+"</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();});$("#"+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;$(".jsDataTable").width(confMan.params.hasVid?"900px":"800px");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("");}
|
||||||
|
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.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("Moderator Controls Ready<br><br>")},4000);}}});}
|
||||||
|
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;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},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(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}}
|
||||||
|
dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_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,});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;}
|
||||||
|
$.verto.dialog.prototype.setState=function(state){var dialog=this;if(dialog.state==$.verto.enum.state.ringing){dialog.stopRinging();}
|
||||||
|
if(dialog.state==state||!checkStateChange(dialog.state,state)){console.error("Dialog "+dialog.callID+": INVALID state change from "+dialog.state.name+" to "+state.name);dialog.hangup();return false;}
|
||||||
|
console.error("Dialog "+dialog.callID+": state change from "+dialog.state.name+" to "+state.name);dialog.lastState=dialog.state;dialog.state=state;if(!dialog.causeCode){dialog.causeCode=16;}
|
||||||
|
if(!dialog.cause){dialog.cause="NORMAL CLEARING";}
|
||||||
|
if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);}
|
||||||
|
switch(dialog.state){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 verto.dialogs[dialog.callID];dialog.rtc.stop();break;}
|
||||||
|
return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;console.log("Response: "+method+" State:"+dialog.state.name,success,e);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){cur_call.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;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.rtc.createAnswer(dialog.params.sdp);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;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{dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("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.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.early);},function(e){console.error(e);dialog.hangup();});console.log("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,ringing:1,destroy:1,answering:1},requesting:{trying:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{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 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);
|
BIN
html5/verto/demo/sounds/bell_ring2.mp3
Normal file
BIN
html5/verto/demo/sounds/bell_ring2.wav
Normal file
412
html5/verto/demo/verto.js
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
'use strict';
|
||||||
|
var cur_call = null;
|
||||||
|
var confMan = null;
|
||||||
|
var $display = $("#display");
|
||||||
|
var verto;
|
||||||
|
var ringing = false;
|
||||||
|
|
||||||
|
function display(msg) {
|
||||||
|
$("#calltitle").html(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearConfMan() {
|
||||||
|
if (confMan) {
|
||||||
|
confMan.destroy();
|
||||||
|
confMan = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#conf").hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function goto_dialog(where) {
|
||||||
|
$.mobile.changePage("#dialog-" + where, {
|
||||||
|
role: "dialog"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function goto_page(where) {
|
||||||
|
$.mobile.changePage("#page-" + where);
|
||||||
|
}
|
||||||
|
|
||||||
|
var first_login = false;
|
||||||
|
var online_visible = false;
|
||||||
|
function online(on) {
|
||||||
|
if (on) {
|
||||||
|
$("#online").show();
|
||||||
|
$("#offline").hide();
|
||||||
|
first_login = true;
|
||||||
|
} else {
|
||||||
|
if (first_login && online_visible) {
|
||||||
|
goto_dialog("logout");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#online").hide();
|
||||||
|
$("#offline").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
online_visible = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_vid() {
|
||||||
|
var use_vid = $("#use_vid").is(':checked');
|
||||||
|
return use_vid;
|
||||||
|
}
|
||||||
|
|
||||||
|
var callbacks = {
|
||||||
|
|
||||||
|
onMessage: function(verto, dialog, msg, data) {
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
case $.verto.enum.message.pvtEvent:
|
||||||
|
console.error("pvtEvent", data.pvtData.action);
|
||||||
|
if (data.pvtData) {
|
||||||
|
switch (data.pvtData.action) {
|
||||||
|
|
||||||
|
case "conference-liveArray-part":
|
||||||
|
clearConfMan();
|
||||||
|
break;
|
||||||
|
case "conference-liveArray-join":
|
||||||
|
clearConfMan();
|
||||||
|
confMan = new $.verto.confMan(verto, {
|
||||||
|
tableID: "#conf_list",
|
||||||
|
statusID: "#conf_count",
|
||||||
|
mainModID: "#conf_mod",
|
||||||
|
displayID: "#conf_display",
|
||||||
|
dialog: dialog,
|
||||||
|
hasVid: check_vid(),
|
||||||
|
laData: data.pvtData
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#conf").show();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case $.verto.enum.message.info:
|
||||||
|
$("#text").html("Message from: <b>" + data.from + "</b>:<br>" + "<pre>" + data.body + "</pre>");
|
||||||
|
break;
|
||||||
|
case $.verto.enum.message.display:
|
||||||
|
var party = dialog.params.remote_caller_id_name + "<" + dialog.params.remote_caller_id_number + ">";
|
||||||
|
display("Talking to: " + dialog.cidString());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onDialogState: function(d) {
|
||||||
|
cur_call = d;
|
||||||
|
|
||||||
|
if (d.state == $.verto.enum.state.ringing) {
|
||||||
|
ringing = true;
|
||||||
|
} else {
|
||||||
|
ringing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (d.state) {
|
||||||
|
case $.verto.enum.state.ringing:
|
||||||
|
display("Call From: " + d.cidString());
|
||||||
|
|
||||||
|
$("#ansbtn").click(function() {
|
||||||
|
cur_call.answer({
|
||||||
|
useStereo: $("#use_stereo").is(':checked')
|
||||||
|
});
|
||||||
|
$('#dialog-incoming-call').dialog('close');
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#declinebtn").click(function() {
|
||||||
|
cur_call.hangup();
|
||||||
|
$('#dialog-incoming-call').dialog('close');
|
||||||
|
});
|
||||||
|
|
||||||
|
goto_dialog("incoming-call");
|
||||||
|
$("#dialog-incoming-call-txt").text("Incoming call from: " + d.cidString());
|
||||||
|
|
||||||
|
if (d.params.wantVideo) {
|
||||||
|
$("#vansbtn").click(function() {
|
||||||
|
$("#use_vid").prop("checked", true);
|
||||||
|
cur_call.answer({
|
||||||
|
useVideo: true,
|
||||||
|
useStereo: $("#use_stereo").is(':checked')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// the buttons in this jquery mobile wont hide .. gotta wrap them in a div as a workaround
|
||||||
|
$("#vansdiv").show();
|
||||||
|
} else {
|
||||||
|
$("#vansdiv").hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case $.verto.enum.state.early:
|
||||||
|
case $.verto.enum.state.active:
|
||||||
|
display("Talking to: " + d.cidString());
|
||||||
|
goto_page("incall");
|
||||||
|
break;
|
||||||
|
case $.verto.enum.state.hangup:
|
||||||
|
$("#main_info").html("Call ended with cause: " + d.cause);
|
||||||
|
case $.verto.enum.state.destroy:
|
||||||
|
$("#hangup_cause").html("");
|
||||||
|
clearConfMan();
|
||||||
|
goto_page("main");
|
||||||
|
cur_call = null;
|
||||||
|
break;
|
||||||
|
case $.verto.enum.state.held:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
display("");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onWSLogin: function(v, success) {
|
||||||
|
display("");
|
||||||
|
|
||||||
|
cur_call = null;
|
||||||
|
ringing = false;
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
online(true);
|
||||||
|
|
||||||
|
verto.subscribe("presence", {
|
||||||
|
handler: function(v, e) {
|
||||||
|
console.error("PRESENCE:", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!window.location.hash) {
|
||||||
|
goto_page("main");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goto_page("login");
|
||||||
|
goto_dialog("login-error");
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onWSClose: function(v, success) {
|
||||||
|
if ($('#online').is(':visible')) {
|
||||||
|
display("");
|
||||||
|
online(false);
|
||||||
|
}
|
||||||
|
var today = new Date();
|
||||||
|
$("#errordisplay").html("Connection Error.<br>Last Attempt: " + today);
|
||||||
|
goto_page("main");
|
||||||
|
},
|
||||||
|
|
||||||
|
onEvent: function(v, e) {
|
||||||
|
console.debug("w00t", e);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
$("#hold").click(function(e) {
|
||||||
|
cur_call.toggleHold();
|
||||||
|
goto_dialog("hold");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#cancelxferbtn").click(function(e) {
|
||||||
|
$("#xferto").val("");
|
||||||
|
$("#xferdiv").hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".startxferbtn").click(function(e) {
|
||||||
|
if ($('#xferdiv').is(':visible')) {
|
||||||
|
var xfer = $("#xferto").val();
|
||||||
|
if (xfer) {
|
||||||
|
cur_call.transfer(xfer);
|
||||||
|
}
|
||||||
|
$("#xferto").val("");
|
||||||
|
$("#xferdiv").hide();
|
||||||
|
} else {
|
||||||
|
$("#xferdiv").show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#clearbtn").click(function(e) {
|
||||||
|
$("#ext").val("");
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".dialbtn").click(function(e) {
|
||||||
|
$("#ext").val($("#ext").val() + e.currentTarget.textContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".dtmf").click(function(e) {
|
||||||
|
if ($('#xferdiv').is(':visible')) {
|
||||||
|
$("#xferto").val($("#xferto").val() + e.currentTarget.textContent);
|
||||||
|
} else {
|
||||||
|
cur_call.dtmf(e.currentTarget.textContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#hupbtn").click(function() {
|
||||||
|
verto.hangup();
|
||||||
|
cur_call = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#webcam").click(function() {
|
||||||
|
check_vid();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#callbtn").click(function() {
|
||||||
|
$('#ext').trigger('change');
|
||||||
|
|
||||||
|
if (cur_call) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#main_info").html("Trying");
|
||||||
|
|
||||||
|
cur_call = verto.newCall({
|
||||||
|
destination_number: $("#ext").val(),
|
||||||
|
caller_id_name: $("#name").val(),
|
||||||
|
caller_id_number: $("#cid").val(),
|
||||||
|
useVideo: check_vid(),
|
||||||
|
useStereo: $("#use_stereo").is(':checked')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function pop(id, cname, dft) {
|
||||||
|
var tmp = $.cookie(cname) || dft;
|
||||||
|
$.cookie(cname, tmp, {
|
||||||
|
expires: 365
|
||||||
|
});
|
||||||
|
$(id).val(tmp).change(function() {
|
||||||
|
$.cookie(cname, $(id).val(), {
|
||||||
|
expires: 365
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
cur_call = null;
|
||||||
|
|
||||||
|
pop("#ext", "verto_demo_ext", "3500");
|
||||||
|
pop("#name", "verto_demo_name", "FreeSWITCH User");
|
||||||
|
pop("#cid", "verto_demo_cid", "1008");
|
||||||
|
pop("#textto", "verto_demo_textto", "1000");
|
||||||
|
|
||||||
|
pop("#login", "verto_demo_login", "1008");
|
||||||
|
pop("#passwd", "verto_demo_passwd", "1234");
|
||||||
|
|
||||||
|
pop("#hostName", "verto_demo_hostname", window.location.hostname);
|
||||||
|
pop("#wsURL", "verto_demo_wsurl", "wss://" + window.location.hostname + ":8082");
|
||||||
|
|
||||||
|
var tmp = $.cookie("verto_demo_vid_checked") || "false";
|
||||||
|
$.cookie("verto_demo_vid_checked", tmp, {
|
||||||
|
expires: 365
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#use_vid").prop("checked", tmp === "true").change(function(e) {
|
||||||
|
tmp = $("#use_vid").is(':checked');
|
||||||
|
$.cookie("verto_demo_vid_checked", tmp ? "true" : "false", {
|
||||||
|
expires: 365
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tmp = $.cookie("verto_demo_stereo_checked") || "false";
|
||||||
|
$.cookie("verto_demo_stereo_checked", tmp, {
|
||||||
|
expires: 365
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#use_stereo").prop("checked", tmp === "true").change(function(e) {
|
||||||
|
tmp = $("#use_stereo").is(':checked');
|
||||||
|
$.cookie("verto_demo_stereo_checked", tmp ? "true" : "false", {
|
||||||
|
expires: 365
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
verto = new $.verto({
|
||||||
|
login: $("#login").val() + "@" + $("#hostName").val(),
|
||||||
|
passwd: $("#passwd").val(),
|
||||||
|
socketUrl: $("#wsURL").val(),
|
||||||
|
tag: "webcam",
|
||||||
|
ringFile: "sounds/bell_ring2.wav",
|
||||||
|
videoParams: {
|
||||||
|
"minWidth": "1280",
|
||||||
|
"minHeight": "720"
|
||||||
|
}
|
||||||
|
},callbacks);
|
||||||
|
|
||||||
|
$("#login").change(function(e) {
|
||||||
|
$("#cid").val(e.currentTarget.value);
|
||||||
|
$.cookie("verto_demo_cid", e.currentTarget.value, {
|
||||||
|
expires: 365
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#vtxtbtn").click(function() {
|
||||||
|
verto.message({
|
||||||
|
to: $("#textto").val(),
|
||||||
|
body: $("#textmsg").val()
|
||||||
|
});
|
||||||
|
$("#textmsg").val("");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#logoutbtn").click(function() {
|
||||||
|
verto.logout();
|
||||||
|
goto_page("login");
|
||||||
|
online(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#loginbtn").click(function() {
|
||||||
|
online(false);
|
||||||
|
verto.loginData({
|
||||||
|
login: $("#login").val() + "@" + $("#hostName").val(),
|
||||||
|
passwd: $("#passwd").val()
|
||||||
|
});
|
||||||
|
verto.login();
|
||||||
|
goto_page("main");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#xferdiv").hide();
|
||||||
|
$("#webcam").hide();
|
||||||
|
|
||||||
|
online(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
init();
|
||||||
|
$("#page-incall").on("pagebeforechange", function(event) {});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind("pagebeforechange", function(e, data) {
|
||||||
|
if (typeof(data.toPage) !== "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (window.location.hash) {
|
||||||
|
|
||||||
|
case "#page-incall":
|
||||||
|
|
||||||
|
console.error(e, data);
|
||||||
|
setTimeout(function() {
|
||||||
|
if (!cur_call) {
|
||||||
|
goto_page("main");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
10000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "#page-main":
|
||||||
|
|
||||||
|
console.error(e, data);
|
||||||
|
setTimeout(function() {
|
||||||
|
if (cur_call && !ringing) {
|
||||||
|
goto_page("incall");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
2000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "#page-login":
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
if (online_visible) {
|
||||||
|
goto_page("main");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
15
html5/verto/js/Makefile
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
JSFILES=src/jquery.FSRTC.js src/jquery.jsonrpcclient.js src/jquery.verto.js
|
||||||
|
|
||||||
|
all: jsmin verto-min.js
|
||||||
|
|
||||||
|
jsmin: jsmin.c
|
||||||
|
$(CC) $< -o $@
|
||||||
|
|
||||||
|
verto-min.js: jsmin $(JSFILES)
|
||||||
|
cat $(JSFILES) | ./jsmin > $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f verto-min.js jsmin *~
|
||||||
|
|
||||||
|
install-demo: all
|
||||||
|
cp verto-min.js ../demo/js
|
10
html5/verto/js/README
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
This file needs to say more.
|
||||||
|
Documentation for the api needs to be developed with jsdoc-toolkit http://pulkitgoyal.in/documenting-jquery-plugins-jsdoc-toolkit/
|
||||||
|
|
||||||
|
Dependancies for DEMO
|
||||||
|
jquery-2.0.3.min.js
|
||||||
|
jquery-2.0.3.min.map
|
||||||
|
jquery.cookie.js
|
||||||
|
jquery.dataTables.js
|
||||||
|
jquery.json-2.4.min.js
|
||||||
|
jquery.mobile-1.3.2.min.js
|
306
html5/verto/js/jsmin.c
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/* jsmin.c
|
||||||
|
2013-03-29
|
||||||
|
|
||||||
|
Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
The Software shall be used for Good, not Evil.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static int theA;
|
||||||
|
static int theB;
|
||||||
|
static int theLookahead = EOF;
|
||||||
|
static int theX = EOF;
|
||||||
|
static int theY = EOF;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
error(char* s)
|
||||||
|
{
|
||||||
|
fputs("JSMIN Error: ", stderr);
|
||||||
|
fputs(s, stderr);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* isAlphanum -- return true if the character is a letter, digit, underscore,
|
||||||
|
dollar sign, or non-ASCII character.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
isAlphanum(int c)
|
||||||
|
{
|
||||||
|
return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
|
||||||
|
(c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\' ||
|
||||||
|
c > 126);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get -- return the next character from stdin. Watch out for lookahead. If
|
||||||
|
the character is a control character, translate it to a space or
|
||||||
|
linefeed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
get()
|
||||||
|
{
|
||||||
|
int c = theLookahead;
|
||||||
|
theLookahead = EOF;
|
||||||
|
if (c == EOF) {
|
||||||
|
c = getc(stdin);
|
||||||
|
}
|
||||||
|
if (c >= ' ' || c == '\n' || c == EOF) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (c == '\r') {
|
||||||
|
return '\n';
|
||||||
|
}
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* peek -- get the next character without getting it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
peek()
|
||||||
|
{
|
||||||
|
theLookahead = get();
|
||||||
|
return theLookahead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* next -- get the next character, excluding comments. peek() is used to see
|
||||||
|
if a '/' is followed by a '/' or '*'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
next()
|
||||||
|
{
|
||||||
|
int c = get();
|
||||||
|
if (c == '/') {
|
||||||
|
switch (peek()) {
|
||||||
|
case '/':
|
||||||
|
for (;;) {
|
||||||
|
c = get();
|
||||||
|
if (c <= '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
get();
|
||||||
|
while (c != ' ') {
|
||||||
|
switch (get()) {
|
||||||
|
case '*':
|
||||||
|
if (peek() == '/') {
|
||||||
|
get();
|
||||||
|
c = ' ';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EOF:
|
||||||
|
error("Unterminated comment.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
theY = theX;
|
||||||
|
theX = c;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* action -- do something! What you do is determined by the argument:
|
||||||
|
1 Output A. Copy B to A. Get the next B.
|
||||||
|
2 Copy B to A. Get the next B. (Delete A).
|
||||||
|
3 Get the next B. (Delete B).
|
||||||
|
action treats a string as a single character. Wow!
|
||||||
|
action recognizes a regular expression if it is preceded by ( or , or =.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
action(int d)
|
||||||
|
{
|
||||||
|
switch (d) {
|
||||||
|
case 1:
|
||||||
|
putc(theA, stdout);
|
||||||
|
if (
|
||||||
|
(theY == '\n' || theY == ' ') &&
|
||||||
|
(theA == '+' || theA == '-' || theA == '*' || theA == '/') &&
|
||||||
|
(theB == '+' || theB == '-' || theB == '*' || theB == '/')
|
||||||
|
) {
|
||||||
|
putc(theY, stdout);
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
theA = theB;
|
||||||
|
if (theA == '\'' || theA == '"' || theA == '`') {
|
||||||
|
for (;;) {
|
||||||
|
putc(theA, stdout);
|
||||||
|
theA = get();
|
||||||
|
if (theA == theB) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (theA == '\\') {
|
||||||
|
putc(theA, stdout);
|
||||||
|
theA = get();
|
||||||
|
}
|
||||||
|
if (theA == EOF) {
|
||||||
|
error("Unterminated string literal.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
theB = next();
|
||||||
|
if (theB == '/' && (
|
||||||
|
theA == '(' || theA == ',' || theA == '=' || theA == ':' ||
|
||||||
|
theA == '[' || theA == '!' || theA == '&' || theA == '|' ||
|
||||||
|
theA == '?' || theA == '+' || theA == '-' || theA == '~' ||
|
||||||
|
theA == '*' || theA == '/' || theA == '{' || theA == '\n'
|
||||||
|
)) {
|
||||||
|
putc(theA, stdout);
|
||||||
|
if (theA == '/' || theA == '*') {
|
||||||
|
putc(' ', stdout);
|
||||||
|
}
|
||||||
|
putc(theB, stdout);
|
||||||
|
for (;;) {
|
||||||
|
theA = get();
|
||||||
|
if (theA == '[') {
|
||||||
|
for (;;) {
|
||||||
|
putc(theA, stdout);
|
||||||
|
theA = get();
|
||||||
|
if (theA == ']') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (theA == '\\') {
|
||||||
|
putc(theA, stdout);
|
||||||
|
theA = get();
|
||||||
|
}
|
||||||
|
if (theA == EOF) {
|
||||||
|
error("Unterminated set in Regular Expression literal.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (theA == '/') {
|
||||||
|
switch (peek()) {
|
||||||
|
case '/':
|
||||||
|
case '*':
|
||||||
|
error("Unterminated set in Regular Expression literal.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (theA =='\\') {
|
||||||
|
putc(theA, stdout);
|
||||||
|
theA = get();
|
||||||
|
}
|
||||||
|
if (theA == EOF) {
|
||||||
|
error("Unterminated Regular Expression literal.");
|
||||||
|
}
|
||||||
|
putc(theA, stdout);
|
||||||
|
}
|
||||||
|
theB = next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* jsmin -- Copy the input to the output, deleting the characters which are
|
||||||
|
insignificant to JavaScript. Comments will be removed. Tabs will be
|
||||||
|
replaced with spaces. Carriage returns will be replaced with linefeeds.
|
||||||
|
Most spaces and linefeeds will be removed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
jsmin()
|
||||||
|
{
|
||||||
|
if (peek() == 0xEF) {
|
||||||
|
get();
|
||||||
|
get();
|
||||||
|
get();
|
||||||
|
}
|
||||||
|
theA = '\n';
|
||||||
|
action(3);
|
||||||
|
while (theA != EOF) {
|
||||||
|
switch (theA) {
|
||||||
|
case ' ':
|
||||||
|
action(isAlphanum(theB) ? 1 : 2);
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
switch (theB) {
|
||||||
|
case '{':
|
||||||
|
case '[':
|
||||||
|
case '(':
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '!':
|
||||||
|
case '~':
|
||||||
|
action(1);
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
action(3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
action(isAlphanum(theB) ? 1 : 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch (theB) {
|
||||||
|
case ' ':
|
||||||
|
action(isAlphanum(theA) ? 1 : 3);
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
switch (theA) {
|
||||||
|
case '}':
|
||||||
|
case ']':
|
||||||
|
case ')':
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
case '`':
|
||||||
|
action(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
action(isAlphanum(theA) ? 1 : 3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
action(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* main -- Output any command line arguments as comments
|
||||||
|
and then minify the input.
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < argc; i += 1) {
|
||||||
|
fprintf(stdout, "// %s\n", argv[i]);
|
||||||
|
}
|
||||||
|
jsmin();
|
||||||
|
return 0;
|
||||||
|
}
|
756
html5/verto/js/src/jquery.FSRTC.js
Normal file
@ -0,0 +1,756 @@
|
|||||||
|
/*
|
||||||
|
* Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH
|
||||||
|
* Copyright (C) 2005-2014, 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 Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
* Portions created by the Initial Developer are Copyright (C)
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
*
|
||||||
|
* jquery.FSRTC.js - WebRTC Glue code
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
// Find the line in sdpLines that starts with |prefix|, and, if specified,
|
||||||
|
// contains |substr| (case-insensitive search).
|
||||||
|
function findLine(sdpLines, prefix, substr) {
|
||||||
|
return findLineInRange(sdpLines, 0, -1, prefix, substr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the line in sdpLines[startLine...endLine - 1] that starts with |prefix|
|
||||||
|
// and, if specified, contains |substr| (case-insensitive search).
|
||||||
|
function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
|
||||||
|
var realEndLine = (endLine != -1) ? endLine : sdpLines.length;
|
||||||
|
for (var i = startLine; i < realEndLine; ++i) {
|
||||||
|
if (sdpLines[i].indexOf(prefix) === 0) {
|
||||||
|
if (!substr || sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the codec payload type from an a=rtpmap:X line.
|
||||||
|
function getCodecPayloadType(sdpLine) {
|
||||||
|
var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+');
|
||||||
|
var result = sdpLine.match(pattern);
|
||||||
|
return (result && result.length == 2) ? result[1] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a new m= line with the specified codec as the first one.
|
||||||
|
function setDefaultCodec(mLine, payload) {
|
||||||
|
var elements = mLine.split(' ');
|
||||||
|
var newLine = [];
|
||||||
|
var index = 0;
|
||||||
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
if (index === 3) // Format of media starts from the fourth.
|
||||||
|
newLine[index++] = payload; // Put target payload to the first.
|
||||||
|
if (elements[i] !== payload) newLine[index++] = elements[i];
|
||||||
|
}
|
||||||
|
return newLine.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
$.FSRTC = function(options) {
|
||||||
|
this.options = $.extend({
|
||||||
|
useVideo: null,
|
||||||
|
useStereo: false,
|
||||||
|
userData: null,
|
||||||
|
videoParams: {},
|
||||||
|
callbacks: {
|
||||||
|
onICEComplete: function() {},
|
||||||
|
onICE: function() {},
|
||||||
|
onOfferSDP: function() {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options);
|
||||||
|
|
||||||
|
this.mediaData = {
|
||||||
|
SDP: null,
|
||||||
|
profile: {},
|
||||||
|
candidateList: []
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
self.constraints.mandatory.OfferToReceiveVideo = true;
|
||||||
|
} else {
|
||||||
|
self.options.useVideo = null;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sets Opus in stereo if stereo is enabled, by adding the stereo=1 fmtp param.
|
||||||
|
$.FSRTC.prototype.stereoHack = function(sdp) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (!self.options.useStereo) {
|
||||||
|
return sdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sdpLines = sdp.split('\r\n');
|
||||||
|
|
||||||
|
// Find opus payload.
|
||||||
|
var opusIndex = findLine(sdpLines, 'a=rtpmap', 'opus/48000'),
|
||||||
|
opusPayload;
|
||||||
|
if (opusIndex) {
|
||||||
|
opusPayload = getCodecPayloadType(sdpLines[opusIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the payload in fmtp line.
|
||||||
|
var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString());
|
||||||
|
if (fmtpLineIndex === null) return sdp;
|
||||||
|
|
||||||
|
// Append stereo=1 to fmtp line.
|
||||||
|
sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; stereo=1');
|
||||||
|
|
||||||
|
sdp = sdpLines.join('\r\n');
|
||||||
|
return sdp;
|
||||||
|
};
|
||||||
|
|
||||||
|
function setCompat() {
|
||||||
|
$.FSRTC.moz = !!navigator.mozGetUserMedia;
|
||||||
|
//navigator.getUserMedia || (navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia);
|
||||||
|
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) {
|
||||||
|
console.log('There has been a problem retrieving the streams - did you allow access?');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onStreamSuccess(self) {
|
||||||
|
console.log("Stream Success");
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChannelError(self, e) {
|
||||||
|
console.error("Channel Error", e);
|
||||||
|
doCallback(self, "onError", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onICESDP(self, sdp) {
|
||||||
|
self.mediaData.SDP = self.stereoHack(sdp.sdp);
|
||||||
|
console.log("ICE SDP");
|
||||||
|
doCallback(self, "onICESDP");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAnswerSDP(self, sdp) {
|
||||||
|
self.answer.SDP = self.stereoHack(sdp.sdp);
|
||||||
|
console.log("ICE ANSWER SDP");
|
||||||
|
doCallback(self, "onAnswerSDP", self.answer.SDP);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMessage(self, msg) {
|
||||||
|
console.log("Message");
|
||||||
|
doCallback(self, "onICESDP", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRemoteStream(self, stream) {
|
||||||
|
if (self.options.useVideo) {
|
||||||
|
self.options.useVideo.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
offerSDP: {
|
||||||
|
type: "offer",
|
||||||
|
sdp: self.remoteSDP
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onStreamSuccess(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError() {
|
||||||
|
onStreamError(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserMedia({
|
||||||
|
constraints: {
|
||||||
|
audio: true,
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
onStreamSuccess(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError() {
|
||||||
|
onStreamError(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserMedia({
|
||||||
|
constraints: {
|
||||||
|
audio: true,
|
||||||
|
video: this.options.useVideo ? {
|
||||||
|
mandatory: this.options.videoParams,
|
||||||
|
optional: []
|
||||||
|
} : null
|
||||||
|
},
|
||||||
|
video: this.options.useVideo ? true : false,
|
||||||
|
onsuccess: onSuccess,
|
||||||
|
onerror: onError
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
navigator.getUserMedia({
|
||||||
|
video: this.options.useVideo,
|
||||||
|
audio: true
|
||||||
|
}, onSuccess, onError);
|
||||||
|
*/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// DERIVED from RTCPeerConnection-v1.5
|
||||||
|
// 2013, @muazkh - github.com/muaz-khan
|
||||||
|
// MIT License - https://www.webrtc-experiment.com/licence/
|
||||||
|
// Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RTCPeerConnection
|
||||||
|
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 = {
|
||||||
|
iceServers: options.iceServers || [STUN]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!moz && !options.iceServers) {
|
||||||
|
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
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
var peer = new PeerConnection(iceServers, optional);
|
||||||
|
|
||||||
|
openOffererChannel();
|
||||||
|
var x = 0;
|
||||||
|
|
||||||
|
peer.onicecandidate = function(event) {
|
||||||
|
if (event.candidate) {
|
||||||
|
options.onICE(event.candidate);
|
||||||
|
} else {
|
||||||
|
if (options.onICEComplete) {
|
||||||
|
options.onICEComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.type == "offer") {
|
||||||
|
if (!moz && !x && options.onICESDP) {
|
||||||
|
options.onICESDP(peer.localDescription);
|
||||||
|
//x = 1;
|
||||||
|
/*
|
||||||
|
x = 1;
|
||||||
|
peer.createOffer(function(sessionDescription) {
|
||||||
|
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||||
|
peer.setLocalDescription(sessionDescription);
|
||||||
|
if (options.onICESDP) {
|
||||||
|
options.onICESDP(sessionDescription);
|
||||||
|
}
|
||||||
|
}, onSdpError, constraints);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!x && options.onICESDP) {
|
||||||
|
options.onICESDP(peer.localDescription);
|
||||||
|
//x = 1;
|
||||||
|
/*
|
||||||
|
x = 1;
|
||||||
|
peer.createAnswer(function(sessionDescription) {
|
||||||
|
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||||
|
peer.setLocalDescription(sessionDescription);
|
||||||
|
if (options.onICESDP) {
|
||||||
|
options.onICESDP(sessionDescription);
|
||||||
|
}
|
||||||
|
}, onSdpError, constraints);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// attachStream = MediaStream;
|
||||||
|
if (options.attachStream) peer.addStream(options.attachStream);
|
||||||
|
|
||||||
|
// attachStreams[0] = audio-stream;
|
||||||
|
// attachStreams[1] = video-stream;
|
||||||
|
// attachStreams[2] = screen-capturing-stream;
|
||||||
|
if (options.attachStreams && options.attachStream.length) {
|
||||||
|
var streams = options.attachStreams;
|
||||||
|
for (var i = 0; i < streams.length; i++) {
|
||||||
|
peer.addStream(streams[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
peer.onaddstream = function(event) {
|
||||||
|
var remoteMediaStream = event.stream;
|
||||||
|
|
||||||
|
// onRemoteStreamEnded(MediaStream)
|
||||||
|
remoteMediaStream.onended = function() {
|
||||||
|
if (options.onRemoteStreamEnded) options.onRemoteStreamEnded(remoteMediaStream);
|
||||||
|
};
|
||||||
|
|
||||||
|
// onRemoteStream(MediaStream)
|
||||||
|
if (options.onRemoteStream) options.onRemoteStream(remoteMediaStream);
|
||||||
|
|
||||||
|
//console.debug('on:add:stream', remoteMediaStream);
|
||||||
|
};
|
||||||
|
|
||||||
|
var constraints = options.constraints || {
|
||||||
|
optional: [],
|
||||||
|
mandatory: {
|
||||||
|
OfferToReceiveAudio: true,
|
||||||
|
OfferToReceiveVideo: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// onOfferSDP(RTCSessionDescription)
|
||||||
|
function createOffer() {
|
||||||
|
if (!options.onOfferSDP) return;
|
||||||
|
|
||||||
|
peer.createOffer(function(sessionDescription) {
|
||||||
|
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||||
|
peer.setLocalDescription(sessionDescription);
|
||||||
|
options.onOfferSDP(sessionDescription);
|
||||||
|
if (moz && options.onICESDP) {
|
||||||
|
options.onICESDP(sessionDescription);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSdpError, constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
// onAnswerSDP(RTCSessionDescription)
|
||||||
|
function createAnswer() {
|
||||||
|
if (options.type != "answer") return;
|
||||||
|
|
||||||
|
//options.offerSDP.sdp = addStereo(options.offerSDP.sdp);
|
||||||
|
peer.setRemoteDescription(new SessionDescription(options.offerSDP), onSdpSuccess, onSdpError);
|
||||||
|
peer.createAnswer(function(sessionDescription) {
|
||||||
|
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||||
|
peer.setLocalDescription(sessionDescription);
|
||||||
|
if (options.onAnswerSDP) {
|
||||||
|
options.onAnswerSDP(sessionDescription);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSdpError, constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if Mozilla Firefox & DataChannel; offer/answer will be created later
|
||||||
|
if ((options.onChannelMessage && !moz) || !options.onChannelMessage) {
|
||||||
|
createOffer();
|
||||||
|
createAnswer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataChannel Bandwidth
|
||||||
|
function setBandwidth(sdp) {
|
||||||
|
// remove existing bandwidth lines
|
||||||
|
sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, '');
|
||||||
|
sdp = sdp.replace(/a=mid:data\r\n/g, 'a=mid:data\r\nb=AS:1638400\r\n');
|
||||||
|
|
||||||
|
return sdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// old: FF<>Chrome interoperability management
|
||||||
|
function getInteropSDP(sdp) {
|
||||||
|
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''),
|
||||||
|
extractedChars = '';
|
||||||
|
|
||||||
|
function getChars() {
|
||||||
|
extractedChars += chars[parseInt(Math.random() * 40)] || '';
|
||||||
|
if (extractedChars.length < 40) getChars();
|
||||||
|
|
||||||
|
return extractedChars;
|
||||||
|
}
|
||||||
|
|
||||||
|
// usually audio-only streaming failure occurs out of audio-specific crypto line
|
||||||
|
// a=crypto:1 AES_CM_128_HMAC_SHA1_32 --------- kAttributeCryptoVoice
|
||||||
|
if (options.onAnswerSDP) sdp = sdp.replace(/(a=crypto:0 AES_CM_128_HMAC_SHA1_32)(.*?)(\r\n)/g, '');
|
||||||
|
|
||||||
|
// video-specific crypto line i.e. SHA1_80
|
||||||
|
// a=crypto:1 AES_CM_128_HMAC_SHA1_80 --------- kAttributeCryptoVideo
|
||||||
|
var inline = getChars() + '\r\n' + (extractedChars = '');
|
||||||
|
sdp = sdp.indexOf('a=crypto') == -1 ? sdp.replace(/c=IN/g, 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:' + inline + 'c=IN') : sdp;
|
||||||
|
|
||||||
|
return sdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
function serializeSdp(sdp) {
|
||||||
|
//if (!moz) sdp = setBandwidth(sdp);
|
||||||
|
//sdp = getInteropSDP(sdp);
|
||||||
|
//console.debug(sdp);
|
||||||
|
return sdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataChannel management
|
||||||
|
var channel;
|
||||||
|
|
||||||
|
function openOffererChannel() {
|
||||||
|
if (!options.onChannelMessage || (moz && !options.onOfferSDP)) return;
|
||||||
|
|
||||||
|
_openOffererChannel();
|
||||||
|
|
||||||
|
if (!moz) return;
|
||||||
|
navigator.mozGetUserMedia({
|
||||||
|
audio: true,
|
||||||
|
fake: true
|
||||||
|
},
|
||||||
|
function(stream) {
|
||||||
|
peer.addStream(stream);
|
||||||
|
createOffer();
|
||||||
|
},
|
||||||
|
useless);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _openOffererChannel() {
|
||||||
|
channel = peer.createDataChannel(options.channel || 'RTCDataChannel', moz ? {} : {
|
||||||
|
reliable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
if (moz) channel.binaryType = 'blob';
|
||||||
|
|
||||||
|
setChannelEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setChannelEvents() {
|
||||||
|
channel.onmessage = function(event) {
|
||||||
|
if (options.onChannelMessage) options.onChannelMessage(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
channel.onopen = function() {
|
||||||
|
if (options.onChannelOpened) options.onChannelOpened(channel);
|
||||||
|
};
|
||||||
|
channel.onclose = function(event) {
|
||||||
|
if (options.onChannelClosed) options.onChannelClosed(event);
|
||||||
|
|
||||||
|
console.warn('WebRTC DataChannel closed', event);
|
||||||
|
};
|
||||||
|
channel.onerror = function(event) {
|
||||||
|
if (options.onChannelError) options.onChannelError(event);
|
||||||
|
|
||||||
|
console.error('WebRTC DataChannel error', event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.onAnswerSDP && moz && options.onChannelMessage) openAnswererChannel();
|
||||||
|
|
||||||
|
function openAnswererChannel() {
|
||||||
|
peer.ondatachannel = function(event) {
|
||||||
|
channel = event.channel;
|
||||||
|
channel.binaryType = 'blob';
|
||||||
|
setChannelEvents();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!moz) return;
|
||||||
|
navigator.mozGetUserMedia({
|
||||||
|
audio: true,
|
||||||
|
fake: true
|
||||||
|
},
|
||||||
|
function(stream) {
|
||||||
|
peer.addStream(stream);
|
||||||
|
createAnswer();
|
||||||
|
},
|
||||||
|
useless);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fake:true is also available on chrome under a flag!
|
||||||
|
function useless() {
|
||||||
|
log('Error in fake:true');
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// getUserMedia
|
||||||
|
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);
|
||||||
|
//video.play();
|
||||||
|
}
|
||||||
|
if (options.onsuccess) {
|
||||||
|
options.onsuccess(stream);
|
||||||
|
}
|
||||||
|
media = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
return media;
|
||||||
|
}
|
||||||
|
|
||||||
|
})(jQuery);
|
653
html5/verto/js/src/jquery.jsonrpcclient.js
Normal file
@ -0,0 +1,653 @@
|
|||||||
|
/*
|
||||||
|
* Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH
|
||||||
|
* Copyright (C) 2005-2014, 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 jquery.jsonrpclient.js modified for Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Textalk AB http://textalk.se/
|
||||||
|
* Portions created by the Initial Developer are Copyright (C)
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
|
*
|
||||||
|
* jquery.jsonrpclient.js - JSON RPC client code
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* This plugin requires jquery.json.js to be available, or at least the methods $.toJSON and
|
||||||
|
* $.parseJSON.
|
||||||
|
*
|
||||||
|
* The plan is to make use of websockets if they are available, but work just as well with only
|
||||||
|
* http if not.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* var foo = new $.JsonRpcClient({ ajaxUrl: '/backend/jsonrpc' });
|
||||||
|
* foo.call(
|
||||||
|
* 'bar', [ 'A parameter', 'B parameter' ],
|
||||||
|
* function(result) { alert('Foo bar answered: ' + result.my_answer); },
|
||||||
|
* function(error) { console.log('There was an error', error); }
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* More examples are available in README.md
|
||||||
|
*/
|
||||||
|
(function($) {
|
||||||
|
/**
|
||||||
|
* @fn new
|
||||||
|
* @memberof $.JsonRpcClient
|
||||||
|
*
|
||||||
|
* @param options An object stating the backends:
|
||||||
|
* ajaxUrl A url (relative or absolute) to a http(s) backend.
|
||||||
|
* socketUrl A url (relative of absolute) to a ws(s) backend.
|
||||||
|
* onmessage A socket message handler for other messages (non-responses).
|
||||||
|
* getSocket A function returning a WebSocket or null.
|
||||||
|
* It must take an onmessage_cb and bind it to the onmessage event
|
||||||
|
* (or chain it before/after some other onmessage handler).
|
||||||
|
* Or, it could return null if no socket is available.
|
||||||
|
* The returned instance must have readyState <= 1, and if less than 1,
|
||||||
|
* react to onopen binding.
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient = function(options) {
|
||||||
|
var self = this;
|
||||||
|
this.options = $.extend({
|
||||||
|
ajaxUrl : null,
|
||||||
|
socketUrl : null, ///< The ws-url for default getSocket.
|
||||||
|
onmessage : null, ///< Other onmessage-handler.
|
||||||
|
login : null, /// auth login
|
||||||
|
passwd : null, /// auth passwd
|
||||||
|
sessid : null,
|
||||||
|
getSocket : function(onmessage_cb) { return self._getSocket(onmessage_cb); }
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
// Declare an instance version of the onmessage callback to wrap 'this'.
|
||||||
|
this.wsOnMessage = function(event) { self._wsOnMessage(event); };
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Holding the WebSocket on default getsocket.
|
||||||
|
$.JsonRpcClient.prototype._ws_socket = null;
|
||||||
|
|
||||||
|
/// Object <id>: { success_cb: cb, error_cb: cb }
|
||||||
|
$.JsonRpcClient.prototype._ws_callbacks = {};
|
||||||
|
|
||||||
|
/// The next JSON-RPC request id.
|
||||||
|
$.JsonRpcClient.prototype._current_id = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn call
|
||||||
|
* @memberof $.JsonRpcClient
|
||||||
|
*
|
||||||
|
* @param method The method to run on JSON-RPC server.
|
||||||
|
* @param params The params; an array or object.
|
||||||
|
* @param success_cb A callback for successful request.
|
||||||
|
* @param error_cb A callback for error.
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) {
|
||||||
|
// Construct the JSON-RPC 2.0 request.
|
||||||
|
|
||||||
|
if (!params) {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.sessid) {
|
||||||
|
params.sessid = this.options.sessid;
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = {
|
||||||
|
jsonrpc : '2.0',
|
||||||
|
method : method,
|
||||||
|
params : params,
|
||||||
|
id : this._current_id++ // Increase the id counter to match request/response
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!success_cb) {
|
||||||
|
success_cb = function(e){console.log("Success: ", e);};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error_cb) {
|
||||||
|
error_cb = function(e){console.log("Error: ", e);};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try making a WebSocket call.
|
||||||
|
var socket = this.options.getSocket(this.wsOnMessage);
|
||||||
|
if (socket !== null) {
|
||||||
|
this._wsCall(socket, request, success_cb, error_cb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No WebSocket, and no HTTP backend? This won't work.
|
||||||
|
if (this.options.ajaxUrl === null) {
|
||||||
|
throw "$.JsonRpcClient.call used with no websocket and no http endpoint.";
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type : 'POST',
|
||||||
|
url : this.options.ajaxUrl,
|
||||||
|
data : $.toJSON(request),
|
||||||
|
dataType : 'json',
|
||||||
|
cache : false,
|
||||||
|
|
||||||
|
success : function(data) {
|
||||||
|
if ('error' in data) error_cb(data.error, this);
|
||||||
|
success_cb(data.result, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
// JSON-RPC Server could return non-200 on error
|
||||||
|
error : function(jqXHR, textStatus, errorThrown) {
|
||||||
|
try {
|
||||||
|
var response = $.parseJSON(jqXHR.responseText);
|
||||||
|
if ('console' in window) console.log(response);
|
||||||
|
error_cb(response.error, this);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
// Perhaps the responseText wasn't really a jsonrpc-error.
|
||||||
|
error_cb({ error: jqXHR.responseText }, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify sends a command to the server that won't need a response. In http, there is probably
|
||||||
|
* an empty response - that will be dropped, but in ws there should be no response at all.
|
||||||
|
*
|
||||||
|
* This is very similar to call, but has no id and no handling of callbacks.
|
||||||
|
*
|
||||||
|
* @fn notify
|
||||||
|
* @memberof $.JsonRpcClient
|
||||||
|
*
|
||||||
|
* @param method The method to run on JSON-RPC server.
|
||||||
|
* @param params The params; an array or object.
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient.prototype.notify = function(method, params) {
|
||||||
|
// Construct the JSON-RPC 2.0 request.
|
||||||
|
|
||||||
|
if (this.options.sessid) {
|
||||||
|
params.sessid = this.options.sessid;
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: method,
|
||||||
|
params: params
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try making a WebSocket call.
|
||||||
|
var socket = this.options.getSocket(this.wsOnMessage);
|
||||||
|
if (socket !== null) {
|
||||||
|
this._wsCall(socket, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No WebSocket, and no HTTP backend? This won't work.
|
||||||
|
if (this.options.ajaxUrl === null) {
|
||||||
|
throw "$.JsonRpcClient.notify used with no websocket and no http endpoint.";
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type : 'POST',
|
||||||
|
url : this.options.ajaxUrl,
|
||||||
|
data : $.toJSON(request),
|
||||||
|
dataType : 'json',
|
||||||
|
cache : false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a batch-call by using a callback.
|
||||||
|
*
|
||||||
|
* The callback will get an object "batch" as only argument. On batch, you can call the methods
|
||||||
|
* "call" and "notify" just as if it was a normal $.JsonRpcClient object, and all calls will be
|
||||||
|
* sent as a batch call then the callback is done.
|
||||||
|
*
|
||||||
|
* @fn batch
|
||||||
|
* @memberof $.JsonRpcClient
|
||||||
|
*
|
||||||
|
* @param callback The main function which will get a batch handler to run call and notify on.
|
||||||
|
* @param all_done_cb A callback function to call after all results have been handled.
|
||||||
|
* @param error_cb A callback function to call if there is an error from the server.
|
||||||
|
* Note, that batch calls should always get an overall success, and the
|
||||||
|
* only error
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) {
|
||||||
|
var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb);
|
||||||
|
callback(batch);
|
||||||
|
batch._execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default getSocket handler.
|
||||||
|
*
|
||||||
|
* @param onmessage_cb The callback to be bound to onmessage events on the socket.
|
||||||
|
*
|
||||||
|
* @fn _getSocket
|
||||||
|
* @memberof $.JsonRpcClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
$.JsonRpcClient.prototype.socketReady = function() {
|
||||||
|
if (this._ws_socket === null || this._ws_socket.readyState > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.JsonRpcClient.prototype.closeSocket = function() {
|
||||||
|
if (self.socketReady()) {
|
||||||
|
this._ws_socket.onclose = function (w) {console.log("Closing Socket")}
|
||||||
|
this._ws_socket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.JsonRpcClient.prototype.loginData = function(params) {
|
||||||
|
self.options.login = params.login;
|
||||||
|
self.options.passwd = params.passwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (!self.socketReady()) {
|
||||||
|
self.authing = false;
|
||||||
|
// No socket, or dying socket, let's get a new one.
|
||||||
|
this._ws_socket = new WebSocket(this.options.socketUrl);
|
||||||
|
|
||||||
|
if (this._ws_socket) {
|
||||||
|
// Set up onmessage handler.
|
||||||
|
this._ws_socket.onmessage = onmessage_cb;
|
||||||
|
this._ws_socket.onclose = function (w) {
|
||||||
|
if (!self.ws_sleep) {
|
||||||
|
self.ws_sleep = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ws_cnt = 0;
|
||||||
|
|
||||||
|
if (self.options.onWSClose) {
|
||||||
|
self.options.onWSClose(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error("Websocket Lost sleep: " + self.ws_sleep + "sec");
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
console.log("Attempting Reconnection....");
|
||||||
|
self.connectSocket(onmessage_cb);
|
||||||
|
}, self.ws_sleep * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
if (++self.ws_cnt >= 150) {
|
||||||
|
self.ws_sleep = 30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up sending of message for when the socket is open.
|
||||||
|
this._ws_socket.onopen = function() {
|
||||||
|
this.ws_sleep = 2;
|
||||||
|
this.ws_cnt = 0;
|
||||||
|
if (self.options.onWSConnect) {
|
||||||
|
self.options.onWSConnect(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
var req;
|
||||||
|
// Send the requests.
|
||||||
|
while (req = $.JsonRpcClient.q.pop()) {
|
||||||
|
self._ws_socket.send(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._ws_socket ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.JsonRpcClient.prototype._getSocket = function(onmessage_cb) {
|
||||||
|
// If there is no ws url set, we don't have a socket.
|
||||||
|
// Likewise, if there is no window.WebSocket.
|
||||||
|
if (this.options.socketUrl === null || !("WebSocket" in window)) return null;
|
||||||
|
|
||||||
|
this.connectSocket(onmessage_cb);
|
||||||
|
|
||||||
|
return this._ws_socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue to save messages delivered when websocket is not ready
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient.q = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal handler to dispatch a JRON-RPC request through a websocket.
|
||||||
|
*
|
||||||
|
* @fn _wsCall
|
||||||
|
* @memberof $.JsonRpcClient
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) {
|
||||||
|
var request_json = $.toJSON(request);
|
||||||
|
|
||||||
|
if (socket.readyState < 1) {
|
||||||
|
// The websocket is not open yet; we have to set sending of the message in onopen.
|
||||||
|
self = this; // In closure below, this is set to the WebSocket. Use self instead.
|
||||||
|
|
||||||
|
$.JsonRpcClient.q.push(request_json);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We have a socket and it should be ready to send on.
|
||||||
|
socket.send(request_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup callbacks. If there is an id, this is a call and not a notify.
|
||||||
|
if ('id' in request && typeof success_cb !== 'undefined') {
|
||||||
|
this._ws_callbacks[request.id] = { request: request_json, request_obj: request, success_cb: success_cb, error_cb: error_cb };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal handler for the websocket messages. It determines if the message is a JSON-RPC
|
||||||
|
* response, and if so, tries to couple it with a given callback. Otherwise, it falls back to
|
||||||
|
* given external onmessage-handler, if any.
|
||||||
|
*
|
||||||
|
* @param event The websocket onmessage-event.
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient.prototype._wsOnMessage = function(event) {
|
||||||
|
// Check if this could be a JSON RPC message.
|
||||||
|
var response;
|
||||||
|
try {
|
||||||
|
response = $.parseJSON(event.data);
|
||||||
|
|
||||||
|
/// @todo Make using the jsonrcp 2.0 check optional, to use this on JSON-RPC 1 backends.
|
||||||
|
|
||||||
|
if (typeof response === 'object'
|
||||||
|
&& 'jsonrpc' in response
|
||||||
|
&& response.jsonrpc === '2.0') {
|
||||||
|
|
||||||
|
/// @todo Handle bad response (without id).
|
||||||
|
|
||||||
|
// If this is an object with result, it is a response.
|
||||||
|
if ('result' in response && this._ws_callbacks[response.id]) {
|
||||||
|
// Get the success callback.
|
||||||
|
var success_cb = this._ws_callbacks[response.id].success_cb;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// set the sessid if present
|
||||||
|
if ('sessid' in response.result && !this.options.sessid || (this.options.sessid != response.result.sessid)) {
|
||||||
|
this.options.sessid = response.result.sessid;
|
||||||
|
if (this.options.sessid) {
|
||||||
|
console.log("setting session UUID to: " + this.options.sessid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// Delete the callback from the storage.
|
||||||
|
delete this._ws_callbacks[response.id];
|
||||||
|
|
||||||
|
// Run callback with result as parameter.
|
||||||
|
success_cb(response.result, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is an object with error, it is an error response.
|
||||||
|
else if ('error' in response && this._ws_callbacks[response.id]) {
|
||||||
|
|
||||||
|
// Get the error callback.
|
||||||
|
var error_cb = this._ws_callbacks[response.id].error_cb;
|
||||||
|
var orig_req = this._ws_callbacks[response.id].request;
|
||||||
|
|
||||||
|
// if this is an auth request, send the credentials and resend the failed request
|
||||||
|
if (!self.authing && response.error.code == -32000 && self.options.login && self.options.passwd) {
|
||||||
|
self.authing = true;
|
||||||
|
|
||||||
|
this.call("login", { login: self.options.login, passwd: self.options.passwd},
|
||||||
|
this._ws_callbacks[response.id].request_obj.method == "login"
|
||||||
|
?
|
||||||
|
function(e) {
|
||||||
|
self.authing = false;
|
||||||
|
console.log("logged in");
|
||||||
|
delete self._ws_callbacks[response.id];
|
||||||
|
|
||||||
|
if (self.options.onWSLogin) {
|
||||||
|
self.options.onWSLogin(true, self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:
|
||||||
|
|
||||||
|
function(e) {
|
||||||
|
self.authing = false;
|
||||||
|
console.log("logged in, resending request id: " + response.id);
|
||||||
|
var socket = self.options.getSocket(self.wsOnMessage);
|
||||||
|
if (socket !== null) {
|
||||||
|
socket.send(orig_req);
|
||||||
|
}
|
||||||
|
if (self.options.onWSLogin) {
|
||||||
|
self.options.onWSLogin(true, self);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
function(e) {
|
||||||
|
console.log("error logging in, request id:", response.id);
|
||||||
|
delete self._ws_callbacks[response.id];
|
||||||
|
error_cb(response.error, this);
|
||||||
|
if (self.options.onWSLogin) {
|
||||||
|
self.options.onWSLogin(false, self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the callback from the storage.
|
||||||
|
delete this._ws_callbacks[response.id];
|
||||||
|
|
||||||
|
// Run callback with the error object as parameter.
|
||||||
|
error_cb(response.error, this);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
// Probably an error while parsing a non json-string as json. All real JSON-RPC cases are
|
||||||
|
// handled above, and the fallback method is called below.
|
||||||
|
console.log("ERROR: "+ err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is not a JSON-RPC response. Call the fallback message handler, if given.
|
||||||
|
if (typeof this.options.onmessage === 'function') {
|
||||||
|
event.eventData = response;
|
||||||
|
if (!event.eventData) {
|
||||||
|
event.eventData = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var reply = this.options.onmessage(event);
|
||||||
|
|
||||||
|
if (reply && typeof reply === "object" && event.eventData.id) {
|
||||||
|
var msg = {
|
||||||
|
jsonrpc: "2.0",
|
||||||
|
id: event.eventData.id,
|
||||||
|
result: reply
|
||||||
|
};
|
||||||
|
|
||||||
|
var socket = self.options.getSocket(self.wsOnMessage);
|
||||||
|
if (socket !== null) {
|
||||||
|
socket.send($.toJSON(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************************************
|
||||||
|
* Batch object with methods
|
||||||
|
************************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handling object for batch calls.
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) {
|
||||||
|
// Array of objects to hold the call and notify requests. Each objects will have the request
|
||||||
|
// object, and unless it is a notify, success_cb and error_cb.
|
||||||
|
this._requests = [];
|
||||||
|
|
||||||
|
this.jsonrpcclient = jsonrpcclient;
|
||||||
|
this.all_done_cb = all_done_cb;
|
||||||
|
this.error_cb = typeof error_cb === 'function' ? error_cb : function() {};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @sa $.JsonRpcClient.prototype.call
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) {
|
||||||
|
|
||||||
|
if (!params) {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.sessid) {
|
||||||
|
params.sessid = this.options.sessid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success_cb) {
|
||||||
|
success_cb = function(e){console.log("Success: ", e);};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error_cb) {
|
||||||
|
error_cb = function(e){console.log("Error: ", e);};
|
||||||
|
}
|
||||||
|
|
||||||
|
this._requests.push({
|
||||||
|
request : {
|
||||||
|
jsonrpc : '2.0',
|
||||||
|
method : method,
|
||||||
|
params : params,
|
||||||
|
id : this.jsonrpcclient._current_id++ // Use the client's id series.
|
||||||
|
},
|
||||||
|
success_cb : success_cb,
|
||||||
|
error_cb : error_cb
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @sa $.JsonRpcClient.prototype.notify
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient._batchObject.prototype.notify = function(method, params) {
|
||||||
|
if (this.options.sessid) {
|
||||||
|
params.sessid = this.options.sessid;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._requests.push({
|
||||||
|
request : {
|
||||||
|
jsonrpc : '2.0',
|
||||||
|
method : method,
|
||||||
|
params : params
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the batched up calls.
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient._batchObject.prototype._execute = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (this._requests.length === 0) return; // All done :P
|
||||||
|
|
||||||
|
// Collect all request data and sort handlers by request id.
|
||||||
|
var batch_request = [];
|
||||||
|
var handlers = {};
|
||||||
|
|
||||||
|
// If we have a WebSocket, just send the requests individually like normal calls.
|
||||||
|
var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage);
|
||||||
|
if (socket !== null) {
|
||||||
|
for (var i = 0; i < this._requests.length; i++) {
|
||||||
|
var call = this._requests[i];
|
||||||
|
var success_cb = ('success_cb' in call) ? call.success_cb : undefined;
|
||||||
|
var error_cb = ('error_cb' in call) ? call.error_cb : undefined;
|
||||||
|
self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb);
|
||||||
|
}
|
||||||
|
if (typeof all_done_cb === 'function') all_done_cb(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < this._requests.length; i++) {
|
||||||
|
var call = this._requests[i];
|
||||||
|
batch_request.push(call.request);
|
||||||
|
|
||||||
|
// If the request has an id, it should handle returns (otherwise it's a notify).
|
||||||
|
if ('id' in call.request) {
|
||||||
|
handlers[call.request.id] = {
|
||||||
|
success_cb : call.success_cb,
|
||||||
|
error_cb : call.error_cb
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); };
|
||||||
|
|
||||||
|
// No WebSocket, and no HTTP backend? This won't work.
|
||||||
|
if (self.jsonrpcclient.options.ajaxUrl === null) {
|
||||||
|
throw "$.JsonRpcClient.batch used with no websocket and no http endpoint.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request
|
||||||
|
$.ajax({
|
||||||
|
url : self.jsonrpcclient.options.ajaxUrl,
|
||||||
|
data : $.toJSON(batch_request),
|
||||||
|
dataType : 'json',
|
||||||
|
cache : false,
|
||||||
|
type : 'POST',
|
||||||
|
|
||||||
|
// Batch-requests should always return 200
|
||||||
|
error : function(jqXHR, textStatus, errorThrown) {
|
||||||
|
self.error_cb(jqXHR, textStatus, errorThrown);
|
||||||
|
},
|
||||||
|
success : success_cb
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal helper to match the result array from a batch call to their respective callbacks.
|
||||||
|
*
|
||||||
|
* @fn _batchCb
|
||||||
|
* @memberof $.JsonRpcClient
|
||||||
|
*/
|
||||||
|
$.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) {
|
||||||
|
for (var i = 0; i < result.length; i++) {
|
||||||
|
var response = result[i];
|
||||||
|
|
||||||
|
// Handle error
|
||||||
|
if ('error' in response) {
|
||||||
|
if (response.id === null || !(response.id in handlers)) {
|
||||||
|
// An error on a notify? Just log it to the console.
|
||||||
|
if ('console' in window) console.log(response);
|
||||||
|
}
|
||||||
|
else handlers[response.id].error_cb(response.error, this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Here we should always have a correct id and no error.
|
||||||
|
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);
|
1932
html5/verto/js/src/jquery.verto.js
Normal file
1
libs/.gitignore
vendored
@ -835,3 +835,4 @@ unimrcp/build/compile
|
|||||||
/curl-*/
|
/curl-*/
|
||||||
/sqlite-*.zip
|
/sqlite-*.zip
|
||||||
/sqlite-*/
|
/sqlite-*/
|
||||||
|
/ldns/
|
||||||
|
@ -59,6 +59,7 @@ typedef struct {
|
|||||||
const char *console_fnkeys[12];
|
const char *console_fnkeys[12];
|
||||||
char loglevel[128];
|
char loglevel[128];
|
||||||
int log_uuid;
|
int log_uuid;
|
||||||
|
int log_uuid_length;
|
||||||
int quiet;
|
int quiet;
|
||||||
int batch_mode;
|
int batch_mode;
|
||||||
char prompt_color[12];
|
char prompt_color[12];
|
||||||
@ -66,6 +67,7 @@ typedef struct {
|
|||||||
char output_text_color[12];
|
char output_text_color[12];
|
||||||
} cli_profile_t;
|
} cli_profile_t;
|
||||||
|
|
||||||
|
static const int log_uuid_short_length = 8;
|
||||||
static int is_color = 1;
|
static int is_color = 1;
|
||||||
static int warn_stop = 0;
|
static int warn_stop = 0;
|
||||||
static int connected = 0;
|
static int connected = 0;
|
||||||
@ -604,6 +606,7 @@ static const char *usage_str =
|
|||||||
" -x, --execute=command Execute Command and Exit\n"
|
" -x, --execute=command Execute Command and Exit\n"
|
||||||
" -l, --loglevel=command Log Level\n"
|
" -l, --loglevel=command Log Level\n"
|
||||||
" -U, --log-uuid Include UUID in log output\n"
|
" -U, --log-uuid Include UUID in log output\n"
|
||||||
|
" -S, --log-uuid-short Include shortened UUID in log output\n"
|
||||||
" -q, --quiet Disable logging\n"
|
" -q, --quiet Disable logging\n"
|
||||||
" -r, --retry Retry connection on failure\n"
|
" -r, --retry Retry connection on failure\n"
|
||||||
" -R, --reconnect Reconnect if disconnected\n"
|
" -R, --reconnect Reconnect if disconnected\n"
|
||||||
@ -742,7 +745,16 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
|
|||||||
printf("%s", colors[level]);
|
printf("%s", colors[level]);
|
||||||
}
|
}
|
||||||
if (global_profile->log_uuid && !esl_strlen_zero(userdata)) {
|
if (global_profile->log_uuid && !esl_strlen_zero(userdata)) {
|
||||||
printf("%s ", userdata);
|
if (global_profile->log_uuid_length) {
|
||||||
|
int len = strlen(userdata);
|
||||||
|
int i = (global_profile->log_uuid_length < len) ? global_profile->log_uuid_length : len;
|
||||||
|
if (fwrite(userdata, sizeof(char), i, stdout) < i) {
|
||||||
|
// don't care
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
} else {
|
||||||
|
printf("%s ", userdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (strcmp("\n",handle->last_event->body)) {
|
if (strcmp("\n",handle->last_event->body)) {
|
||||||
char *c = handle->last_event->body;
|
char *c = handle->last_event->body;
|
||||||
@ -1235,6 +1247,14 @@ static void read_config(const char *dft_cfile, const char *cfile) {
|
|||||||
esl_set_string(profiles[pcount-1].loglevel, val);
|
esl_set_string(profiles[pcount-1].loglevel, val);
|
||||||
} else if(!strcasecmp(var, "log-uuid")) {
|
} else if(!strcasecmp(var, "log-uuid")) {
|
||||||
profiles[pcount-1].log_uuid = esl_true(val);
|
profiles[pcount-1].log_uuid = esl_true(val);
|
||||||
|
} else if(!strcasecmp(var, "log-uuid-short")) {
|
||||||
|
profiles[pcount-1].log_uuid = esl_true(val);
|
||||||
|
profiles[pcount-1].log_uuid_length = (esl_true(val) ? log_uuid_short_length : 0);
|
||||||
|
} else if(!strcasecmp(var, "log-uuid-length")) {
|
||||||
|
int i;
|
||||||
|
if ((i = atoi(val)) > -1) {
|
||||||
|
profiles[pcount-1].log_uuid_length = i;
|
||||||
|
}
|
||||||
} else if(!strcasecmp(var, "quiet")) {
|
} else if(!strcasecmp(var, "quiet")) {
|
||||||
profiles[pcount-1].quiet = esl_true(val);
|
profiles[pcount-1].quiet = esl_true(val);
|
||||||
} else if(!strcasecmp(var, "prompt-color")) {
|
} else if(!strcasecmp(var, "prompt-color")) {
|
||||||
@ -1301,6 +1321,7 @@ int main(int argc, char *argv[])
|
|||||||
{"execute", 1, 0, 'x'},
|
{"execute", 1, 0, 'x'},
|
||||||
{"loglevel", 1, 0, 'l'},
|
{"loglevel", 1, 0, 'l'},
|
||||||
{"log-uuid", 0, 0, 'U'},
|
{"log-uuid", 0, 0, 'U'},
|
||||||
|
{"log-uuid-short", 0, 0, 'S'},
|
||||||
{"quiet", 0, 0, 'q'},
|
{"quiet", 0, 0, 'q'},
|
||||||
{"batchmode", 0, 0, 'b'},
|
{"batchmode", 0, 0, 'b'},
|
||||||
{"retry", 0, 0, 'r'},
|
{"retry", 0, 0, 'r'},
|
||||||
@ -1324,6 +1345,7 @@ int main(int argc, char *argv[])
|
|||||||
char argv_command[1024] = "";
|
char argv_command[1024] = "";
|
||||||
char argv_loglevel[128] = "";
|
char argv_loglevel[128] = "";
|
||||||
int argv_log_uuid = 0;
|
int argv_log_uuid = 0;
|
||||||
|
int argv_log_uuid_short = 0;
|
||||||
int argv_quiet = 0;
|
int argv_quiet = 0;
|
||||||
int argv_batch = 0;
|
int argv_batch = 0;
|
||||||
int loops = 2, reconnect = 0;
|
int loops = 2, reconnect = 0;
|
||||||
@ -1373,7 +1395,7 @@ int main(int argc, char *argv[])
|
|||||||
esl_global_set_default_logger(6); /* default debug level to 6 (info) */
|
esl_global_set_default_logger(6); /* default debug level to 6 (info) */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
opt = getopt_long(argc, argv, "H:P:S:u:p:d:x:l:Ut:T:qrRhib?n", options, &option_index);
|
opt = getopt_long(argc, argv, "H:P:u:p:d:x:l:USt:T:qrRhib?n", options, &option_index);
|
||||||
if (opt == -1) break;
|
if (opt == -1) break;
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'H':
|
case 'H':
|
||||||
@ -1419,6 +1441,9 @@ int main(int argc, char *argv[])
|
|||||||
case 'U':
|
case 'U':
|
||||||
argv_log_uuid = 1;
|
argv_log_uuid = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'S':
|
||||||
|
argv_log_uuid_short = 1;
|
||||||
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
argv_quiet = 1;
|
argv_quiet = 1;
|
||||||
break;
|
break;
|
||||||
@ -1487,6 +1512,10 @@ int main(int argc, char *argv[])
|
|||||||
if (argv_log_uuid) {
|
if (argv_log_uuid) {
|
||||||
profile->log_uuid = 1;
|
profile->log_uuid = 1;
|
||||||
}
|
}
|
||||||
|
if (argv_log_uuid_short) {
|
||||||
|
profile->log_uuid = 1;
|
||||||
|
profile->log_uuid_length = log_uuid_short_length;
|
||||||
|
}
|
||||||
esl_log(ESL_LOG_DEBUG, "Using profile %s [%s]\n", profile->name, profile->host);
|
esl_log(ESL_LOG_DEBUG, "Using profile %s [%s]\n", profile->name, profile->host);
|
||||||
esl_set_string(prompt_color, profile->prompt_color);
|
esl_set_string(prompt_color, profile->prompt_color);
|
||||||
esl_set_string(input_text_color, profile->input_text_color);
|
esl_set_string(input_text_color, profile->input_text_color);
|
||||||
|
@ -12,9 +12,9 @@ perlmod: ESL.la
|
|||||||
install-data-local: perlmod-install
|
install-data-local: perlmod-install
|
||||||
|
|
||||||
perlmod-install: install-perlLTLIBRARIES
|
perlmod-install: install-perlLTLIBRARIES
|
||||||
install -m 755 ESL.pm $(PERL_SITEDIR)
|
install -d -m 755 ESL $(DESTDIR)$(PERL_SITEDIR)/ESL
|
||||||
install -d -m 755 ESL $(PERL_SITEDIR)/ESL
|
install -m 755 ESL.pm $(DESTDIR)$(PERL_SITEDIR)
|
||||||
install -m 755 ESL/* $(PERL_SITEDIR)/ESL
|
install -m 755 ESL/* $(DESTDIR)$(PERL_SITEDIR)/ESL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
esl_wrap.cpp:
|
esl_wrap.cpp:
|
||||||
|
@ -81,28 +81,30 @@ extern "C" {
|
|||||||
\param expr a string expression
|
\param expr a string expression
|
||||||
\return true or false
|
\return true or false
|
||||||
*/
|
*/
|
||||||
#define esl_true(expr)\
|
static __inline__ int esl_true(const char *expr) {
|
||||||
(expr && ( !strcasecmp(expr, "yes") ||\
|
return (expr && (!strcasecmp(expr, "yes")
|
||||||
!strcasecmp(expr, "on") ||\
|
|| !strcasecmp(expr, "on")
|
||||||
!strcasecmp(expr, "true") ||\
|
|| !strcasecmp(expr, "true")
|
||||||
!strcasecmp(expr, "enabled") ||\
|
|| !strcasecmp(expr, "enabled")
|
||||||
!strcasecmp(expr, "active") ||\
|
|| !strcasecmp(expr, "active")
|
||||||
!strcasecmp(expr, "allow") ||\
|
|| !strcasecmp(expr, "allow")
|
||||||
atoi(expr))) ? 1 : 0
|
|| atoi(expr)));
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Evaluate the falsefullness of a string expression
|
\brief Evaluate the falsefullness of a string expression
|
||||||
\param expr a string expression
|
\param expr a string expression
|
||||||
\return true or false
|
\return true or false
|
||||||
*/
|
*/
|
||||||
#define esl_false(expr)\
|
static __inline__ int esl_false(const char *expr) {
|
||||||
(expr && ( !strcasecmp(expr, "no") ||\
|
return (expr && (!strcasecmp(expr, "no")
|
||||||
!strcasecmp(expr, "off") ||\
|
|| !strcasecmp(expr, "off")
|
||||||
!strcasecmp(expr, "false") ||\
|
|| !strcasecmp(expr, "false")
|
||||||
!strcasecmp(expr, "disabled") ||\
|
|| !strcasecmp(expr, "disabled")
|
||||||
!strcasecmp(expr, "inactive") ||\
|
|| !strcasecmp(expr, "inactive")
|
||||||
!strcasecmp(expr, "disallow") ||\
|
|| !strcasecmp(expr, "disallow")
|
||||||
!atoi(expr))) ? 1 : 0
|
|| !atoi(expr)));
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct esl_config esl_config_t;
|
typedef struct esl_config esl_config_t;
|
||||||
|
|
||||||
|
@ -5538,6 +5538,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown)
|
|||||||
ftdm_conf_node_destroy(val);
|
ftdm_conf_node_destroy(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_core_hash_destroy(&globals.ss7_configs);
|
||||||
ftdm_global_destroy();
|
ftdm_global_destroy();
|
||||||
|
|
||||||
// this breaks pika but they are MIA so *shrug*
|
// this breaks pika but they are MIA so *shrug*
|
||||||
|
@ -59,6 +59,8 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
|
|||||||
#define FTDM_HALF_DTMF_PAUSE 500
|
#define FTDM_HALF_DTMF_PAUSE 500
|
||||||
#define FTDM_FULL_DTMF_PAUSE 1000
|
#define FTDM_FULL_DTMF_PAUSE 1000
|
||||||
|
|
||||||
|
#define FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan) (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_DTMF_DETECTION))
|
||||||
|
|
||||||
ftdm_time_t time_last_throttle_log = 0;
|
ftdm_time_t time_last_throttle_log = 0;
|
||||||
ftdm_time_t time_current_throttle_log = 0;
|
ftdm_time_t time_current_throttle_log = 0;
|
||||||
|
|
||||||
@ -105,6 +107,7 @@ static val_str_t channel_flag_strs[] = {
|
|||||||
{ "blocking", FTDM_CHANNEL_BLOCKING},
|
{ "blocking", FTDM_CHANNEL_BLOCKING},
|
||||||
{ "media", FTDM_CHANNEL_DIGITAL_MEDIA},
|
{ "media", FTDM_CHANNEL_DIGITAL_MEDIA},
|
||||||
{ "native-sigbridge", FTDM_CHANNEL_NATIVE_SIGBRIDGE},
|
{ "native-sigbridge", FTDM_CHANNEL_NATIVE_SIGBRIDGE},
|
||||||
|
{ "sig-dtmf-detection", FTDM_CHANNEL_SIG_DTMF_DETECTION},
|
||||||
{ "invalid", FTDM_CHANNEL_MAX_FLAG},
|
{ "invalid", FTDM_CHANNEL_MAX_FLAG},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -690,15 +693,11 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
|
|||||||
ftdm_status_t status = FTDM_SUCCESS;
|
ftdm_status_t status = FTDM_SUCCESS;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
|
||||||
|
/* The signaling must be already stopped (this is just a sanity check, should never happen) */
|
||||||
|
ftdm_assert_return(!ftdm_test_flag(span, FTDM_SPAN_STARTED), FTDM_FAIL, "Signaling for span %s has not been stopped, refusing to destroy span\n");
|
||||||
|
|
||||||
ftdm_mutex_lock(span->mutex);
|
ftdm_mutex_lock(span->mutex);
|
||||||
|
|
||||||
/* stop the signaling */
|
|
||||||
|
|
||||||
/* This is a forced stopped */
|
|
||||||
ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE);
|
|
||||||
|
|
||||||
ftdm_span_stop(span);
|
|
||||||
|
|
||||||
/* destroy the channels */
|
/* destroy the channels */
|
||||||
ftdm_clear_flag(span, FTDM_SPAN_CONFIGURED);
|
ftdm_clear_flag(span, FTDM_SPAN_CONFIGURED);
|
||||||
for(j = 1; j <= span->chan_count && span->channels[j]; j++) {
|
for(j = 1; j <= span->chan_count && span->channels[j]; j++) {
|
||||||
@ -3374,7 +3373,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||||||
{
|
{
|
||||||
/* if they don't have thier own, use ours */
|
/* if they don't have thier own, use ours */
|
||||||
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||||
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
|
if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan)) {
|
||||||
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
|
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
|
||||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
|
||||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
|
||||||
@ -3387,9 +3386,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||||||
case FTDM_COMMAND_DISABLE_DTMF_DETECT:
|
case FTDM_COMMAND_DISABLE_DTMF_DETECT:
|
||||||
{
|
{
|
||||||
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||||
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
|
if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan)) {
|
||||||
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
|
teletone_dtmf_detect_init (&ftdmchan->dtmf_detect, ftdmchan->rate);
|
||||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
|
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
|
||||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
|
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
|
||||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n");
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled software DTMF detector\n");
|
||||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||||
@ -3465,8 +3464,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||||||
break;
|
break;
|
||||||
case FTDM_COMMAND_SEND_DTMF:
|
case FTDM_COMMAND_SEND_DTMF:
|
||||||
{
|
{
|
||||||
if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) {
|
char *digits = FTDM_COMMAND_OBJ_CHAR_P;
|
||||||
char *digits = FTDM_COMMAND_OBJ_CHAR_P;
|
if (ftdmchan->span->sig_send_dtmf) {
|
||||||
|
status = ftdmchan->span->sig_send_dtmf(ftdmchan, digits);
|
||||||
|
GOTO_STATUS(done, status);
|
||||||
|
} else if (!ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_GENERATE)) {
|
||||||
|
|
||||||
if ((status = ftdmchan_activate_dtmf_buffer(ftdmchan)) != FTDM_SUCCESS) {
|
if ((status = ftdmchan_activate_dtmf_buffer(ftdmchan)) != FTDM_SUCCESS) {
|
||||||
GOTO_STATUS(done, status);
|
GOTO_STATUS(done, status);
|
||||||
@ -3777,7 +3779,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
|
|||||||
|
|
||||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s (debug = %d)\n", dtmf, ftdmchan->dtmfdbg.enabled);
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s (debug = %d)\n", dtmf, ftdmchan->dtmfdbg.enabled);
|
||||||
|
|
||||||
if (ftdmchan->span->sig_dtmf && (ftdmchan->span->sig_dtmf(ftdmchan, dtmf) == FTDM_BREAK)) {
|
if (ftdmchan->span->sig_queue_dtmf && (ftdmchan->span->sig_queue_dtmf(ftdmchan, dtmf) == FTDM_BREAK)) {
|
||||||
/* Signalling module wants to absorb this DTMF event */
|
/* Signalling module wants to absorb this DTMF event */
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -4216,7 +4218,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT) && !ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_DTMF_DETECT)) {
|
if (FTDM_CHANNEL_SW_DTMF_ALLOWED(ftdmchan) && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT)) {
|
||||||
teletone_hit_type_t hit;
|
teletone_hit_type_t hit;
|
||||||
char digit_char;
|
char digit_char;
|
||||||
uint32_t dur;
|
uint32_t dur;
|
||||||
@ -6040,6 +6042,17 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ftdm_group_destroy(ftdm_group_t **group)
|
||||||
|
{
|
||||||
|
ftdm_group_t *grp = NULL;
|
||||||
|
ftdm_assert(group != NULL, "Group must not be null\n");
|
||||||
|
grp = *group;
|
||||||
|
ftdm_mutex_destroy(&grp->mutex);
|
||||||
|
ftdm_safe_free(grp->name);
|
||||||
|
ftdm_safe_free(grp);
|
||||||
|
*group = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||||
{
|
{
|
||||||
if (!span->signal_cb) {
|
if (!span->signal_cb) {
|
||||||
@ -6376,10 +6389,37 @@ FT_DECLARE(uint32_t) ftdm_running(void)
|
|||||||
return globals.running;
|
return globals.running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void destroy_span(ftdm_span_t *span)
|
||||||
|
{
|
||||||
|
if (ftdm_test_flag(span, FTDM_SPAN_CONFIGURED)) {
|
||||||
|
ftdm_span_destroy(span);
|
||||||
|
}
|
||||||
|
hashtable_remove(globals.span_hash, (void *)span->name);
|
||||||
|
ftdm_safe_free(span->dtmf_hangup);
|
||||||
|
ftdm_safe_free(span->type);
|
||||||
|
ftdm_safe_free(span->name);
|
||||||
|
ftdm_safe_free(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void force_stop_span(ftdm_span_t *span)
|
||||||
|
{
|
||||||
|
/* This is a forced stop */
|
||||||
|
ftdm_clear_flag(span, FTDM_SPAN_NON_STOPPABLE);
|
||||||
|
ftdm_span_stop(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void span_for_each(void (*func)(ftdm_span_t *span))
|
||||||
|
{
|
||||||
|
ftdm_span_t *sp = NULL, *next = NULL;
|
||||||
|
for (sp = globals.spans; sp; sp = next) {
|
||||||
|
next = sp->next;
|
||||||
|
func(sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
||||||
{
|
{
|
||||||
ftdm_span_t *sp;
|
ftdm_group_t *grp = NULL, *next_grp = NULL;
|
||||||
|
|
||||||
time_end();
|
time_end();
|
||||||
|
|
||||||
@ -6397,45 +6437,49 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
|||||||
|
|
||||||
ftdm_span_close_all();
|
ftdm_span_close_all();
|
||||||
|
|
||||||
|
/* Stop and destroy alls pans */
|
||||||
ftdm_mutex_lock(globals.span_mutex);
|
ftdm_mutex_lock(globals.span_mutex);
|
||||||
for (sp = globals.spans; sp;) {
|
|
||||||
ftdm_span_t *cur_span = sp;
|
|
||||||
sp = sp->next;
|
|
||||||
|
|
||||||
if (cur_span) {
|
span_for_each(force_stop_span);
|
||||||
if (ftdm_test_flag(cur_span, FTDM_SPAN_CONFIGURED)) {
|
span_for_each(destroy_span);
|
||||||
ftdm_span_destroy(cur_span);
|
|
||||||
}
|
|
||||||
|
|
||||||
hashtable_remove(globals.span_hash, (void *)cur_span->name);
|
|
||||||
ftdm_safe_free(cur_span->dtmf_hangup);
|
|
||||||
ftdm_safe_free(cur_span->type);
|
|
||||||
ftdm_safe_free(cur_span->name);
|
|
||||||
ftdm_safe_free(cur_span);
|
|
||||||
cur_span = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
globals.spans = NULL;
|
globals.spans = NULL;
|
||||||
|
|
||||||
ftdm_mutex_unlock(globals.span_mutex);
|
ftdm_mutex_unlock(globals.span_mutex);
|
||||||
|
|
||||||
/* destroy signaling and io modules */
|
/* destroy signaling and io modules */
|
||||||
ftdm_unload_modules();
|
ftdm_unload_modules();
|
||||||
|
|
||||||
ftdm_global_set_logger( NULL );
|
/* Destroy hunting groups */
|
||||||
|
ftdm_mutex_lock(globals.group_mutex);
|
||||||
|
grp = globals.groups;
|
||||||
|
while (grp) {
|
||||||
|
next_grp = grp->next;
|
||||||
|
ftdm_group_destroy(&grp);
|
||||||
|
grp = next_grp;
|
||||||
|
}
|
||||||
|
ftdm_mutex_unlock(globals.group_mutex);
|
||||||
|
|
||||||
/* finally destroy the globals */
|
/* finally destroy the globals */
|
||||||
ftdm_mutex_lock(globals.mutex);
|
ftdm_mutex_lock(globals.mutex);
|
||||||
|
|
||||||
ftdm_sched_destroy(&globals.timingsched);
|
ftdm_sched_destroy(&globals.timingsched);
|
||||||
|
|
||||||
hashtable_destroy(globals.interface_hash);
|
hashtable_destroy(globals.interface_hash);
|
||||||
hashtable_destroy(globals.module_hash);
|
hashtable_destroy(globals.module_hash);
|
||||||
hashtable_destroy(globals.span_hash);
|
hashtable_destroy(globals.span_hash);
|
||||||
hashtable_destroy(globals.group_hash);
|
hashtable_destroy(globals.group_hash);
|
||||||
ftdm_mutex_unlock(globals.mutex);
|
|
||||||
ftdm_mutex_destroy(&globals.mutex);
|
|
||||||
ftdm_mutex_destroy(&globals.span_mutex);
|
ftdm_mutex_destroy(&globals.span_mutex);
|
||||||
ftdm_mutex_destroy(&globals.group_mutex);
|
ftdm_mutex_destroy(&globals.group_mutex);
|
||||||
ftdm_mutex_destroy(&globals.call_id_mutex);
|
ftdm_mutex_destroy(&globals.call_id_mutex);
|
||||||
|
|
||||||
|
ftdm_mutex_unlock(globals.mutex);
|
||||||
|
|
||||||
|
ftdm_mutex_destroy(&globals.mutex);
|
||||||
|
|
||||||
|
ftdm_sched_global_destroy();
|
||||||
|
|
||||||
|
ftdm_global_set_logger(NULL);
|
||||||
memset(&globals, 0, sizeof(globals));
|
memset(&globals, 0, sizeof(globals));
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,13 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_global_init()
|
|||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(ftdm_status_t) ftdm_sched_global_destroy()
|
||||||
|
{
|
||||||
|
ftdm_mutex_destroy(&sched_globals.mutex);
|
||||||
|
memset(&sched_globals, 0, sizeof(sched_globals));
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched)
|
FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched)
|
||||||
{
|
{
|
||||||
ftdm_status_t status = FTDM_FAIL;
|
ftdm_status_t status = FTDM_FAIL;
|
||||||
|
@ -60,18 +60,6 @@
|
|||||||
|
|
||||||
#include <private/ftdm_core.h>
|
#include <private/ftdm_core.h>
|
||||||
|
|
||||||
// Debug
|
|
||||||
#define LOG_SIG_DATA 0
|
|
||||||
#define DEBUG_STATES 0
|
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG_STATES // state debugging
|
|
||||||
#define STATE_ADVANCE_LOG_LEVEL FTDM_LOG_CRIT
|
|
||||||
#else
|
|
||||||
#define STATE_ADVANCE_LOG_LEVEL FTDM_LOG_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* MACROS */
|
/* MACROS */
|
||||||
@ -177,7 +165,6 @@ static ftdm_io_interface_t g_ftdm_gsm_interface;
|
|||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
static int read_channel(ftdm_channel_t *ftdm_chan , const void *buf, int size)
|
static int read_channel(ftdm_channel_t *ftdm_chan , const void *buf, int size)
|
||||||
{
|
{
|
||||||
|
|
||||||
ftdm_size_t outsize = size;
|
ftdm_size_t outsize = size;
|
||||||
ftdm_status_t status = ftdm_channel_read(ftdm_chan, (void *)buf, &outsize);
|
ftdm_status_t status = ftdm_channel_read(ftdm_chan, (void *)buf, &outsize);
|
||||||
if (FTDM_FAIL == status) {
|
if (FTDM_FAIL == status) {
|
||||||
@ -189,11 +176,6 @@ static int read_channel(ftdm_channel_t *ftdm_chan , const void *buf, int size)
|
|||||||
|
|
||||||
int on_wat_span_write(unsigned char span_id, void *buffer, unsigned len)
|
int on_wat_span_write(unsigned char span_id, void *buffer, unsigned len)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if LOG_SIG_DATA
|
|
||||||
fprintf(stdout, " Out Data ====================>>> %s \r\n (%d) - %d\n", (char *)buffer, len, (int) span_id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ftdm_span_t *span = NULL;
|
ftdm_span_t *span = NULL;
|
||||||
ftdm_status_t status = FTDM_FAIL;
|
ftdm_status_t status = FTDM_FAIL;
|
||||||
ftdm_gsm_span_data_t *gsm_data = NULL;
|
ftdm_gsm_span_data_t *gsm_data = NULL;
|
||||||
@ -211,15 +193,7 @@ int on_wat_span_write(unsigned char span_id, void *buffer, unsigned len)
|
|||||||
ftdm_log(FTDM_LOG_ERROR, "Failed to write %d bytes to d-channel in span %s\n", len, span->name);
|
ftdm_log(FTDM_LOG_ERROR, "Failed to write %d bytes to d-channel in span %s\n", len, span->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if LOG_SIG_DATA
|
|
||||||
// fprintf(stdout, "\r\n==================== len=%d outsize=%d \r\n", len, (int)outsize);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
fflush(stdout);
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_wat_span_status(unsigned char span_id, wat_span_status_t *status)
|
static void on_wat_span_status(unsigned char span_id, wat_span_status_t *status)
|
||||||
@ -260,9 +234,7 @@ static void on_wat_span_status(unsigned char span_id, wat_span_status_t *status)
|
|||||||
void on_wat_con_ind(unsigned char span_id, uint8_t call_id, wat_con_event_t *con_event)
|
void on_wat_con_ind(unsigned char span_id, uint8_t call_id, wat_con_event_t *con_event)
|
||||||
{
|
{
|
||||||
ftdm_span_t *span = NULL;
|
ftdm_span_t *span = NULL;
|
||||||
//ftdm_status_t ftdm_status = FTDM_FAIL;
|
|
||||||
ftdm_gsm_span_data_t *gsm_data = NULL;
|
ftdm_gsm_span_data_t *gsm_data = NULL;
|
||||||
//fprintf(stdout, "s%d: Incoming call (id:%d) Calling Number:%s Calling Name:\"%s\" type:%d plan:%d\n", span_id, call_id, con_event->calling_num.digits, con_event->calling_name, con_event->calling_num.type, con_event->calling_num.plan);
|
|
||||||
|
|
||||||
ftdm_log(FTDM_LOG_INFO, "s%d: Incoming call (id:%d) Calling Number:%s Calling Name:\"%s\" type:%d plan:%d\n", span_id, call_id, con_event->calling_num.digits, con_event->calling_name, con_event->calling_num.type, con_event->calling_num.plan);
|
ftdm_log(FTDM_LOG_INFO, "s%d: Incoming call (id:%d) Calling Number:%s Calling Name:\"%s\" type:%d plan:%d\n", span_id, call_id, con_event->calling_num.digits, con_event->calling_name, con_event->calling_num.type, con_event->calling_num.plan);
|
||||||
|
|
||||||
@ -404,8 +376,6 @@ void on_wat_rel_cfm(unsigned char span_id, uint8_t call_id)
|
|||||||
|
|
||||||
void on_wat_sms_ind(unsigned char span_id, wat_sms_event_t *sms_event)
|
void on_wat_sms_ind(unsigned char span_id, wat_sms_event_t *sms_event)
|
||||||
{
|
{
|
||||||
//printf("on_wat_sms_ind\r\n");
|
|
||||||
|
|
||||||
ftdm_span_t *span = NULL;
|
ftdm_span_t *span = NULL;
|
||||||
ftdm_channel_t *ftdmchan;
|
ftdm_channel_t *ftdmchan;
|
||||||
|
|
||||||
@ -431,7 +401,6 @@ void on_wat_sms_ind(unsigned char span_id, wat_sms_event_t *sms_event)
|
|||||||
gsm_data->dchan->caller_data.priv = (void *)&sms_data;
|
gsm_data->dchan->caller_data.priv = (void *)&sms_data;
|
||||||
ftdm_span_send_signal(span, &sigev);
|
ftdm_span_send_signal(span, &sigev);
|
||||||
}
|
}
|
||||||
// SEND_STATE_SIGNAL(FTDM_SIGEVENT_SMS);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,26 +419,35 @@ void on_wat_sms_sts(unsigned char span_id, uint8_t sms_id, wat_sms_status_t *sta
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_wat_dtmf_ind(unsigned char span_id, const char *dtmf)
|
||||||
|
{
|
||||||
|
ftdm_span_t *span = NULL;
|
||||||
|
ftdm_gsm_span_data_t *gsm_data = NULL;
|
||||||
|
|
||||||
|
if (!(span = GetSpanByID(span_id, &gsm_data))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ftdm_channel_queue_dtmf(gsm_data->bchan, dtmf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void on_wat_log(uint8_t level, char *fmt, ...)
|
void on_wat_log(uint8_t level, char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
|
||||||
int ftdm_level;
|
int ftdm_level;
|
||||||
char buff[10001];
|
char buff[4096];
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, fmt);
|
va_start(argptr, fmt);
|
||||||
|
|
||||||
switch(level) {
|
switch(level) {
|
||||||
case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break;
|
case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break;
|
||||||
case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
|
case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
|
||||||
default:
|
|
||||||
case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break;
|
case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break;
|
||||||
case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break;
|
case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break;
|
||||||
case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break;
|
case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break;
|
||||||
case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break;
|
case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break;
|
||||||
|
default: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -498,32 +476,33 @@ void on_wat_free(void *ptr)
|
|||||||
|
|
||||||
void on_wat_log_span(uint8_t span_id, uint8_t level, char *fmt, ...)
|
void on_wat_log_span(uint8_t span_id, uint8_t level, char *fmt, ...)
|
||||||
{
|
{
|
||||||
#if 0
|
ftdm_span_t *span = NULL;
|
||||||
|
ftdm_gsm_span_data_t *gsm_data = NULL;
|
||||||
int ftdm_level;
|
int ftdm_level;
|
||||||
return;
|
char buff[4096];
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
|
||||||
|
if (!(span = GetSpanByID(span_id, &gsm_data))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
va_start(argptr, fmt);
|
va_start(argptr, fmt);
|
||||||
|
|
||||||
char buff[10001];
|
|
||||||
switch(level) {
|
switch(level) {
|
||||||
case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break;
|
case WAT_LOG_CRIT: ftdm_level = FTDM_LOG_LEVEL_CRIT; break;
|
||||||
case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
|
case WAT_LOG_ERROR: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
|
||||||
default:
|
|
||||||
|
|
||||||
case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break;
|
case WAT_LOG_WARNING: ftdm_level = FTDM_LOG_LEVEL_WARNING; break;
|
||||||
case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break;
|
case WAT_LOG_INFO: ftdm_level = FTDM_LOG_LEVEL_INFO; break;
|
||||||
case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break;
|
case WAT_LOG_NOTICE: ftdm_level = FTDM_LOG_LEVEL_NOTICE; break;
|
||||||
case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break;
|
case WAT_LOG_DEBUG: ftdm_level = FTDM_LOG_LEVEL_DEBUG; break;
|
||||||
|
default: ftdm_level = FTDM_LOG_LEVEL_ERROR; break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
vsprintf(buff, fmt, argptr);
|
vsprintf(buff, fmt, argptr);
|
||||||
|
|
||||||
ftdm_log(FTDM_PRE, ftdm_level, "WAT span %d:%s", span_id, buff);
|
ftdm_log_chan_ex(gsm_data->dchan, __FILE__, __FUNCTION__, __LINE__, ftdm_level, "%s", buff);
|
||||||
|
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -540,7 +519,7 @@ static ftdm_status_t ftdm_gsm_start(ftdm_span_t *span)
|
|||||||
{
|
{
|
||||||
if (wat_span_start(span->span_id)) {
|
if (wat_span_start(span->span_id)) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Failed to start span %s!\n", span->name);
|
ftdm_log(FTDM_LOG_ERROR, "Failed to start span %s!\n", span->name);
|
||||||
return FTDM_SUCCESS;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ftdm_thread_create_detached(ftdm_gsm_run, span);
|
return ftdm_thread_create_detached(ftdm_gsm_run, span);
|
||||||
@ -548,13 +527,15 @@ static ftdm_status_t ftdm_gsm_start(ftdm_span_t *span)
|
|||||||
|
|
||||||
static ftdm_status_t ftdm_gsm_stop(ftdm_span_t *span)
|
static ftdm_status_t ftdm_gsm_stop(ftdm_span_t *span)
|
||||||
{
|
{
|
||||||
|
if (wat_span_stop(span->span_id)) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Failed to stop span %s!\n", span->name);
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_gsm_get_channel_sig_status)
|
static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(ftdm_gsm_get_channel_sig_status)
|
||||||
{
|
{
|
||||||
ftdm_log(FTDM_LOG_INFO, "\r\nftdm_gsm_get_channel_sig_status\r\n");
|
|
||||||
|
|
||||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||||
*status = FTDM_SIG_STATE_UP;
|
*status = FTDM_SIG_STATE_UP;
|
||||||
}
|
}
|
||||||
@ -698,7 +679,7 @@ static ftdm_state_map_t gsm_state_map = {
|
|||||||
static ftdm_status_t ftdm_gsm_state_advance(ftdm_channel_t *ftdmchan)
|
static ftdm_status_t ftdm_gsm_state_advance(ftdm_channel_t *ftdmchan)
|
||||||
{
|
{
|
||||||
|
|
||||||
ftdm_log_chan(ftdmchan, STATE_ADVANCE_LOG_LEVEL , "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler for %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||||
|
|
||||||
ftdm_channel_complete_state(ftdmchan);
|
ftdm_channel_complete_state(ftdmchan);
|
||||||
|
|
||||||
@ -857,6 +838,7 @@ static ftdm_status_t init_wat_lib(void)
|
|||||||
wat_interface.wat_sms_ind = on_wat_sms_ind;
|
wat_interface.wat_sms_ind = on_wat_sms_ind;
|
||||||
wat_interface.wat_sms_sts = on_wat_sms_sts;
|
wat_interface.wat_sms_sts = on_wat_sms_sts;
|
||||||
wat_interface.wat_span_sts = on_wat_span_status;
|
wat_interface.wat_span_sts = on_wat_span_status;
|
||||||
|
wat_interface.wat_dtmf_ind = on_wat_dtmf_ind;
|
||||||
|
|
||||||
if (wat_register(&wat_interface)) {
|
if (wat_register(&wat_interface)) {
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "Failed registering interface to WAT library ...\n");
|
ftdm_log(FTDM_LOG_DEBUG, "Failed registering interface to WAT library ...\n");
|
||||||
@ -869,6 +851,30 @@ static ftdm_status_t init_wat_lib(void)
|
|||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WAT_AT_CMD_RESPONSE_FUNC(on_dtmf_sent)
|
||||||
|
{
|
||||||
|
ftdm_channel_t *ftdmchan = obj;
|
||||||
|
ftdm_span_t *span = ftdmchan->span;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (success == WAT_TRUE) {
|
||||||
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "DTMF successfully transmitted on span %s\n", span->name);
|
||||||
|
} else {
|
||||||
|
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Command execution failed on span %s. Err: %s\n", span->name, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; tokens[i]; i++) {
|
||||||
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "%s\n", tokens[i]);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ftdm_status_t ftdm_gsm_send_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf)
|
||||||
|
{
|
||||||
|
ftdm_gsm_span_data_t *gsm_data = ftdmchan->span->signal_data;
|
||||||
|
wat_send_dtmf(ftdmchan->span->span_id, gsm_data->call_id, dtmf, on_dtmf_sent, ftdmchan);
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
||||||
{
|
{
|
||||||
@ -879,16 +885,22 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
|||||||
ftdm_channel_t *ftdmchan = NULL;
|
ftdm_channel_t *ftdmchan = NULL;
|
||||||
ftdm_channel_t *dchan = NULL;
|
ftdm_channel_t *dchan = NULL;
|
||||||
ftdm_channel_t *bchan = NULL;
|
ftdm_channel_t *bchan = NULL;
|
||||||
|
ftdm_bool_t hwdtmf_detect = FTDM_FALSE;
|
||||||
|
ftdm_bool_t hwdtmf_generate = FTDM_FALSE;
|
||||||
|
|
||||||
unsigned paramindex = 0;
|
unsigned paramindex = 0;
|
||||||
const char *var = NULL;
|
const char *var = NULL;
|
||||||
const char *val = NULL;
|
const char *val = NULL;
|
||||||
|
|
||||||
|
int codec = FTDM_CODEC_SLIN;
|
||||||
|
int interval = 20;
|
||||||
|
|
||||||
/* libwat is smart enough to set good default values for the timers if they are set to 0 */
|
/* libwat is smart enough to set good default values for the timers if they are set to 0 */
|
||||||
memset(&span_config, 0, sizeof(span_config));
|
memset(&span_config, 0, sizeof(span_config));
|
||||||
|
|
||||||
/* set some span defaults */
|
/* set some span defaults */
|
||||||
span_config.moduletype = WAT_MODULE_TELIT;
|
span_config.moduletype = WAT_MODULE_TELIT;
|
||||||
|
span_config.hardware_dtmf = WAT_FALSE;
|
||||||
|
|
||||||
if (FTDM_SUCCESS != init_wat_lib()) {
|
if (FTDM_SUCCESS != init_wat_lib()) {
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
@ -935,10 +947,6 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
|||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gsm_data = ftdm_calloc(1, sizeof(*gsm_data));
|
gsm_data = ftdm_calloc(1, sizeof(*gsm_data));
|
||||||
if (!gsm_data) {
|
if (!gsm_data) {
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
@ -946,9 +954,6 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
|||||||
gsm_data->dchan = dchan;
|
gsm_data->dchan = dchan;
|
||||||
gsm_data->bchan = bchan;
|
gsm_data->bchan = bchan;
|
||||||
|
|
||||||
//sprintf(gsm_data->dchan->chan_name, "%s\t\n", "GSM dchan");
|
|
||||||
//sprintf(gsm_data->bchan->chan_name, "%s\r\n", "GSM bchan");
|
|
||||||
|
|
||||||
for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
|
for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
|
||||||
var = ftdm_parameters[paramindex].var;
|
var = ftdm_parameters[paramindex].var;
|
||||||
val = ftdm_parameters[paramindex].val;
|
val = ftdm_parameters[paramindex].val;
|
||||||
@ -966,6 +971,21 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
|||||||
ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with moduletype %s\n", span->name, val);
|
ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with moduletype %s\n", span->name, val);
|
||||||
} else if (!strcasecmp(var, "debug")) {
|
} else if (!strcasecmp(var, "debug")) {
|
||||||
span_config.debug_mask = wat_str2debug(val);
|
span_config.debug_mask = wat_str2debug(val);
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with debug mask %s == 0x%X\n", span->name, val, span_config.debug_mask);
|
||||||
|
} else if (!strcasecmp(var, "hwdtmf")) {
|
||||||
|
hwdtmf_detect = FTDM_FALSE;
|
||||||
|
hwdtmf_generate = FTDM_FALSE;
|
||||||
|
if (!strcasecmp(val, "generate")) {
|
||||||
|
hwdtmf_generate = FTDM_TRUE;
|
||||||
|
} else if (!strcasecmp(val, "detect")) {
|
||||||
|
hwdtmf_detect = FTDM_TRUE;
|
||||||
|
} else if (!strcasecmp(val, "both") || ftdm_true(val)) {
|
||||||
|
hwdtmf_detect = FTDM_TRUE;
|
||||||
|
hwdtmf_generate = FTDM_TRUE;
|
||||||
|
} else {
|
||||||
|
span_config.hardware_dtmf = WAT_FALSE;
|
||||||
|
}
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "Configuring GSM span %s with hardware dtmf %s\n", span->name, val);
|
||||||
} else {
|
} else {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Ignoring unknown GSM parameter '%s'", var);
|
ftdm_log(FTDM_LOG_ERROR, "Ignoring unknown GSM parameter '%s'", var);
|
||||||
}
|
}
|
||||||
@ -976,17 +996,24 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
|||||||
span->stop = ftdm_gsm_stop;
|
span->stop = ftdm_gsm_stop;
|
||||||
span->sig_read = NULL;
|
span->sig_read = NULL;
|
||||||
span->sig_write = NULL;
|
span->sig_write = NULL;
|
||||||
|
if (hwdtmf_detect || hwdtmf_generate) {
|
||||||
|
span_config.hardware_dtmf = WAT_TRUE;
|
||||||
|
if (hwdtmf_generate) {
|
||||||
|
span->sig_send_dtmf = ftdm_gsm_send_dtmf;
|
||||||
|
}
|
||||||
|
if (hwdtmf_detect) {
|
||||||
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SIG_DTMF_DETECTION);
|
||||||
|
}
|
||||||
|
}
|
||||||
span->signal_cb = sig_cb;
|
span->signal_cb = sig_cb;
|
||||||
span->signal_type = FTDM_SIGTYPE_GSM;
|
span->signal_type = FTDM_SIGTYPE_GSM;
|
||||||
span->signal_data = gsm_data; /* Gideon, plz fill me with gsm span specific data (you allocate and free) */
|
span->signal_data = gsm_data;
|
||||||
span->outgoing_call = gsm_outgoing_call;
|
span->outgoing_call = gsm_outgoing_call;
|
||||||
span->get_span_sig_status = ftdm_gsm_get_span_sig_status;
|
span->get_span_sig_status = ftdm_gsm_get_span_sig_status;
|
||||||
span->set_span_sig_status = ftdm_gsm_set_span_sig_status;
|
span->set_span_sig_status = ftdm_gsm_set_span_sig_status;
|
||||||
span->get_channel_sig_status = ftdm_gsm_get_channel_sig_status;
|
span->get_channel_sig_status = ftdm_gsm_get_channel_sig_status;
|
||||||
span->set_channel_sig_status = ftdm_gsm_set_channel_sig_status;
|
span->set_channel_sig_status = ftdm_gsm_set_channel_sig_status;
|
||||||
|
|
||||||
//printf("\r\nspan->state_map = &gsm_state_map;\r\n");
|
|
||||||
span->state_map = &gsm_state_map;
|
span->state_map = &gsm_state_map;
|
||||||
span->state_processor = ftdm_gsm_state_advance;
|
span->state_processor = ftdm_gsm_state_advance;
|
||||||
|
|
||||||
@ -999,28 +1026,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_gsm_configure_span_signaling)
|
|||||||
|
|
||||||
gsm_data->span = span;
|
gsm_data->span = span;
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* setup the scheduler (create if needed) */
|
|
||||||
snprintf(schedname, sizeof(schedname), "ftmod_r2_%s", span->name);
|
|
||||||
ftdm_assert(ftdm_sched_create(&r2data->sched, schedname) == FTDM_SUCCESS, "Failed to create schedule!\n");
|
|
||||||
spanpvt->sched = r2data->sched;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
fprintf(stdout, "Configuring wat span %d %s \r\n", span->span_id, span->name);
|
|
||||||
if (wat_span_config(span->span_id, &span_config)) {
|
if (wat_span_config(span->span_id, &span_config)) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Failed to configure span %s for GSM signaling!!\n", span->name);
|
ftdm_log(FTDM_LOG_ERROR, "Failed to configure span %s for GSM signaling!!\n", span->name);
|
||||||
return FTDM_FAIL;
|
return FTDM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_NATIVE_CODEC, &codec);
|
||||||
int codec = FTDM_CODEC_SLIN;
|
ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_CODEC, &codec);
|
||||||
int interval = 20;
|
ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_INTERVAL, &interval);
|
||||||
|
|
||||||
ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_NATIVE_CODEC, &codec);
|
|
||||||
ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_CODEC, &codec);
|
|
||||||
ftdm_channel_command(gsm_data->bchan, FTDM_COMMAND_SET_INTERVAL, &interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
|
|
||||||
|
@ -1304,7 +1304,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
|
|||||||
span->indicate = ftdm_sangoma_isdn_indicate;
|
span->indicate = ftdm_sangoma_isdn_indicate;
|
||||||
span->channel_request = NULL;
|
span->channel_request = NULL;
|
||||||
span->signal_cb = sig_cb;
|
span->signal_cb = sig_cb;
|
||||||
span->sig_dtmf = ftdm_sangoma_isdn_dtmf;
|
span->sig_queue_dtmf = ftdm_sangoma_isdn_dtmf;
|
||||||
span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status;
|
span->get_channel_sig_status = ftdm_sangoma_isdn_get_chan_sig_status;
|
||||||
span->set_channel_sig_status = ftdm_sangoma_isdn_set_chan_sig_status;
|
span->set_channel_sig_status = ftdm_sangoma_isdn_set_chan_sig_status;
|
||||||
span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status;
|
span->get_span_sig_status = ftdm_sangoma_isdn_get_span_sig_status;
|
||||||
|
@ -513,7 +513,8 @@ struct ftdm_span {
|
|||||||
ftdm_span_stop_t stop;
|
ftdm_span_stop_t stop;
|
||||||
ftdm_channel_sig_read_t sig_read;
|
ftdm_channel_sig_read_t sig_read;
|
||||||
ftdm_channel_sig_write_t sig_write;
|
ftdm_channel_sig_write_t sig_write;
|
||||||
ftdm_channel_sig_dtmf_t sig_dtmf;
|
ftdm_channel_sig_dtmf_t sig_queue_dtmf;
|
||||||
|
ftdm_channel_sig_dtmf_t sig_send_dtmf;
|
||||||
ftdm_channel_state_processor_t state_processor; /*!< This guy is called whenever state processing is required */
|
ftdm_channel_state_processor_t state_processor; /*!< This guy is called whenever state processing is required */
|
||||||
void *io_data; /*!< Private I/O data per span. Do not touch unless you are an I/O module */
|
void *io_data; /*!< Private I/O data per span. Do not touch unless you are an I/O module */
|
||||||
char *type;
|
char *type;
|
||||||
|
@ -92,6 +92,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_get_time_to_next_timer(const ftdm_sched_t *
|
|||||||
/*! \brief Global initialization, called just once, this is called by FreeTDM core, other users MUST not call it */
|
/*! \brief Global initialization, called just once, this is called by FreeTDM core, other users MUST not call it */
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_sched_global_init(void);
|
FT_DECLARE(ftdm_status_t) ftdm_sched_global_init(void);
|
||||||
|
|
||||||
|
/*! \brief Global destroy, called just once, this is called by FreeTDM core, other users MUST not call it */
|
||||||
|
FT_DECLARE(ftdm_status_t) ftdm_sched_global_destroy(void);
|
||||||
|
|
||||||
/*! \brief Checks if the main scheduling thread is running */
|
/*! \brief Checks if the main scheduling thread is running */
|
||||||
FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void);
|
FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void);
|
||||||
|
|
||||||
|
@ -268,9 +268,11 @@ typedef enum {
|
|||||||
#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36)
|
#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36)
|
||||||
/*!< Native signaling bridge is enabled */
|
/*!< Native signaling bridge is enabled */
|
||||||
#define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37)
|
#define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37)
|
||||||
|
/*!< Native signaling DTMF detection */
|
||||||
|
#define FTDM_CHANNEL_SIG_DTMF_DETECTION (1ULL << 38)
|
||||||
|
|
||||||
/*!< This no more flags after this flag */
|
/*!< This no more flags after this flag */
|
||||||
#define FTDM_CHANNEL_MAX_FLAG (1ULL << 38)
|
#define FTDM_CHANNEL_MAX_FLAG (1ULL << 39)
|
||||||
/*!<When adding a new flag, need to update ftdm_io.c:channel_flag_strs */
|
/*!<When adding a new flag, need to update ftdm_io.c:channel_flag_strs */
|
||||||
|
|
||||||
#include "ftdm_state.h"
|
#include "ftdm_state.h"
|
||||||
|
@ -1 +1 @@
|
|||||||
Thu May 22 15:39:33 UTC 2014
|
Sat Jul 12 04:39:49 CDT 2014
|
||||||
|
@ -350,8 +350,15 @@ int su_getsocktype(su_socket_t s)
|
|||||||
|
|
||||||
int su_setreuseaddr(su_socket_t s, int reuse)
|
int su_setreuseaddr(su_socket_t s, int reuse)
|
||||||
{
|
{
|
||||||
return setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
|
#ifdef SO_REUSEPORT
|
||||||
(void *)&reuse, (socklen_t)sizeof(reuse));
|
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
|
||||||
|
(void *)&reuse, (socklen_t)sizeof(reuse)) < 0)
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
|
||||||
|
(void *)&reuse, (socklen_t)sizeof(reuse)) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ int tport_recv_stream_ws(tport_t *self)
|
|||||||
N = ws_read_frame(&wstp->ws, &oc, &data);
|
N = ws_read_frame(&wstp->ws, &oc, &data);
|
||||||
|
|
||||||
if (N == -2) {
|
if (N == -2) {
|
||||||
return 2;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((N == -1000) || (N == 0)) {
|
if ((N == -1000) || (N == 0)) {
|
||||||
|
@ -368,18 +368,25 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
|
|||||||
ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes)
|
ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes)
|
||||||
{
|
{
|
||||||
size_t r;
|
size_t r;
|
||||||
|
int sanity = 2000;
|
||||||
|
|
||||||
if (wsh->ssl) {
|
if (wsh->ssl) {
|
||||||
do {
|
do {
|
||||||
r = SSL_write(wsh->ssl, data, bytes);
|
r = SSL_write(wsh->ssl, data, bytes);
|
||||||
} while (r == -1 && SSL_get_error(wsh->ssl, r) == SSL_ERROR_WANT_WRITE);
|
if (sanity < 2000) {
|
||||||
|
ms_sleep(1);
|
||||||
|
}
|
||||||
|
} while (--sanity > 0 && r == -1 && SSL_get_error(wsh->ssl, r) == SSL_ERROR_WANT_WRITE);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
r = send(wsh->sock, data, bytes, 0);
|
r = send(wsh->sock, data, bytes, 0);
|
||||||
} while (r == -1 && xp_is_blocking(xp_errno()));
|
if (sanity < 2000) {
|
||||||
|
ms_sleep(1);
|
||||||
|
}
|
||||||
|
} while (--sanity > 0 && r == -1 && xp_is_blocking(xp_errno()));
|
||||||
|
|
||||||
//if (r<0) {
|
//if (r<0) {
|
||||||
//printf("wRITE FAIL: %s\n", strerror(errno));
|
//printf("wRITE FAIL: %s\n", strerror(errno));
|
||||||
|
@ -1 +1 @@
|
|||||||
Tue Dec 6 17:55:59 CST 2011
|
Thu Jun 5 22:07:01 CDT 2014
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
#define GEN_CONST
|
#define GEN_CONST
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_STDBOOL_H)
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "spandsp/stdbool.h"
|
||||||
|
#endif
|
||||||
#include "floating_fudge.h"
|
#include "floating_fudge.h"
|
||||||
|
|
||||||
#include "spandsp.h"
|
#include "spandsp.h"
|
||||||
@ -48,9 +53,6 @@
|
|||||||
|
|
||||||
#define PACKET_LOSS_TIME -1
|
#define PACKET_LOSS_TIME -1
|
||||||
|
|
||||||
#define FALSE 0
|
|
||||||
#define TRUE (!FALSE)
|
|
||||||
|
|
||||||
g1050_constants_t g1050_constants[1] =
|
g1050_constants_t g1050_constants[1] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -746,7 +748,7 @@ static void g1050_segment_init(g1050_segment_state_t *s,
|
|||||||
s->max_jitter = parms->max_jitter;
|
s->max_jitter = parms->max_jitter;
|
||||||
|
|
||||||
/* The following is common state information to all links. */
|
/* The following is common state information to all links. */
|
||||||
s->high_loss = FALSE;
|
s->high_loss = false;
|
||||||
s->congestion_delay = 0.0;
|
s->congestion_delay = 0.0;
|
||||||
s->last_arrival_time = 0.0;
|
s->last_arrival_time = 0.0;
|
||||||
|
|
||||||
@ -797,7 +799,7 @@ static void g1050_core_init(g1050_core_state_t *s, g1050_core_model_t *parms, in
|
|||||||
static void g1050_segment_model(g1050_segment_state_t *s, double delays[], int len)
|
static void g1050_segment_model(g1050_segment_state_t *s, double delays[], int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int lose;
|
bool lose;
|
||||||
int was_high_loss;
|
int was_high_loss;
|
||||||
double impulse;
|
double impulse;
|
||||||
double slice_delay;
|
double slice_delay;
|
||||||
@ -805,7 +807,7 @@ static void g1050_segment_model(g1050_segment_state_t *s, double delays[], int l
|
|||||||
/* Compute delay and loss value for each time slice. */
|
/* Compute delay and loss value for each time slice. */
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
lose = FALSE;
|
lose = false;
|
||||||
/* Initialize delay to the serial delay plus some jitter. */
|
/* Initialize delay to the serial delay plus some jitter. */
|
||||||
slice_delay = s->serial_delay + s->max_jitter*q1050_rand();
|
slice_delay = s->serial_delay + s->max_jitter*q1050_rand();
|
||||||
/* If no QoS, do congestion delay and packet loss analysis. */
|
/* If no QoS, do congestion delay and packet loss analysis. */
|
||||||
@ -826,14 +828,14 @@ static void g1050_segment_model(g1050_segment_state_t *s, double delays[], int l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (was_high_loss && q1050_rand() < s->prob_packet_loss)
|
if (was_high_loss && q1050_rand() < s->prob_packet_loss)
|
||||||
lose = TRUE;
|
lose = true;
|
||||||
/* Single pole LPF for the congestion delay impulses. */
|
/* Single pole LPF for the congestion delay impulses. */
|
||||||
s->congestion_delay = s->congestion_delay*s->impulse_coeff + impulse*(1.0 - s->impulse_coeff);
|
s->congestion_delay = s->congestion_delay*s->impulse_coeff + impulse*(1.0 - s->impulse_coeff);
|
||||||
slice_delay += s->congestion_delay;
|
slice_delay += s->congestion_delay;
|
||||||
}
|
}
|
||||||
/* If duplex mismatch on LAN, packet loss based on loss probability. */
|
/* If duplex mismatch on LAN, packet loss based on loss probability. */
|
||||||
if (s->multiple_access && (q1050_rand() < s->prob_packet_collision_loss))
|
if (s->multiple_access && (q1050_rand() < s->prob_packet_collision_loss))
|
||||||
lose = TRUE;
|
lose = true;
|
||||||
/* Put computed delay into time slice array. */
|
/* Put computed delay into time slice array. */
|
||||||
if (lose)
|
if (lose)
|
||||||
{
|
{
|
||||||
@ -851,12 +853,12 @@ static void g1050_segment_model(g1050_segment_state_t *s, double delays[], int l
|
|||||||
static void g1050_core_model(g1050_core_state_t *s, double delays[], int len)
|
static void g1050_core_model(g1050_core_state_t *s, double delays[], int len)
|
||||||
{
|
{
|
||||||
int32_t i;
|
int32_t i;
|
||||||
int lose;
|
bool lose;
|
||||||
double jitter_delay;
|
double jitter_delay;
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
lose = FALSE;
|
lose = false;
|
||||||
jitter_delay = s->base_delay + s->max_jitter*q1050_rand();
|
jitter_delay = s->base_delay + s->max_jitter*q1050_rand();
|
||||||
/* Route flapping */
|
/* Route flapping */
|
||||||
if (--s->route_flap_counter <= 0)
|
if (--s->route_flap_counter <= 0)
|
||||||
@ -866,18 +868,18 @@ static void g1050_core_model(g1050_core_state_t *s, double delays[], int len)
|
|||||||
s->route_flap_counter = s->route_flap_interval;
|
s->route_flap_counter = s->route_flap_interval;
|
||||||
}
|
}
|
||||||
if (q1050_rand() < s->prob_packet_loss)
|
if (q1050_rand() < s->prob_packet_loss)
|
||||||
lose = TRUE;
|
lose = true;
|
||||||
/* Link failures */
|
/* Link failures */
|
||||||
if (--s->link_failure_counter <= 0)
|
if (--s->link_failure_counter <= 0)
|
||||||
{
|
{
|
||||||
/* We are in a link failure */
|
/* We are in a link failure */
|
||||||
lose = TRUE;
|
lose = true;
|
||||||
if (--s->link_recovery_counter <= 0)
|
if (--s->link_recovery_counter <= 0)
|
||||||
{
|
{
|
||||||
/* Leave failure state. */
|
/* Leave failure state. */
|
||||||
s->link_failure_counter = s->link_failure_interval_ticks;
|
s->link_failure_counter = s->link_failure_interval_ticks;
|
||||||
s->link_recovery_counter = s->link_failure_duration_ticks;
|
s->link_recovery_counter = s->link_failure_duration_ticks;
|
||||||
lose = FALSE;
|
lose = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lose)
|
if (lose)
|
||||||
@ -1056,23 +1058,23 @@ static void g1050_simulate_chunk(g1050_state_t *s)
|
|||||||
|
|
||||||
s->base_time += 1.0;
|
s->base_time += 1.0;
|
||||||
|
|
||||||
memcpy(&s->segment[0].delays[0], &s->segment[0].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[0].delays[0]));
|
memmove(&s->segment[0].delays[0], &s->segment[0].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[0].delays[0]));
|
||||||
g1050_segment_model(&s->segment[0], &s->segment[0].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
g1050_segment_model(&s->segment[0], &s->segment[0].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
||||||
|
|
||||||
memcpy(&s->segment[1].delays[0], &s->segment[1].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[1].delays[0]));
|
memmove(&s->segment[1].delays[0], &s->segment[1].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[1].delays[0]));
|
||||||
g1050_segment_model(&s->segment[1], &s->segment[1].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
g1050_segment_model(&s->segment[1], &s->segment[1].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
||||||
|
|
||||||
memcpy(&s->core.delays[0], &s->core.delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->core.delays[0]));
|
memmove(&s->core.delays[0], &s->core.delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->core.delays[0]));
|
||||||
g1050_core_model(&s->core, &s->core.delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
g1050_core_model(&s->core, &s->core.delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
||||||
|
|
||||||
memcpy(&s->segment[2].delays[0], &s->segment[2].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[2].delays[0]));
|
memmove(&s->segment[2].delays[0], &s->segment[2].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[2].delays[0]));
|
||||||
g1050_segment_model(&s->segment[2], &s->segment[2].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
g1050_segment_model(&s->segment[2], &s->segment[2].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
||||||
|
|
||||||
memcpy(&s->segment[3].delays[0], &s->segment[3].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[3].delays[0]));
|
memmove(&s->segment[3].delays[0], &s->segment[3].delays[G1050_TICKS_PER_SEC], 2*G1050_TICKS_PER_SEC*sizeof(s->segment[3].delays[0]));
|
||||||
g1050_segment_model(&s->segment[3], &s->segment[3].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
g1050_segment_model(&s->segment[3], &s->segment[3].delays[2*G1050_TICKS_PER_SEC], G1050_TICKS_PER_SEC);
|
||||||
|
|
||||||
memcpy(&s->arrival_times_1[0], &s->arrival_times_1[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_1[0]));
|
memmove(&s->arrival_times_1[0], &s->arrival_times_1[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_1[0]));
|
||||||
memcpy(&s->arrival_times_2[0], &s->arrival_times_2[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_2[0]));
|
memmove(&s->arrival_times_2[0], &s->arrival_times_2[s->packet_rate], 2*s->packet_rate*sizeof(s->arrival_times_2[0]));
|
||||||
for (i = 0; i < s->packet_rate; i++)
|
for (i = 0; i < s->packet_rate; i++)
|
||||||
{
|
{
|
||||||
s->arrival_times_1[2*s->packet_rate + i] = s->base_time + 2.0 + (double) i/(double) s->packet_rate;
|
s->arrival_times_1[2*s->packet_rate + i] = s->base_time + 2.0 + (double) i/(double) s->packet_rate;
|
||||||
@ -1126,7 +1128,7 @@ SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
|
|||||||
&mo->sidea_lan,
|
&mo->sidea_lan,
|
||||||
sp->sidea_lan_bit_rate,
|
sp->sidea_lan_bit_rate,
|
||||||
sp->sidea_lan_multiple_access,
|
sp->sidea_lan_multiple_access,
|
||||||
FALSE,
|
false,
|
||||||
packet_size,
|
packet_size,
|
||||||
packet_rate);
|
packet_rate);
|
||||||
g1050_segment_init(&s->segment[1],
|
g1050_segment_init(&s->segment[1],
|
||||||
@ -1134,7 +1136,7 @@ SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
|
|||||||
&constants->segment[1],
|
&constants->segment[1],
|
||||||
&mo->sidea_access_link,
|
&mo->sidea_access_link,
|
||||||
sp->sidea_access_link_bit_rate_ab,
|
sp->sidea_access_link_bit_rate_ab,
|
||||||
FALSE,
|
false,
|
||||||
sp->sidea_access_link_qos_enabled,
|
sp->sidea_access_link_qos_enabled,
|
||||||
packet_size,
|
packet_size,
|
||||||
packet_rate);
|
packet_rate);
|
||||||
@ -1144,7 +1146,7 @@ SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
|
|||||||
&constants->segment[2],
|
&constants->segment[2],
|
||||||
&mo->sideb_access_link,
|
&mo->sideb_access_link,
|
||||||
sp->sideb_access_link_bit_rate_ba,
|
sp->sideb_access_link_bit_rate_ba,
|
||||||
FALSE,
|
false,
|
||||||
sp->sideb_access_link_qos_enabled,
|
sp->sideb_access_link_qos_enabled,
|
||||||
packet_size,
|
packet_size,
|
||||||
packet_rate);
|
packet_rate);
|
||||||
@ -1154,7 +1156,7 @@ SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
|
|||||||
&mo->sideb_lan,
|
&mo->sideb_lan,
|
||||||
sp->sideb_lan_bit_rate,
|
sp->sideb_lan_bit_rate,
|
||||||
sp->sideb_lan_multiple_access,
|
sp->sideb_lan_multiple_access,
|
||||||
FALSE,
|
false,
|
||||||
packet_size,
|
packet_size,
|
||||||
packet_rate);
|
packet_rate);
|
||||||
|
|
||||||
@ -1186,6 +1188,13 @@ SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
SPAN_DECLARE(int) g1050_free(g1050_state_t *s)
|
||||||
|
{
|
||||||
|
free(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(void) g1050_dump_parms(int model, int speed_pattern)
|
SPAN_DECLARE(void) g1050_dump_parms(int model, int speed_pattern)
|
||||||
{
|
{
|
||||||
g1050_channel_speeds_t *sp;
|
g1050_channel_speeds_t *sp;
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
#define GEN_CONST
|
#define GEN_CONST
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_STDBOOL_H)
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "spandsp/stdbool.h"
|
||||||
|
#endif
|
||||||
#include "floating_fudge.h"
|
#include "floating_fudge.h"
|
||||||
|
|
||||||
#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
|
#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
|
||||||
@ -345,7 +350,7 @@ SPAN_DECLARE(void) one_way_line_model_set_mains_pickup(one_way_line_model_state_
|
|||||||
|
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
tone_gen_descriptor_init(&mains_tone_desc, f, (int) (level - 10.0f), f*3, (int) level, 1, 0, 0, 0, TRUE);
|
tone_gen_descriptor_init(&mains_tone_desc, f, (int) (level - 10.0f), f*3, (int) level, 1, 0, 0, 0, true);
|
||||||
tone_gen_init(&s->mains_tone, &mains_tone_desc);
|
tone_gen_init(&s->mains_tone, &mains_tone_desc);
|
||||||
}
|
}
|
||||||
s->mains_interference = f;
|
s->mains_interference = f;
|
||||||
@ -454,9 +459,9 @@ SPAN_DECLARE(void) both_ways_line_model_set_mains_pickup(both_ways_line_model_st
|
|||||||
|
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
tone_gen_descriptor_init(&mains_tone_desc, f, (int) (level1 - 10.0f), f*3, (int) level1, 1, 0, 0, 0, TRUE);
|
tone_gen_descriptor_init(&mains_tone_desc, f, (int) (level1 - 10.0f), f*3, (int) level1, 1, 0, 0, 0, true);
|
||||||
tone_gen_init(&s->line1.mains_tone, &mains_tone_desc);
|
tone_gen_init(&s->line1.mains_tone, &mains_tone_desc);
|
||||||
tone_gen_descriptor_init(&mains_tone_desc, f, (int) (level2 - 10.0f), f*3, (int) level2, 1, 0, 0, 0, TRUE);
|
tone_gen_descriptor_init(&mains_tone_desc, f, (int) (level2 - 10.0f), f*3, (int) level2, 1, 0, 0, 0, true);
|
||||||
tone_gen_init(&s->line2.mains_tone, &mains_tone_desc);
|
tone_gen_init(&s->line2.mains_tone, &mains_tone_desc);
|
||||||
}
|
}
|
||||||
s->line1.mains_interference = f;
|
s->line1.mains_interference = f;
|
||||||
@ -494,8 +499,9 @@ SPAN_DECLARE(one_way_line_model_state_t *) one_way_line_model_init(int model, fl
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(int) one_way_line_model_release(one_way_line_model_state_t *s)
|
SPAN_DECLARE(int) one_way_line_model_free(one_way_line_model_state_t *s)
|
||||||
{
|
{
|
||||||
|
codec_munge_free(s->munge);
|
||||||
free(s);
|
free(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -559,8 +565,10 @@ SPAN_DECLARE(both_ways_line_model_state_t *) both_ways_line_model_init(int model
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(int) both_ways_line_model_release(both_ways_line_model_state_t *s)
|
SPAN_DECLARE(int) both_ways_line_model_free(both_ways_line_model_state_t *s)
|
||||||
{
|
{
|
||||||
|
codec_munge_free(s->line1.munge);
|
||||||
|
codec_munge_free(s->line2.munge);
|
||||||
free(s);
|
free(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -40,17 +40,16 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "floating_fudge.h"
|
|
||||||
#if defined(HAVE_FFTW3_H)
|
#if defined(HAVE_FFTW3_H)
|
||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
#else
|
#else
|
||||||
#include <fftw.h>
|
#include <fftw.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_TGMATH_H)
|
|
||||||
#include <tgmath.h>
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_MATH_H)
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#if defined(HAVE_STDBOOL_H)
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "spandsp/stdbool.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "spandsp.h"
|
#include "spandsp.h"
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
#define GEN_CONST
|
#define GEN_CONST
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_STDBOOL_H)
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "spandsp/stdbool.h"
|
||||||
|
#endif
|
||||||
#include "floating_fudge.h"
|
#include "floating_fudge.h"
|
||||||
|
|
||||||
#include "spandsp.h"
|
#include "spandsp.h"
|
||||||
@ -49,9 +54,6 @@
|
|||||||
|
|
||||||
#define PACKET_LOSS_TIME -1
|
#define PACKET_LOSS_TIME -1
|
||||||
|
|
||||||
#define FALSE 0
|
|
||||||
#define TRUE (!FALSE)
|
|
||||||
|
|
||||||
SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model,
|
SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model,
|
||||||
int speed_pattern,
|
int speed_pattern,
|
||||||
int packet_size,
|
int packet_size,
|
||||||
@ -70,6 +72,14 @@ SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model,
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
SPAN_DECLARE(int) rfc2198_sim_free(rfc2198_sim_state_t *s)
|
||||||
|
{
|
||||||
|
g1050_free(s->g1050);
|
||||||
|
free(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s,
|
SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s,
|
||||||
const uint8_t buf[],
|
const uint8_t buf[],
|
||||||
int len,
|
int len,
|
||||||
|
@ -272,6 +272,8 @@ SPAN_DECLARE(g1050_state_t *) g1050_init(int model,
|
|||||||
int packet_size,
|
int packet_size,
|
||||||
int packet_rate);
|
int packet_rate);
|
||||||
|
|
||||||
|
SPAN_DECLARE(int) g1050_free(g1050_state_t *s);
|
||||||
|
|
||||||
SPAN_DECLARE(void) g1050_dump_parms(int model, int speed_pattern);
|
SPAN_DECLARE(void) g1050_dump_parms(int model, int speed_pattern);
|
||||||
|
|
||||||
SPAN_DECLARE(int) g1050_put(g1050_state_t *s,
|
SPAN_DECLARE(int) g1050_put(g1050_state_t *s,
|
||||||
|
@ -154,7 +154,7 @@ SPAN_DECLARE(both_ways_line_model_state_t *) both_ways_line_model_init(int model
|
|||||||
int codec,
|
int codec,
|
||||||
int rbs_pattern);
|
int rbs_pattern);
|
||||||
|
|
||||||
SPAN_DECLARE(int) both_ways_line_model_release(both_ways_line_model_state_t *s);
|
SPAN_DECLARE(int) both_ways_line_model_free(both_ways_line_model_state_t *s);
|
||||||
|
|
||||||
SPAN_DECLARE(void) one_way_line_model(one_way_line_model_state_t *s,
|
SPAN_DECLARE(void) one_way_line_model(one_way_line_model_state_t *s,
|
||||||
int16_t output[],
|
int16_t output[],
|
||||||
@ -167,7 +167,7 @@ SPAN_DECLARE(void) one_way_line_model_set_mains_pickup(one_way_line_model_state_
|
|||||||
|
|
||||||
SPAN_DECLARE(one_way_line_model_state_t *) one_way_line_model_init(int model, float noise, int codec, int rbs_pattern);
|
SPAN_DECLARE(one_way_line_model_state_t *) one_way_line_model_init(int model, float noise, int codec, int rbs_pattern);
|
||||||
|
|
||||||
SPAN_DECLARE(int) one_way_line_model_release(one_way_line_model_state_t *s);
|
SPAN_DECLARE(int) one_way_line_model_free(one_way_line_model_state_t *s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,8 @@ SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model,
|
|||||||
int packet_rate,
|
int packet_rate,
|
||||||
int redundancy_depth);
|
int redundancy_depth);
|
||||||
|
|
||||||
|
SPAN_DECLARE(int) rfc2198_sim_free(rfc2198_sim_state_t *s);
|
||||||
|
|
||||||
SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s,
|
SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s,
|
||||||
const uint8_t buf[],
|
const uint8_t buf[],
|
||||||
int len,
|
int len,
|
||||||
|
@ -51,7 +51,7 @@ extern "C" {
|
|||||||
|
|
||||||
SPAN_DECLARE(complexify_state_t *) complexify_init(void);
|
SPAN_DECLARE(complexify_state_t *) complexify_init(void);
|
||||||
|
|
||||||
SPAN_DECLARE(void) complexify_release(complexify_state_t *s);
|
SPAN_DECLARE(int) complexify_free(complexify_state_t *s);
|
||||||
|
|
||||||
SPAN_DECLARE(complexf_t) complexify(complexify_state_t *s, int16_t amp);
|
SPAN_DECLARE(complexf_t) complexify(complexify_state_t *s, int16_t amp);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ SPAN_DECLARE(void) ifft(complex_t data[], int len);
|
|||||||
|
|
||||||
SPAN_DECLARE(codec_munge_state_t *) codec_munge_init(int codec, int info);
|
SPAN_DECLARE(codec_munge_state_t *) codec_munge_init(int codec, int info);
|
||||||
|
|
||||||
SPAN_DECLARE(void) codec_munge_release(codec_munge_state_t *s);
|
SPAN_DECLARE(void) codec_munge_free(codec_munge_state_t *s);
|
||||||
|
|
||||||
SPAN_DECLARE(void) codec_munge(codec_munge_state_t *s, int16_t amp[], int len);
|
SPAN_DECLARE(void) codec_munge(codec_munge_state_t *s, int16_t amp[], int len);
|
||||||
|
|
||||||
|
@ -39,6 +39,11 @@
|
|||||||
#if defined(HAVE_MATH_H)
|
#if defined(HAVE_MATH_H)
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_STDBOOL_H)
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include "spandsp/stdbool.h"
|
||||||
|
#endif
|
||||||
#include "floating_fudge.h"
|
#include "floating_fudge.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -66,12 +71,14 @@ struct complexify_state_s
|
|||||||
};
|
};
|
||||||
|
|
||||||
static complex_t circle[MAX_FFT_LEN/2];
|
static complex_t circle[MAX_FFT_LEN/2];
|
||||||
static int circle_init = FALSE;
|
static int circle_init = false;
|
||||||
static complex_t icircle[MAX_FFT_LEN/2];
|
static complex_t icircle[MAX_FFT_LEN/2];
|
||||||
static int icircle_init = FALSE;
|
static int icircle_init = false;
|
||||||
|
|
||||||
#define SF_MAX_HANDLE 32
|
#define SF_MAX_HANDLE 32
|
||||||
static int sf_close_at_exit_registered = FALSE;
|
|
||||||
|
static int sf_close_at_exit_registered = false;
|
||||||
|
|
||||||
static SNDFILE *sf_close_at_exit_list[SF_MAX_HANDLE] =
|
static SNDFILE *sf_close_at_exit_list[SF_MAX_HANDLE] =
|
||||||
{
|
{
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
@ -95,9 +102,10 @@ SPAN_DECLARE(complexify_state_t *) complexify_init(void)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(void) complexify_release(complexify_state_t *s)
|
SPAN_DECLARE(int) complexify_free(complexify_state_t *s)
|
||||||
{
|
{
|
||||||
free(s);
|
free(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
@ -243,7 +251,7 @@ SPAN_DECLARE(void) fft(complex_t data[], int len)
|
|||||||
x = -(2.0*3.1415926535*i)/(double) MAX_FFT_LEN;
|
x = -(2.0*3.1415926535*i)/(double) MAX_FFT_LEN;
|
||||||
circle[i] = expj(x);
|
circle[i] = expj(x);
|
||||||
}
|
}
|
||||||
circle_init = TRUE;
|
circle_init = true;
|
||||||
}
|
}
|
||||||
fftx(data, temp, len);
|
fftx(data, temp, len);
|
||||||
}
|
}
|
||||||
@ -263,7 +271,7 @@ SPAN_DECLARE(void) ifft(complex_t data[], int len)
|
|||||||
x = (2.0*3.1415926535*i)/(double) MAX_FFT_LEN;
|
x = (2.0*3.1415926535*i)/(double) MAX_FFT_LEN;
|
||||||
icircle[i] = expj(x);
|
icircle[i] = expj(x);
|
||||||
}
|
}
|
||||||
icircle_init = TRUE;
|
icircle_init = true;
|
||||||
}
|
}
|
||||||
ifftx(data, temp, len);
|
ifftx(data, temp, len);
|
||||||
}
|
}
|
||||||
@ -308,7 +316,7 @@ SPAN_DECLARE(codec_munge_state_t *) codec_munge_init(int codec, int info)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(void) codec_munge_release(codec_munge_state_t *s)
|
SPAN_DECLARE(void) codec_munge_free(codec_munge_state_t *s)
|
||||||
{
|
{
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
@ -389,7 +397,7 @@ static int sf_record_handle(SNDFILE *handle)
|
|||||||
if (!sf_close_at_exit_registered)
|
if (!sf_close_at_exit_registered)
|
||||||
{
|
{
|
||||||
atexit(sf_close_at_exit);
|
atexit(sf_close_at_exit);
|
||||||
sf_close_at_exit_registered = TRUE;
|
sf_close_at_exit_registered = true;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -455,7 +463,6 @@ SPAN_DECLARE(int) sf_close_telephony(SNDFILE *handle)
|
|||||||
{
|
{
|
||||||
if (sf_close_at_exit_list[i] == handle)
|
if (sf_close_at_exit_list[i] == handle)
|
||||||
{
|
{
|
||||||
sf_close(sf_close_at_exit_list[i]);
|
|
||||||
sf_close_at_exit_list[i] = NULL;
|
sf_close_at_exit_list[i] = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
modem CDATA #IMPLIED
|
modem CDATA #IMPLIED
|
||||||
tag CDATA #IMPLIED
|
tag CDATA #IMPLIED
|
||||||
value CDATA #IMPLIED
|
value CDATA #IMPLIED
|
||||||
|
timein CDATA #IMPLIED
|
||||||
timeout CDATA #IMPLIED
|
timeout CDATA #IMPLIED
|
||||||
crc_error CDATA #IMPLIED
|
crc_error CDATA #IMPLIED
|
||||||
pattern CDATA #IMPLIED
|
pattern CDATA #IMPLIED
|
||||||
|
@ -91,6 +91,9 @@
|
|||||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||||
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
||||||
<step dir="T" type="POSTAMBLE"/>
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
<step dir="T" type="CLEAR"/>
|
||||||
|
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||||
|
<step type="STATUS" value="RX_DCNDATA"/>
|
||||||
</test>
|
</test>
|
||||||
<test name="V17-12000-V29-9600">
|
<test name="V17-12000-V29-9600">
|
||||||
<!-- Tester calls, trying to provoke a crash seen in some versions of spandsp, when
|
<!-- Tester calls, trying to provoke a crash seen in some versions of spandsp, when
|
||||||
@ -183,6 +186,198 @@
|
|||||||
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||||
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
||||||
<step dir="T" type="POSTAMBLE"/>
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
<step dir="T" type="CLEAR"/>
|
||||||
|
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||||
|
<step type="STATUS" value="OK"/>
|
||||||
|
</test>
|
||||||
|
<test name="Phase-D-collision">
|
||||||
|
<!-- DUT calls tester and sends 1 IMPRESS and 1 WHITE page. The MCF after the first
|
||||||
|
page is delayed enough to cause a collision with a retry of the MPS from the DUT. -->
|
||||||
|
<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="3500"/>
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
<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="Modem-change-at-CTC">
|
||||||
|
<!-- Similar test to TSB85/OREN03, but there is a modem change at the CTC -->
|
||||||
|
<!-- Tester calls DUT and sends 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 type="WAIT" value="75"/>
|
||||||
|
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||||
|
<step dir="T" type="HDLC" tag="DCS" value="FF C8 41 00 60 1F 20"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<step dir="T" type="TCF" modem="V.29/9600" value="1800"/>
|
||||||
|
|
||||||
|
<step dir="R" type="HDLC" modem="V.21" tag="CFR" value="FF C8 21"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<step dir="T" type="PREAMBLE" modem="V.29/9600"/>
|
||||||
|
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif" frame_size="64" crc_error="0"/>
|
||||||
|
<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 00 10"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
|
<possible-step>
|
||||||
|
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||||
|
<step dir="R" type="SILENCE"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<step dir="T" type="PREAMBLE" modem="V.29/9600"/>
|
||||||
|
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif" frame_size="64" crc_error="0"/>
|
||||||
|
<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 00 10"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
|
<possible-step>
|
||||||
|
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||||
|
<step dir="R" type="SILENCE"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<step dir="T" type="PREAMBLE" modem="V.29/9600"/>
|
||||||
|
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif" frame_size="64" crc_error="0"/>
|
||||||
|
<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 00 10"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
|
<possible-step>
|
||||||
|
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||||
|
<step dir="R" type="SILENCE"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<step dir="T" type="PREAMBLE" modem="V.29/9600"/>
|
||||||
|
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif" frame_size="64" crc_error="0"/>
|
||||||
|
<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 00 10"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
|
<possible-step>
|
||||||
|
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||||
|
<step dir="R" type="SILENCE"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<step dir="T" type="PREAMBLE" modem="V.21"/>
|
||||||
|
<step dir="T" type="HDLC" tag="CTC + V.27ter/4800" value="FF C8 48 00 10"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
|
<step dir="R" type="HDLC" modem="V.21" tag="CTR" value="FF C8 23"/>
|
||||||
|
<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" frame_size="64"/>
|
||||||
|
<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 00 6B"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
|
<possible-step>
|
||||||
|
<step dir="R" type="HDLC" modem="V.21" tag="RNR" value="FF C8 37"/>
|
||||||
|
<step dir="R" type="SILENCE"/>
|
||||||
|
|
||||||
|
<step type="WAIT" value="75"/>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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"/>
|
||||||
|
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
|
||||||
|
<step dir="T" type="POSTAMBLE"/>
|
||||||
|
|
||||||
|
<step dir="T" type="CLEAR"/>
|
||||||
|
<step dir="R" type="CLEAR" timein="0" timeout="100"/>
|
||||||
|
<step type="STATUS" value="OK"/>
|
||||||
</test>
|
</test>
|
||||||
</test-group>
|
</test-group>
|
||||||
</fax-tests>
|
</fax-tests>
|
||||||
|
@ -1029,13 +1029,13 @@ SPAN_DECLARE(int) adsi_add_field(adsi_tx_state_t *s, uint8_t *msg, int len, uint
|
|||||||
msg[len++] = (uint8_t) field_len;
|
msg[len++] = (uint8_t) field_len;
|
||||||
if (field_len == DLE)
|
if (field_len == DLE)
|
||||||
msg[len++] = (uint8_t) field_len;
|
msg[len++] = (uint8_t) field_len;
|
||||||
memcpy(msg + len, field_body, field_len);
|
memcpy(&msg[len], field_body, field_len);
|
||||||
len += field_len;
|
len += field_len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No field type or length, for restricted single message formats */
|
/* No field type or length, for restricted single message formats */
|
||||||
memcpy(msg + len, field_body, field_len);
|
memcpy(&msg[len], field_body, field_len);
|
||||||
len += field_len;
|
len += field_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1080,7 +1080,7 @@ SPAN_DECLARE(int) adsi_add_field(adsi_tx_state_t *s, uint8_t *msg, int len, uint
|
|||||||
x = msg[--len];
|
x = msg[--len];
|
||||||
if (field_type != CLIP_DTMF_HASH_UNSPECIFIED)
|
if (field_type != CLIP_DTMF_HASH_UNSPECIFIED)
|
||||||
msg[len++] = field_type;
|
msg[len++] = field_type;
|
||||||
memcpy(msg + len, field_body, field_len);
|
memcpy(&msg[len], field_body, field_len);
|
||||||
msg[len + field_len] = (uint8_t) x;
|
msg[len + field_len] = (uint8_t) x;
|
||||||
len += (field_len + 1);
|
len += (field_len + 1);
|
||||||
}
|
}
|
||||||
|
@ -5411,7 +5411,7 @@ static int command_search(const char *u, int *matched)
|
|||||||
|
|
||||||
entry = 0;
|
entry = 0;
|
||||||
/* Loop over the length of the string to search the trie... */
|
/* Loop over the length of the string to search the trie... */
|
||||||
for (i = 0, ptr = 0; ptr < COMMAND_TRIE_LEN; i++)
|
for (i = 0, ptr = 0; ptr < COMMAND_TRIE_LEN - 2; i++)
|
||||||
{
|
{
|
||||||
/* The character in u we are processing... */
|
/* The character in u we are processing... */
|
||||||
/* V.250 5.4.1 says upper and lower case are equivalent in commands */
|
/* V.250 5.4.1 says upper and lower case are equivalent in commands */
|
||||||
|
@ -348,12 +348,14 @@ SPAN_DECLARE(bell_mf_tx_state_t *) bell_mf_tx_init(bell_mf_tx_state_t *s)
|
|||||||
|
|
||||||
SPAN_DECLARE(int) bell_mf_tx_release(bell_mf_tx_state_t *s)
|
SPAN_DECLARE(int) bell_mf_tx_release(bell_mf_tx_state_t *s)
|
||||||
{
|
{
|
||||||
|
queue_release(&s->queue.queue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(int) bell_mf_tx_free(bell_mf_tx_state_t *s)
|
SPAN_DECLARE(int) bell_mf_tx_free(bell_mf_tx_state_t *s)
|
||||||
{
|
{
|
||||||
|
queue_release(&s->queue.queue);
|
||||||
span_free(s);
|
span_free(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -597,12 +597,14 @@ SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s,
|
|||||||
|
|
||||||
SPAN_DECLARE(int) dtmf_tx_release(dtmf_tx_state_t *s)
|
SPAN_DECLARE(int) dtmf_tx_release(dtmf_tx_state_t *s)
|
||||||
{
|
{
|
||||||
|
queue_release(&s->queue.queue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(int) dtmf_tx_free(dtmf_tx_state_t *s)
|
SPAN_DECLARE(int) dtmf_tx_free(dtmf_tx_state_t *s)
|
||||||
{
|
{
|
||||||
|
queue_release(&s->queue.queue);
|
||||||
span_free(s);
|
span_free(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ SPAN_DECLARE(logging_state_t *) fax_get_logging_state(fax_state_t *s)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
|
SPAN_DECLARE(int) fax_restart(fax_state_t *s, bool calling_party)
|
||||||
{
|
{
|
||||||
v8_parms_t v8_parms;
|
v8_parms_t v8_parms;
|
||||||
|
|
||||||
@ -420,7 +420,7 @@ SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
|
|||||||
v8_parms.nsf = -1;
|
v8_parms.nsf = -1;
|
||||||
v8_parms.t66 = -1;
|
v8_parms.t66 = -1;
|
||||||
v8_restart(&s->v8, calling_party, &v8_parms);
|
v8_restart(&s->v8, calling_party, &v8_parms);
|
||||||
t30_restart(&s->t30);
|
t30_restart(&s->t30, calling_party);
|
||||||
#if defined(LOG_FAX_AUDIO)
|
#if defined(LOG_FAX_AUDIO)
|
||||||
{
|
{
|
||||||
char buf[100 + 1];
|
char buf[100 + 1];
|
||||||
@ -455,7 +455,7 @@ SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
|
SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, bool calling_party)
|
||||||
{
|
{
|
||||||
v8_parms_t v8_parms;
|
v8_parms_t v8_parms;
|
||||||
|
|
||||||
@ -515,13 +515,14 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
|
|||||||
SPAN_DECLARE(int) fax_release(fax_state_t *s)
|
SPAN_DECLARE(int) fax_release(fax_state_t *s)
|
||||||
{
|
{
|
||||||
t30_release(&s->t30);
|
t30_release(&s->t30);
|
||||||
|
v8_release(&s->v8);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(int) fax_free(fax_state_t *s)
|
SPAN_DECLARE(int) fax_free(fax_state_t *s)
|
||||||
{
|
{
|
||||||
t30_release(&s->t30);
|
fax_release(s);
|
||||||
span_free(s);
|
span_free(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,10 @@ SPAN_DECLARE_NONSTD(void) fax_modems_hdlc_tx_frame(void *user_data, const uint8_
|
|||||||
|
|
||||||
s = (fax_modems_state_t *) user_data;
|
s = (fax_modems_state_t *) user_data;
|
||||||
|
|
||||||
hdlc_tx_frame(&s->hdlc_tx, msg, len);
|
if (len == -1)
|
||||||
|
hdlc_tx_restart(&s->hdlc_tx);
|
||||||
|
else
|
||||||
|
hdlc_tx_frame(&s->hdlc_tx, msg, len);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -311,6 +311,20 @@ SPAN_DECLARE(void) hdlc_rx_set_octet_counting_report_interval(hdlc_rx_state_t *s
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
SPAN_DECLARE(int) hdlc_rx_restart(hdlc_rx_state_t *s)
|
||||||
|
{
|
||||||
|
s->framing_ok_announced = false;
|
||||||
|
s->flags_seen = 0;
|
||||||
|
s->raw_bit_stream = 0;
|
||||||
|
s->byte_in_progress = 0;
|
||||||
|
s->num_bits = 0;
|
||||||
|
s->octet_counting_mode = false;
|
||||||
|
s->octet_count = 0;
|
||||||
|
s->len = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(hdlc_rx_state_t *) hdlc_rx_init(hdlc_rx_state_t *s,
|
SPAN_DECLARE(hdlc_rx_state_t *) hdlc_rx_init(hdlc_rx_state_t *s,
|
||||||
bool crc32,
|
bool crc32,
|
||||||
bool report_bad_frames,
|
bool report_bad_frames,
|
||||||
@ -375,7 +389,7 @@ SPAN_DECLARE(int) hdlc_rx_get_stats(hdlc_rx_state_t *s,
|
|||||||
|
|
||||||
SPAN_DECLARE(int) hdlc_tx_frame(hdlc_tx_state_t *s, const uint8_t *frame, size_t len)
|
SPAN_DECLARE(int) hdlc_tx_frame(hdlc_tx_state_t *s, const uint8_t *frame, size_t len)
|
||||||
{
|
{
|
||||||
if (len <= 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
s->tx_end = true;
|
s->tx_end = true;
|
||||||
return 0;
|
return 0;
|
||||||
@ -394,7 +408,7 @@ SPAN_DECLARE(int) hdlc_tx_frame(hdlc_tx_state_t *s, const uint8_t *frame, size_t
|
|||||||
if (s->len)
|
if (s->len)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(s->buffer + s->len, frame, len);
|
memcpy(&s->buffer[s->len], frame, len);
|
||||||
if (s->crc_bytes == 2)
|
if (s->crc_bytes == 2)
|
||||||
s->crc = crc_itu16_calc(frame, len, (uint16_t) s->crc);
|
s->crc = crc_itu16_calc(frame, len, (uint16_t) s->crc);
|
||||||
else
|
else
|
||||||
@ -589,6 +603,27 @@ SPAN_DECLARE(void) hdlc_tx_set_max_frame_len(hdlc_tx_state_t *s, size_t max_len)
|
|||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
|
SPAN_DECLARE(int) hdlc_tx_restart(hdlc_tx_state_t *s)
|
||||||
|
{
|
||||||
|
s->octets_in_progress = 0;
|
||||||
|
s->num_bits = 0;
|
||||||
|
s->idle_octet = 0x7E;
|
||||||
|
s->flag_octets = 0;
|
||||||
|
s->abort_octets = 0;
|
||||||
|
s->report_flag_underflow = false;
|
||||||
|
s->len = 0;
|
||||||
|
s->pos = 0;
|
||||||
|
if (s->crc_bytes == 2)
|
||||||
|
s->crc = 0xFFFF;
|
||||||
|
else
|
||||||
|
s->crc = 0xFFFFFFFF;
|
||||||
|
s->byte = 0;
|
||||||
|
s->bits = 0;
|
||||||
|
s->tx_end = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
||||||
bool crc32,
|
bool crc32,
|
||||||
int inter_frame_flags,
|
int inter_frame_flags,
|
||||||
@ -602,7 +637,6 @@ SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(s, 0, sizeof(*s));
|
memset(s, 0, sizeof(*s));
|
||||||
s->idle_octet = 0x7E;
|
|
||||||
s->underflow_handler = handler;
|
s->underflow_handler = handler;
|
||||||
s->user_data = user_data;
|
s->user_data = user_data;
|
||||||
s->inter_frame_flags = (inter_frame_flags < 1) ? 1 : inter_frame_flags;
|
s->inter_frame_flags = (inter_frame_flags < 1) ? 1 : inter_frame_flags;
|
||||||
@ -616,6 +650,7 @@ SPAN_DECLARE(hdlc_tx_state_t *) hdlc_tx_init(hdlc_tx_state_t *s,
|
|||||||
s->crc_bytes = 2;
|
s->crc_bytes = 2;
|
||||||
s->crc = 0xFFFF;
|
s->crc = 0xFFFF;
|
||||||
}
|
}
|
||||||
|
s->idle_octet = 0x7E;
|
||||||
s->progressive = progressive;
|
s->progressive = progressive;
|
||||||
s->max_frame_len = HDLC_MAXFRAME_LEN;
|
s->max_frame_len = HDLC_MAXFRAME_LEN;
|
||||||
return s;
|
return s;
|
||||||
|