mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 08:05:37 +00:00
Merge remote branch 'origin/master'
This commit is contained in:
commit
0d37261888
@ -300,7 +300,7 @@ endif
|
||||
fs_encode_SOURCES = src/fs_encode.c
|
||||
fs_encode_CFLAGS = $(AM_CFLAGS)
|
||||
fs_encode_LDFLAGS = $(AM_LDFLAGS) $(CORE_LIBS)
|
||||
fs_encode_LDADD = libfreeswitch.la
|
||||
fs_encode_LDADD = libfreeswitch.la -lcrypt -lrt
|
||||
|
||||
##
|
||||
## tone2wav ()
|
||||
@ -308,7 +308,7 @@ fs_encode_LDADD = libfreeswitch.la
|
||||
tone2wav_SOURCES = src/tone2wav.c
|
||||
tone2wav_CFLAGS = $(AM_CFLAGS)
|
||||
tone2wav_LDFLAGS = $(AM_LDFLAGS) $(CORE_LIBS)
|
||||
tone2wav_LDADD = libfreeswitch.la
|
||||
tone2wav_LDADD = libfreeswitch.la -lcrypt -lrt
|
||||
|
||||
##
|
||||
## fs_ivrd ()
|
||||
|
@ -43,8 +43,8 @@ start() {
|
||||
fi
|
||||
cd $FS_HOME
|
||||
daemon --user $FS_USER --pidfile $PID_FILE "$FS_FILE $FREESWITCH_ARGS $FREESWITCH_PARAMS >/dev/null 2>&1"
|
||||
echo
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch $LOCK_FILE;
|
||||
echo
|
||||
return $RETVAL
|
||||
|
@ -2,6 +2,7 @@ loggers/mod_console
|
||||
loggers/mod_logfile
|
||||
loggers/mod_syslog
|
||||
#applications/mod_cidlookup
|
||||
#applications/mod_blacklist
|
||||
applications/mod_commands
|
||||
applications/mod_conference
|
||||
applications/mod_dptools
|
||||
@ -38,6 +39,7 @@ applications/mod_valet_parking
|
||||
#applications/mod_fsk
|
||||
#applications/mod_ladspa
|
||||
#applications/mod_mongo
|
||||
applications/mod_sms
|
||||
codecs/mod_g723_1
|
||||
codecs/mod_amr
|
||||
#codecs/mod_amrwb
|
||||
@ -81,6 +83,7 @@ event_handlers/mod_event_socket
|
||||
#event_handlers/mod_event_zmq
|
||||
event_handlers/mod_cdr_csv
|
||||
event_handlers/mod_cdr_sqlite
|
||||
#event_handlers/mod_cdr_mongodb
|
||||
#event_handlers/mod_cdr_pg_csv
|
||||
#event_handlers/mod_radius_cdr
|
||||
#event_handlers/mod_erlang_event
|
||||
|
11
conf/autoload_configs/blacklist.conf.xml
Normal file
11
conf/autoload_configs/blacklist.conf.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<configuration name="mod_blacklist.conf" description="Blacklist module">
|
||||
<lists>
|
||||
<!--
|
||||
Example blacklist, the referenced file contains blacklisted items, one entry per line
|
||||
|
||||
NOTE: make sure the file exists and is readable by FreeSWITCH.
|
||||
|
||||
<list name="example" filename="/usr/local/freeswitch/conf/blacklists/example.list"/>
|
||||
-->
|
||||
</lists>
|
||||
</configuration>
|
13
conf/autoload_configs/cdr_mongodb.conf.xml
Normal file
13
conf/autoload_configs/cdr_mongodb.conf.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<configuration name="cdr_mongodb.conf" description="MongoDB CDR logger">
|
||||
<settings>
|
||||
<!-- Hostnames and IPv6 addrs not supported (yet) -->
|
||||
<param name="host" value="127.0.0.1"/>
|
||||
<param name="port" value="27017"/>
|
||||
|
||||
<!-- Namespace format is database.collection -->
|
||||
<param name="namespace" value="test.cdr"/>
|
||||
|
||||
<!-- If true, create CDR for B-leg of call (default: true) -->
|
||||
<param name="log-b-leg" value="false"/>
|
||||
</settings>
|
||||
</configuration>
|
@ -1,6 +1,12 @@
|
||||
<configuration name="mongo.conf">
|
||||
<settings>
|
||||
<param name="host" value="127.0.0.1:27017"/>
|
||||
<!--
|
||||
connection-string handles different ways to connect to mongo
|
||||
samples:
|
||||
server:port
|
||||
foo/server:port,server:port SET
|
||||
-->
|
||||
<param name="connection-string" value="127.0.0.1:27017"/>
|
||||
<param name="min-connections" value="10"/>
|
||||
<param name="max-connections" value="100"/>
|
||||
|
||||
|
14
conf/chatplan/default.xml
Normal file
14
conf/chatplan/default.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<include>
|
||||
<context name="default">
|
||||
|
||||
<extension name="demo">
|
||||
<condition field="to" expression="^(.*)$">
|
||||
<!-- <action application="lua" data="test.lua"/> -->
|
||||
|
||||
<action application="reply" data="Hello, you said: ${_body}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
</context>
|
||||
</include>
|
@ -70,8 +70,8 @@
|
||||
<!-- independence day -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="2" mweek="1" mon="9">
|
||||
<!-- labor day is the 1st monday in september -->
|
||||
<condition wday="2" mday="1-7" mon="9">
|
||||
<!-- labor day is the 1st monday in september (the only monday between the 1st and the 7th) -->
|
||||
<action application="set" data="open=false"/>
|
||||
</condition>
|
||||
<condition wday="2" mweek="2" mon="10">
|
||||
@ -181,7 +181,7 @@
|
||||
<extension name="eavesdrop">
|
||||
<condition field="destination_number" expression="^88(\d{4})$|^\*0(.*)$">
|
||||
<action application="answer"/>
|
||||
<action application="eavesdrop" data="${hash(select/${domain_name}-spymap/$1)}"/>
|
||||
<action application="eavesdrop" data="${hash(select/${domain_name}-spymap/$1$2)}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
|
@ -46,6 +46,10 @@
|
||||
<X-PRE-PROCESS cmd="include" data="dialplan/*.xml"/>
|
||||
</section>
|
||||
|
||||
<section name="chatplan" description="Regex/XML Chatplan">
|
||||
<X-PRE-PROCESS cmd="include" data="chatplan/*.xml"/>
|
||||
</section>
|
||||
|
||||
<!-- mod_dingaling is reliant on the vcard data in the "directory" section. -->
|
||||
<!-- mod_sofia is reliant on the user data for authorization -->
|
||||
<section name="directory" description="User Directory">
|
||||
|
@ -9,6 +9,26 @@
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="has_called_conf">
|
||||
<input pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="play-file" data="$1"/>
|
||||
<action function="sleep" data="100"/>
|
||||
<action function="play-file" data="conference/conf-has_joined.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="has_left_conf">
|
||||
<input pattern="^(\d+)$">
|
||||
<match>
|
||||
<action function="play-file" data="$1"/>
|
||||
<action function="sleep" data="100"/>
|
||||
<action function="play-file" data="conference/conf-has_left.wav"/>
|
||||
</match>
|
||||
</input>
|
||||
</macro>
|
||||
|
||||
<macro name="enter_dest_number">
|
||||
<input pattern="^(.*)$">
|
||||
<match>
|
||||
|
14
configure.in
14
configure.in
@ -428,7 +428,7 @@ case "$host" in
|
||||
fi
|
||||
;;
|
||||
*-solaris2*)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -DPATH_MAX=2048)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -DPATH_MAX=2048 -D__EXTENSIONS__)
|
||||
APR_ADDTO(SWITCH_AM_LDFLAGS, -lsendfile -lresolv -lsocket -lnsl -luuid)
|
||||
APR_ADDTO(ESL_LDFLAGS, -lnsl -lsocket)
|
||||
;;
|
||||
@ -474,7 +474,7 @@ AC_PROG_GCC_TRADITIONAL
|
||||
AC_FUNC_MALLOC
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_STRFTIME
|
||||
AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create])
|
||||
AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create getdtablesize])
|
||||
AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
|
||||
AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
|
||||
|
||||
@ -871,7 +871,7 @@ then
|
||||
if test "$python_has_distutils" != "no" ; then
|
||||
AC_MSG_CHECKING([location of site-packages])
|
||||
|
||||
PYTHON_SITE_DIR="`$PYTHON -c 'from distutils import sysconfig; print sysconfig.get_python_lib(0);'`"
|
||||
PYTHON_SITE_DIR="`$PYTHON -c 'from distutils import sysconfig; print(sysconfig.get_python_lib(0));'`"
|
||||
|
||||
if test -z "$PYTHON_SITE_DIR" ; then
|
||||
AC_MSG_ERROR([Unable to detect python site-packages path])
|
||||
@ -884,10 +884,10 @@ then
|
||||
#
|
||||
# python distutils found, get settings from python directly
|
||||
#
|
||||
PYTHON_CFLAGS="`$PYTHON -c 'from distutils import sysconfig; flags = [[\"-I\" + sysconfig.get_python_inc(0), \"-I\" + sysconfig.get_python_inc(1), \" \".join(sysconfig.get_config_var(\"CFLAGS\").split())]]; print \" \".join(flags);'`"
|
||||
PYTHON_LDFLAGS="`$PYTHON -c 'from distutils import sysconfig; libs = sysconfig.get_config_var(\"LIBS\").split() + sysconfig.get_config_var(\"SYSLIBS\").split(); libs.append(\"-lpython\"+sysconfig.get_config_var(\"VERSION\")); print \" \".join(libs);'`"
|
||||
PYTHON_LIB="`$PYTHON -c 'from distutils import sysconfig; print \"python\" + sysconfig.get_config_var(\"VERSION\");'`"
|
||||
PYTHON_LIBDIR="`$PYTHON -c 'from distutils import sysconfig; print sysconfig.get_config_var(\"LIBDIR\");'`"
|
||||
PYTHON_CFLAGS="`$PYTHON -c 'from distutils import sysconfig; flags = [[\"-I\" + sysconfig.get_python_inc(0), \"-I\" + sysconfig.get_python_inc(1), \" \".join(sysconfig.get_config_var(\"CFLAGS\").split())]]; print(\" \".join(flags));'`"
|
||||
PYTHON_LDFLAGS="`$PYTHON -c 'from distutils import sysconfig; libs = sysconfig.get_config_var(\"LIBS\").split() + sysconfig.get_config_var(\"SYSLIBS\").split(); libs.append(\"-lpython\"+sysconfig.get_config_var(\"VERSION\")); print(\" \".join(libs));'`"
|
||||
PYTHON_LIB="`$PYTHON -c 'from distutils import sysconfig; print(\"python\" + sysconfig.get_config_var(\"VERSION\"));'`"
|
||||
PYTHON_LIBDIR="`$PYTHON -c 'from distutils import sysconfig; print(sysconfig.get_config_var(\"LIBDIR\"));'`"
|
||||
|
||||
# handle python being installed into /usr/local
|
||||
AC_MSG_CHECKING([python libdir])
|
||||
|
110
docs/ChangeLog
110
docs/ChangeLog
@ -26,6 +26,10 @@ freeswitch (1.0.7)
|
||||
build: add support for bz2 to getlibs (r:b61fc396)
|
||||
build: Bump callie sounds to 1.0.15 (r:c8eaef60)
|
||||
build: always use our includes first so we use our srcdir headers over installed versions (r:15c79424)
|
||||
build: pocketsphinx build for 0.7 windows vs2008 (r:a7613c06/FS-3348)
|
||||
build: They no longer ship the wsj model in pocketsphinx... and seems the dictionary has moved a bit. (r:23571680)
|
||||
build: unimrcp vs2010 build fixes for new version (r:2dcca5f4)
|
||||
build: add sqlite to clean on make current or update-clean (r:2366f429)
|
||||
codec2: working prototype, still for testing only (r:04ca0751)
|
||||
config: move limit.conf to db.conf
|
||||
config: Update VM phrase macros to voice option then action on main, config menus
|
||||
@ -279,10 +283,38 @@ freeswitch (1.0.7)
|
||||
core: Add the ability to issue a break to switch_ivr_sleep when media is not ready, allowing continuation of processing of the dialplan. (r:dfc30b2e/FS-3373)
|
||||
core: parse events and messages in channel_ready (r:94148095)
|
||||
core: add last_hold_time and hold_accum vars for cdr data (r:676ef808)
|
||||
core: avoid recursion loop in parse_all_events vs channel_ready (r:22d89943)
|
||||
core: auto populate global origination_caller_id_name/number from effective_caller_id_name/number in enterprise originate (r:f8c029a1)
|
||||
core: add --enable-timerfd-wrapper to wrap timefd syscalls for platforms with the right kernel and wrong libc (r:306b332d)
|
||||
core: don't parse events in channel_ready during hold (r:cad68d53)
|
||||
core: only parse messages from channel_ready when its a session calling channel ready on itself not when another thread calls it (r:1d12519d)
|
||||
core: Fix single quote stripping and add %y to turn ' into \' (r:3b5a0ae5/FS-3359)
|
||||
core: push out signal data into its own queue system (r:f1ee225c)
|
||||
core: When in a dialplan hunt and we have a custom caller_profile, ${destination_number} and other variable kept the previous value of the original dialplan parsing. This correct this so it take the custom created caller_profile for that hunt (r:b0e0dd22)
|
||||
core: pause traffic if sql_queue gets to big (r:2939262e)
|
||||
core: fix detection of tones in monitor_early_media_fail (r:3cbae3fb/FS-3413)
|
||||
core: use rwlock for global vars to reduce contention (r:0521886d)
|
||||
core: Fix separate_string_blank_delim to handle strings with '&' (r:f3a42258/FS-3099)
|
||||
core: Fix setting display on wrong channel on eavesdrop (r:3dc4b530)
|
||||
core: add new detailed_calls view a version of the channels table that shows only one legged calls or bridged calls (r:beecd937)
|
||||
core: display update on flip_cid (r:0fc8050c)
|
||||
core: make sql stmt more portable (r:6b948cf1)
|
||||
core: print ip:port on rtp bind err (r:11d2cd1b)
|
||||
core: display fixes and add 2 new cols to channels to store last sent display data (r:d364e9f2)
|
||||
core: sanitize outbound caller id number on one-legged calls (r:dee0f540/FS-3483)
|
||||
core: clean up originator/ee profile so the right one is prevelant in events (r:3e2c662a)
|
||||
core: check for answer flag in bridge to do display update properly (r:0f459d4b)
|
||||
core: add event subclasses in switch_event.c (r:3696ced7/FS-3497)
|
||||
core: add max_sessions to heartbeat event (r:9c8437a1/FS-3415)
|
||||
core: fix event firing for CHANNEL_PROGRESS_MEDIA event (r:e2a4fb11/FS-3396)
|
||||
core: add emulation for asterisk DIALSTATUS magic var (r:9d98d49f)
|
||||
core: the new code requires accurate timestamps, we were incrementing it by the interval (20) instead of the samples (160) (r:f10566af/FS-3181)
|
||||
docs: Major clean up of doxygen generated core API documentation (r:794246e1)
|
||||
docs: Add libteletone back to core API documentation (r:c35c138d)
|
||||
embedded languages: Provide core level support for conditional Set Global Variable (r:c017c24b/FSCORE-612)
|
||||
embedded languages: add insertFile front end to switch_ivr_insert_file and reswig (r:c4e350ab)
|
||||
flex client: check in basic flex demo as basis to develop a client application (r:25be760b)
|
||||
flex client: the hotkeys js is broken, get rid of it (r:2f6f71d4)
|
||||
fs_cli: block control-z from fs cli and print a warning how to exit properly (r:dc436b82)
|
||||
fs_cli: skip blocking writes on fs_cli to avoid backing up event socket (r:2ec2a9b0)
|
||||
fs_cli: let ctl-c work until you are connected (r:986f258d)
|
||||
@ -294,6 +326,7 @@ freeswitch (1.0.7)
|
||||
libdingaling: fix race on shutdown causing crash (FSMOD-47)
|
||||
libdingaling: Fix crash in new GV interface when exceeding 24 calls (r:be00609a/FS-2171)
|
||||
libdingaling: fix crash when GV call ends (r:687140b5/FS-3139)
|
||||
libdingaling: fix small leak (r:d3ea42d8/FS-3334)
|
||||
libesl: Fix potential race condition (ESL-36)
|
||||
libesl: Add /uuid command to fs_cli to filter logs by uuid
|
||||
libesl: Increase buffer in fs_cli for Win (r:d1d6be88/FSCORE-611)
|
||||
@ -324,6 +357,7 @@ freeswitch (1.0.7)
|
||||
libesl: use poll instead of select in ESL client lib because select is not your friend.... (r:ae595cd5)
|
||||
libesl: Add digit_timeout to ESL::IVR's playAndGetDigits method (r:f564d383)
|
||||
libesl: add array manipulation to the wraper code (r:ffa0a071)
|
||||
libesl: fix mem leak - good catch, Jlenk! (r:e420e17f/FS-3386)
|
||||
libfreetdm: implemented freetdm config nodes and ss7 initial configuration
|
||||
libfreetdm: fix codec for CAS signaling (r:b76e7f18)
|
||||
libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c)
|
||||
@ -342,6 +376,11 @@ freeswitch (1.0.7)
|
||||
libsofiasip: fix bad assert (r:56404641/FS-3133)
|
||||
libsofiasip: lower stack and boost priority of sofia schedule thread (r:257bc9ff)
|
||||
libsofiasip: Fix for issue reported on the mailing list with a Chinese locale and windows. This commit removes a hidden char that should not have been there anyway. (r:7adaceb8)
|
||||
libsofiasip: resolve edge case in the 3rd party sofia sip stack library when dealing with a malformed contact and missing ack. Will push upstream to sofia devs (r:d68605f5/FS-3394)
|
||||
libsofiasip: use individual pools instead of sub-pools for nua handles to avoid pool swell (r:f7612413)
|
||||
libsofiasip: Fix segfault in sofia's stun code (r:7403db70)
|
||||
libsofiasip: add homer capture hooks to libsofia (r:3e029f0d)
|
||||
libsofiasip: Fix mem leak when homer capture server not available (r:bc177a4b/FS-3475)
|
||||
libspandsp: Fixed a typo in spandsp's msvc/inttypes.h Updated sig_tone processing in spandsp to the latest, to allow moy to proceed with his signaling work.
|
||||
libspandsp: removed a saturate16 from spandsp that was causing problems fixed a typo in the MSVC inttypes.h file for spandsp
|
||||
libspandsp: Changes to the signaling tone detector to detect concurrent 2400Hz + 2600Hz tones. This passes voice immunity and other key tests, but it bounces a bit when transitions like 2400 -> 2400+2600 -> 2600 occur. Transitions between tone off and tone on are clean. (r:bc13e944)
|
||||
@ -351,9 +390,15 @@ freeswitch (1.0.7)
|
||||
libspandsp: Added missing error codes when an ECM FAX is abandoned with the T30_ERR message (r:ec57dc7a)
|
||||
libspandsp: Fixed a vulnerability in T.4 and T.6 processing which is similar to http://bugzilla.maptools.org/show_bug.cgi?id=2297 in libtiff. A really screwed up 2D T.4 image, or a maliciously constructed T.4 2D or T.6 image should potential run off the end of an image decoder buffer. (r:c6f67322)
|
||||
libspandsp: Changed T.38 terminal handling, so errors from the user's packet transmit routine properly filter up the chain, cause termination of the FAX session, and are reported to the caller. (r:c890fbfa)
|
||||
libspandsp: Numerous little changes to spandsp that haven't been pushed to Freeswitch for a while. The only big changes are a majorly rewritten V.42 and V.42bis which are now basically functional. (r:d30e82e2)
|
||||
libspandsp: Another round of tweaks for spandsp. There should be no functional changes, although quite a few things have changed in the test suite (r:4a7bbf4e)
|
||||
libstfu: add param to jb to try to recapture latency (disabled by default) (r:d59d41d7)
|
||||
libsqlite: fix issue on mailing list mod_crd_sqlite entry limit and sqlite segfaults on triggers (r:1badec17)
|
||||
libsqlite: make strdup NULL return strdup("") in sqlite for mac bug (r:b6bed14f)
|
||||
libsqlite: force an update on sqlite build (r:71dd3ca8)
|
||||
libunimrcp: Update to latest UniMRCP version. MRCP requests can no timeout if there is no server response. (r:17099473)
|
||||
libunimrcp: unimrcp lib does not notify mod_unimrcp of RTSP TEARDOWN timeouts (r:3484f338)
|
||||
libunimrcp: fixed unimrcp to prevent double destroy of connection (r:493085bb)
|
||||
mod_avmd: Initial check in - Advanced Voicemail Detect (r:10c6a30a) (by Eric Des Courtis)
|
||||
mod_avmd: Add to windows build (r:df4bd935)
|
||||
mod_avmd: Fix mem leak (r:cd951384/FS-2839)
|
||||
@ -425,6 +470,9 @@ freeswitch (1.0.7)
|
||||
mod_commands: add moh by default to uuid_broadcast when only broadcasting to A leg use aleg arg to disable this (r:d164a797)
|
||||
mod_commands: add API uuid_limit - thanks to Francois Delawarde (r:98a95016/FS-1792)
|
||||
mod_commands: omit file_string:// prefix if input begins with ~ (r:f12ab59e)
|
||||
mod_commands: fix crash when uuid_break all cannot find bonded uuid channel (r:69e61f76/FS-3468)
|
||||
mod_commands: fix uuid_dual_transfer for inline dialplan (r:5d84efc3/FS-3403)
|
||||
mod_commands: update show calls to show both 1 legged calls and bridged calls, also show bridged_calls for previous behaviour of show calls (r:c16c74d9)
|
||||
mod_conference: Fix reporting of volume up/down (MODAPP-419)
|
||||
mod_conference: add last talking time per member to conference xml list
|
||||
mod_conference: add terminate-on-silence conference param
|
||||
@ -465,6 +513,7 @@ freeswitch (1.0.7)
|
||||
mod_conference: wait for thread to start in mod conference to avoid one in a million race on heavy traffic (r:b1cf5bee)
|
||||
mod_conference: add conference member flag nomoh (r:f35a6814)
|
||||
mod_conference: add hup command to conference (kick without the kick sound) (r:492db906)
|
||||
mod_conference: see H.264 iFrames (r:765be8c9/FS-3406)
|
||||
mod_curl: use method=post when post requested (r:c6a4ddd0/FSMOD-69)
|
||||
mod_db: fix stack corruption (MODAPP-407)
|
||||
mod_dialplan_xml: Add in the INFO log the caller id number when processing a request (Currenly only show the caller name) (r:e1df5e13)
|
||||
@ -475,7 +524,9 @@ freeswitch (1.0.7)
|
||||
mod_dingaling: fix leak in chat_send (r:eb109a85)
|
||||
mod_dingaling: use the login as message source when not in component mode. (chat_send) (r:58c28aab)
|
||||
mod_dingaling: fix mod_dingaling/iksemel/gnutls link error when using newer autotools (r:294b0779/FS-3182)
|
||||
mod_dingaling: fix segmentation fault on mod_dingaling when receiving a discovery from the server (r:2e651c8f/FS-3391)
|
||||
mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f)
|
||||
mod_directory: let mod_directory use non-XML dialplans (r:8895de1b)
|
||||
mod_distributor: Add mod_distributor to VS2010 - not built by default (r:bac79ba1)
|
||||
mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012)
|
||||
mod_dptools: Make park app not send 183 session progress (r:76932995/FSCORE-567)
|
||||
@ -493,6 +544,11 @@ freeswitch (1.0.7)
|
||||
mod_dptools: Set the default lang if not supplied (mod_say_en) (r:5382972a/FS-3215)
|
||||
mod_dptools: add capture dp app (r:860d2a6c)
|
||||
mod_dptools: Allow redefinition of continue_on_fail and failure_causes during bridge execution. (r:01d0250e/FS-1986)
|
||||
mod_dptools: Fix "dial 0" 3-way call on att x-fer (r:d4fe85ed/FS-3275)
|
||||
mod_dptools: fix campon to play music even on first run and cancel faster (r:9cf44f3a)
|
||||
mod_dptools: fix small leak in strftime (r:bbbd67ba)
|
||||
mod_dptools: resolve Heap corruption in strftime_api_function -thanks (r:707bd05b/FS-3417)
|
||||
mod_dptools: fix seg on user_recurse_variables reported on the mailing list (r:01b2bd04)
|
||||
mod_easyroute: Fix possible segfaults and memory leak during unload, and add new setting odbc-retries (r:7fbc47f8/FS-2973)
|
||||
mod_enum: switch mod_enum to use new portable in-tree version (r:2bbc37e3)
|
||||
mod_enum: fix race condition between ldns configure creating ldns/util.h and mod_enum (r:87884c5c)
|
||||
@ -506,6 +562,7 @@ freeswitch (1.0.7)
|
||||
mod_erlang_event: Rewrite XML fetch conditional wait to be more sane (Reported by James Aimonetti) (r:6941c6eb/FS-2775)
|
||||
mod_erlang_event: Don't urlencode events (and destroy an event after use) (r:4eccdfef)
|
||||
mod_erlang_event Add proper locking for the list of XML bindings (r:9fe440b2)
|
||||
mod_event_multicast: make multicast loopback configurable (r:97a7668c/FS-3416)
|
||||
mod_event_socket: fix up other users of switch_event_xmlize() to use SWITCH_EVENT_NONE (r:d6eb7562)
|
||||
mod_event_socket: Fix small mem leaks (r:e4f90584/MODEVENT-68)
|
||||
mod_event_socket: Add "-ERR" to api cmd response when failure occurs (r:58759052/FS-2827)
|
||||
@ -526,6 +583,7 @@ freeswitch (1.0.7)
|
||||
mod_fifo: Fix crash when using fifo_destroy_after_use (r:ee562c82/FS-2879)
|
||||
mod_fifo: don't seg in edge case error conditions (r:9ee13b72)
|
||||
mod_fifo: set tracking data before enabling hooks (r:34267869)
|
||||
mod_fifo: Fix fifo orbit timeout when not using a chime tested with and without chime (r:7fee1fd1)
|
||||
mod_file_string: Fix segfault when using file string in conference (r:9c40e8e9/FS-3122)
|
||||
mod_freetdm: Fix for TON and NPI not passed through to channel variables on incoming calls
|
||||
mod_freetdm: add pvt data to freetdm channels fix fxs features (r:9d456900)
|
||||
@ -596,6 +654,7 @@ freeswitch (1.0.7)
|
||||
mod_khomp: Removed alternative contexts / extensions - New struct for matchs - On calls originated from an FXS branch, the Endpoint searches for a valid extension (digits sent) after the DTMF '#' or after the timeout (option fxs-digit-timeout). That search is done in the context defined in section <fxs-options>, or if no context configured, the search is done in context defined in context-fxs. - Added "dialplan" configuration: Name of the dialplan module in use (default XML) - Group context enabled. If set, the search for a valid extension is done only in that context. - Updated documentation (r:1ef3fc9a)
|
||||
mod_ladspa: Add mod_ladspa (Audio plugin framework for linux) (r:2d3d8f8d)
|
||||
mod_ladspa: add string params to ladspa so you can connect files to audio ports (string params don't count towards number params) (r:b7891511)
|
||||
mod_ladspa: putenv() breaks the process environment variables, use setenv() instead. (r:f6dadb58)
|
||||
mod_lcr: Expand variables (MODAPP-418)
|
||||
mod_lcr: add enable_sip_redir parameter (r:70bf7a0a/MODAPP-427)
|
||||
mod_lcr: don't validate profiles with ${} vars since they are dynamic and we can't guess what the proper value should be (r:af33afaa)
|
||||
@ -607,6 +666,7 @@ freeswitch (1.0.7)
|
||||
mod_lcr: don't add routes that have no rate of the desired type (r:82e3ccf8)
|
||||
mod_lcr: fix "as xml" for larger number of arguments (r:3dca2ebb/FS-3283)
|
||||
mod_lcr: fix malformed XML when has embedded %s (r:5fa9619f/FS-3284)
|
||||
mod_lcr: initial addition of very basic LRN (r:6d1d4a9c)
|
||||
mod_loopback: add loopback_bowout_on_execute var to make 1 legged loopback calls bow out of the picture
|
||||
mod_loopback: only execute app once in app mode (r:64f58f2d)
|
||||
mod_loopback: fix bug in mod_loopback where bowout=false (r:e9ab5368)
|
||||
@ -614,6 +674,7 @@ freeswitch (1.0.7)
|
||||
mod_loopback: fix voicemail failure (r:1a1881e8/FS-2795)
|
||||
mod_loopback: pass ring_ready like we do with pre_answer (r:9d087d45)
|
||||
mod_loopback: refactor mod_loopback timeout handling (r:43442e4f)
|
||||
mod_loopback: Fix loopback_bowout_on_execute failure when doing txfax calls (r:895b505f/FS-3494)
|
||||
mod_lua: Add switch_core_sqldb functionality from inside Lua script (r:26f2e095/FS-1384)
|
||||
mod_lua: Made 2nd arg to freeswitch.Dbh:query (cb func) optional (r:87db11af)
|
||||
mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0)
|
||||
@ -625,7 +686,9 @@ freeswitch (1.0.7)
|
||||
mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165)
|
||||
mod_managed: add additional support (r:5be58aac)
|
||||
mod_managed: add mono 2.8 patch file see FS-2774 (r:6a948bd9/FS-2774)
|
||||
mod_managed: resolve Memory leak in mod_managed by EventBinding and swig delete_switch_event (r:c6048134/FS-3381)
|
||||
mod_mongo: New mod, initial commit; module for MongoDB (http://www.mongodb.org/) (r:dc6ca6f8/FS-3278)
|
||||
mod_mongo: add mapreduce API (r:7c5b5797/FS-3357)
|
||||
mod_mp4v: MP4V-ES passthru for washibechi on IRC
|
||||
mod_mp4: New module. Supports playback of MP4 files. Depends on libmp4v2 <http://code.google.com/p/mp4v2/> (originally compiled against v1.6.1)
|
||||
mod_nibblebill: free allocated mem at shutdown; free properly if using custom_sql
|
||||
@ -648,6 +711,9 @@ freeswitch (1.0.7)
|
||||
mod_portaudio: Fix inbound state (CS_ROUTING not CS_INIT) (MODENDP-302)
|
||||
mod_portaudio: mod_portaudio improvements and bug fixes (r:33b74ca8/FS-3006)
|
||||
mod_portaudio: Add pa devlist to portaudio webapi (r:e8f10ea3)
|
||||
mod_portaudio: fix crash on bad init (r:6f49e6ba/FS-3361)
|
||||
mod_portaudio: move load_config a bit lower since it needs to use the hashtables (r:1529c0ec)
|
||||
mod_portaudio: Fix Windows crash (r:94c9cbf6/FS-3498)
|
||||
mod_portaudio_stream: update to specify the channel index (r:d1169d6e)
|
||||
mod_protovm: This is a very early new prototype voicemail ivr system. You need to copy the sounds.xml and make it loadale in the language folder and protovm.conf.xml inside the autoload_configs folder. Configs file will most definitly change. Once stabilized, we make it install those file by default. (r:fb549777)
|
||||
mod_radius_cdr: Add 'Freeswitch-Direction' av pair (r:a5170df0)
|
||||
@ -658,6 +724,14 @@ freeswitch (1.0.7)
|
||||
mod_rtmp: Make all sockets non-blocking (r:affcdb0a)
|
||||
mod_rtmp: mod_rtmp for windows (r:f8cda539/FS-3355)
|
||||
mod_rtmp: flush buffer to avoid lag and enable plc (r:4bb76831)
|
||||
mod_rtmp: add conf (r:4eaabd28)
|
||||
mod_rtmp: set variables based on input hash (r:3815d188)
|
||||
mod_rtmp: Remove duplicate output from rtmp status profile xxx API command (r:2e016541)
|
||||
mod_rtmp: Make all sockets non-blocking (r:affcdb0a)
|
||||
mod_rtmp: Lower default buffer size to 50ms (r:d52a254d)
|
||||
mod_rtmp: CNG frames need to have codec set too (r:36f812d9)
|
||||
mod_rtmp: remove superfluous hangup (r:50817655)
|
||||
mod_rtmp: fix crash when call made from user not in domain (r:a5452174/FS-3353)
|
||||
mod_sangoma_codec: Add sample config file
|
||||
mod_sangoma_codec: added load/noload options for the supported codecs
|
||||
mod_sangoma_codec: rename load/noload to register/noregister
|
||||
@ -685,6 +759,7 @@ freeswitch (1.0.7)
|
||||
mod_shell_stream: Fix defunct processes being left behind (r:89666f44/FS-3316)
|
||||
mod_shout: bump mod_shout to use mpg123-1.13.2 to hopefully address unwanted calls to exit() and inherit other upstream fixes (r:079f3f73)
|
||||
mod_shout: add append flag to mod_shout, can append MP3's (r:0419c4e0)
|
||||
mod_shout: add ability to set bitrate, samplerate, and encoder quality in config file (r:8ea3cbd5/FS-1231)
|
||||
mod_silk: Fix mod_silk compliance and performance issues (r:2ddbc457/MODCODEC-20)
|
||||
mod_skinny: Add the missing api files
|
||||
mod_skinny: add example dialplan and directory config (r:1bfcc17e)
|
||||
@ -714,6 +789,9 @@ freeswitch (1.0.7)
|
||||
mod_skypopen: deleted osscuse subdir (r:4842a620)
|
||||
mod_skypopen: adding installer and Skype client configuration directories (to be announced :) ) (r:25ebf715)
|
||||
mod_skypopen: refining INTERACTIVE INSTALLER for Linux (to be announced :) ) (r:aa7f47ac)
|
||||
mod_skypopen: refining oss driver, removing audio sync during call (was each 20 secs), audio sync at the tcp interfacing with the skype client (reading more than 20ms worth) (r:891015e6)
|
||||
mod_skypopen: fixed a demented bug (incrementing a variable zeroed in the same loop) maybe responsible for moh sputtering under load on virtual machines (r:43eeeb82)
|
||||
mod_skypopen: avoid accumulating delay on VMs, better debug logging (r:1b4c78bf)
|
||||
mod_snapshot: fix bad codepaths in mod_snapshot (r:844ac220)
|
||||
mod_sndfile: Add support for .alaw and .ulaw to mod_sndfile (r:facf09b8/MODFORM-41)
|
||||
mod_sndfile: return break in mod_sndfile when seek returns failure (r:564dc7e4)
|
||||
@ -897,6 +975,31 @@ freeswitch (1.0.7)
|
||||
mod_sofia: removed the vid refresh thing (r:49e52b4c/FS-3362)
|
||||
mod_sofia: add sip_liberal_dtmf chanvar and liberal-dtmf profile param to use the maximum methods of DTMF avoiding sticking to the spec which leads to incompatability (r:bc7cb400)
|
||||
mod_sofia: support final response in response header passing (r:acd0898e)
|
||||
mod_sofia: Fix failure to fall back to g.711 when t.38 attempt fails (r:07a79752/FS-3214)
|
||||
mod_sofia: pop ::<profile_name> off the domain name in mwi events to hint at the profile (r:e2ed8c08)
|
||||
mod_sofia: dig into the database to figure out what profile to send mwi on when they are not willing to alais the domain to the profile =/ (r:b14340a5)
|
||||
mod_sofia: Fix 3pcc codec negotiation issue with bypass_media (r:c5a2275f/FS-3340)
|
||||
mod_sofia: re-add not-so-superfluous-after-all NUTAG_AUTOANSWER(0) (r:927fde18/FS-3349)
|
||||
mod_sofia: add mutex around gateway access on per-profile basis and token based access to global profiles to prevent hanging on to the hash mutex while doing sql stmts which may cause issues/slowdowns (r:9df8169d)
|
||||
mod_sofia: add parallelism to sofia by offsetting sip messages to the concerned sessions and using multiple queue threads for message handling (r:fb68746e)
|
||||
mod_sofia: Fix sofia hang on shutdown (r:3be64cbf/FS-3354)
|
||||
mod_sofia: remove vid refresh from SDP on declined video connection (r:49e52b4c/FS-3362)
|
||||
mod_sofia: fix small mem leak in sofia (r:6f62f391/FS-3386)
|
||||
mod_sofia: add proxy tag to UPDATE packets if it was set by INVITE (r:e6605139)
|
||||
mod_sofia: resolve attended transfers, it fails to parse the Replaces when encoded (r:d9bbf129/FS-3304)
|
||||
mod_sofia: if user has set presence_id, don't override it (r:7cdc8342)
|
||||
mod_sofia: only list real profiles not aliases in presence code (r:f9969f38)
|
||||
mod_sofia: Fix 200 OK not passed for Callee-Initiated ReInvite for T.38 (r:b2299035/FS-3421)
|
||||
mod_sofia: destroy nh if SIP transaction terminated by a 488 (r:a0cec8ab/FS-3444)
|
||||
mod_sofia: use register contact to determine proper contact in 200 ok response to register (r:f9612fec)
|
||||
mod_sofia: add NDLB-allow-nondup-sdp to indicate you want to parse a differnt sdp in 200 ok from 1xx (previous default) this is a RFC violation so I decided not to support it by default anymore. Enable this if you want that broken behaviour (r:3f489a2a)
|
||||
mod_sofia: add homer capture hooks to mod_sofia (r:98473085)
|
||||
mod_sofia: sdp_m_per_ptime is now implied to be true, if you don't like this set it to false but its going to be undefined behaviour. This basically means if you call in with ptime 30 then you have a bunch of ptime 20 codecs in your outbound list that there will be one m= line with 30 and the original inbound codec and more m= lines for each discinct ptime in your list. This is, of course, will depend on disable_trancoding or absolute_codec_string as well (r:56d67ead)
|
||||
mod_sofia: filter re-transmission of extra SIP headers (r:9e399c19/FS-3439)
|
||||
mod_sofia: Fix RTP handling bug to allow goofy & undefined behavior (r:77413ba9/FS-3451)
|
||||
mod_sofia: don't allow auto answer on an non-outbound call (r:61ee7fdc)
|
||||
mod_sofia: use the call_id of the original register in the unsolicited notify for MWI (r:53b0ecce)
|
||||
mod_soundtouch: updated soundtouch to library 1.5.0 to fix gcc > 4.3 incompatibilities (r:dfb5c629)
|
||||
mod_spandsp: initial checkin of mod_fax/mod_voipcodecs merge into mod_spandsp (r:fa9a59a8)
|
||||
mod_spandsp: rework of new mod_spandsp to have functions broken up into different c files (r:65400642)
|
||||
mod_spandsp: improve duplicate digit detection and add 'min_dup_digit_spacing_ms' channel variable for use with the dtmf detector (r:eab4f246/FSMOD-45)
|
||||
@ -916,6 +1019,8 @@ freeswitch (1.0.7)
|
||||
mod_spandsp: add more fax event information (r:0555b702/FS-3345)
|
||||
mod_spandsp: fix memory issue in spandsp_tone_detect (r:8793c2ed)
|
||||
mod_spandsp: add proper tone detect stop (r:8beb10d2/FS-3367)
|
||||
mod_spandsp: add more fax event information (r:0555b702/FS-3345)
|
||||
mod_spandsp: fix memory issue in spandsp_tone_detect (r:8793c2ed)
|
||||
mod_spidermonkey: allow vars to be set containing vars from languages (r:5cd072a3)
|
||||
mod_spidermonkey: fix seg in js hangup (r:7d554c11)
|
||||
mod_spidermonkey: Fix mod_spidermonkey build on FreeBSD, (Undefined symbol PR_LocalTimeParameters). (r:3edb8419)
|
||||
@ -935,6 +1040,7 @@ freeswitch (1.0.7)
|
||||
mod_valet_parking: add event for Valet Parking action exit
|
||||
mod_valet_parking: pass hold class on transfer (r:76a065ec)
|
||||
mod_valet_parking: add valet_announce_slot variable (r:293d7254)
|
||||
mod_valet_parking: make valet parking reserve a space for 10 seconds to allow time for an attended transfer switcharoo (r:308f44af)
|
||||
mod_voicemail: Fix vm_prefs profile lock (MODAPP-417)
|
||||
mod_voicemail: add 'vm-enabled' param (default true)
|
||||
mod_voicemail: fix vm msg being deleted when pressing key to forward to email (MODAPP-403)
|
||||
@ -952,6 +1058,10 @@ freeswitch (1.0.7)
|
||||
mod_voicemail: vm-skip-instructions param in xml directory to disable instructions how to record a file (r:ed7e1f39)
|
||||
mod_voicemail: Implement 10 new standard api function call that allow you to control fs voicemail storage system. The goal is to have a standard API set for any additional storage system we wish the voicemail to run off. Current list of added api name are : vm_fsdb_msg_count, vm_fsdb_msg_list, vm_fsdb_msg_get, vm_fsdb_msg_delete, vm_fsdb_msg_undelete, vm_fsdb_msg_purge, vm_fsdb_msg_save, vm_fsdb_pref_greeting_set, vm_fsdb_pref_recname_set, vm_fsdb_pref_password_set. (r:1f4cb488)
|
||||
mod_voicemail: Adding a new voicemail fsdb api vm_fsdb_auth_login that does basic login authentication for a user (r:bfdfac5e)
|
||||
mod_voicemail: Fix vm to email dial 8 option (r:8592b6d9/FS-3382)
|
||||
mod_voicemail: Add 2 new profile settings, db-password-override and allow-empty-password-auth. By default, they have value of their previous behavior. If db-password-override=true, the db password will only be used if present, if not present fallback to the xml config file vm-password. If allow-empty-password-auth=false, it will disable login via a authentication method if there is no password set in the user account (This wont affect voicemail_authorize=true login). (r:a9db642a)
|
||||
mod_voicemail: remove pointless update_mwi() in vm_list api command (r:b952b2b2)
|
||||
mod_voicemail: add message_len to output of vm_list api command (r:77c5000d)
|
||||
mod_xml_cdr: add force_process_cdr var to process b leg cdr on a case by case basis when b leg cdr is disabled (XML-17)
|
||||
mod_xml_cdr: add leg param to query string (XML-24)
|
||||
mod_xml_cdr: fix locked sessions (XML-26)
|
||||
|
@ -5,23 +5,23 @@
|
||||
<prompt phrase="Pound" filename="35.wav"/>
|
||||
<prompt phrase="Star" filename="42.wav"/>
|
||||
<prompt phrase="Dot" filename="46.wav"/>
|
||||
<prompt phrase="Hyphen" filename="45.wav"/>
|
||||
<prompt phrase="Exclamation point" filename="33.wav"/>
|
||||
<prompt phrase="At" filename="64.wav"/>
|
||||
<prompt phrase="Dollar sign" filename="36.wav"/>
|
||||
<prompt phrase="Percent" filename="37.wav"/>
|
||||
<prompt phrase="Ampersand" filename="38.wav"/>
|
||||
<prompt phrase="Double quote" filename="34.wav"/>
|
||||
<prompt phrase="Single quote" filename="39.wav"/>
|
||||
<prompt phrase="Forward slash" filename="47.wav"/>
|
||||
<prompt phrase="Underscore" filename="95.wav"/>
|
||||
<prompt phrase="Backslash" filename="92.wav"/>
|
||||
<prompt phrase="Tilde" filename="126.wav"/>
|
||||
<prompt phrase="Equal sign" filename="61.wav"/>
|
||||
<prompt phrase="Colon" filename="58.wav"/>
|
||||
<prompt phrase="Semicolon" filename="59.wav"/>
|
||||
<prompt phrase="Caret" filename="94.wav"/>
|
||||
<prompt phrase="Pipe" filename="124.wav"/>
|
||||
<prompt phrase="Hyphen" filename="45.wav"/>
|
||||
<prompt phrase="Exclamation point" filename="33.wav"/>
|
||||
<prompt phrase="At" filename="64.wav"/>
|
||||
<prompt phrase="Dollar sign" filename="36.wav"/>
|
||||
<prompt phrase="Percent" filename="37.wav"/>
|
||||
<prompt phrase="Ampersand" filename="38.wav"/>
|
||||
<prompt phrase="Double quote" filename="34.wav"/>
|
||||
<prompt phrase="Single quote" filename="39.wav"/>
|
||||
<prompt phrase="Forward slash" filename="47.wav"/>
|
||||
<prompt phrase="Underscore" filename="95.wav"/>
|
||||
<prompt phrase="Backslash" filename="92.wav"/>
|
||||
<prompt phrase="Tilde" filename="126.wav"/>
|
||||
<prompt phrase="Equal sign" filename="61.wav"/>
|
||||
<prompt phrase="Colon" filename="58.wav"/>
|
||||
<prompt phrase="Semicolon" filename="59.wav"/>
|
||||
<prompt phrase="Caret" filename="94.wav"/>
|
||||
<prompt phrase="Pipe" filename="124.wav"/>
|
||||
<prompt phrase="A" filename="97.wav"/>
|
||||
<prompt phrase="B" filename="98.wav"/>
|
||||
<prompt phrase="C" filename="99.wav"/>
|
||||
@ -239,30 +239,30 @@
|
||||
<prompt phrase="I need to record your first and last name. This recording is used throughout the system, including in the company directory." filename="vm-tutorial_record_name.wav"/>
|
||||
<prompt phrase="Your personal identification number, or 'pin', is used to prevent others from accessing your voicemail messages. Would you like to change it now?" filename="vm-tutorial_change_pin.wav"/>
|
||||
<prompt phrase="The person you are trying to reach is not available and does not have voicemail." filename="vm-not_available_no_voicemail.wav"/>
|
||||
<prompt phrase="The PIN you entered is below the minimum length." filename="voicemail/vm-pin_below_minimum_length.wav"/>
|
||||
<prompt phrase="The minimum PIN length is..." filename="voicemail/vm-minimum_pin_length_is.wav"/>
|
||||
<prompt phrase="The PIN you entered is below the minimum length." filename="voicemail/vm-pin_below_minimum_length.wav"/>
|
||||
<prompt phrase="The minimum PIN length is..." filename="voicemail/vm-minimum_pin_length_is.wav"/>
|
||||
</voicemail>
|
||||
<directory>
|
||||
<prompt phrase="Please enter the first few letters of the persons" filename="dir-enter_person.wav"/>
|
||||
<prompt phrase="...last name..." filename="dir-last_name.wav"/>
|
||||
<prompt phrase="To search by..." filename="dir-to_search_by.wav"/>
|
||||
<prompt phrase="...first name..." filename="dir-first_name.wav"/>
|
||||
<prompt phrase="There were no matching results." filename="dir-no_matching_results.wav"/>
|
||||
<prompt phrase="...results matched your search." filename="dir-result_match.wav"/>
|
||||
<prompt phrase="Your search returned too many results." filename="dir-too_many_result.wav"/>
|
||||
<prompt phrase="No more results." filename="dir-no_more_results.wav"/>
|
||||
<prompt phrase="Result number..." filename="dir-result_number.wav"/>
|
||||
<prompt phrase="...at extension..." filename="dir-at_extension.wav"/>
|
||||
<prompt phrase="To select this entry..." filename="dir-to_select_entry.wav"/>
|
||||
<prompt phrase="For the next entry..." filename="dir-for_next.wav"/>
|
||||
<prompt phrase="For the previous entry..." filename="dir-for_prev.wav"/>
|
||||
<prompt phrase="To start a new search..." filename="dir-start_new_search.wav"/>
|
||||
<prompt phrase="You need to specify a minimum of..." filename="dir-specify_mininum.wav"/>
|
||||
<prompt phrase="...letters of the person's name." filename="dir-letters_of_person_name.wav"/>
|
||||
<prompt phrase="Please try again." filename="dir-please_try_again.wav"/>
|
||||
<prompt phrase="press" filename="dir-press.wav" info="we can copy vm/vm-press.wav"/>
|
||||
<prompt phrase="Please enter the first few letters of the persons" filename="dir-enter_person.wav"/>
|
||||
<prompt phrase="...last name..." filename="dir-last_name.wav"/>
|
||||
<prompt phrase="To search by..." filename="dir-to_search_by.wav"/>
|
||||
<prompt phrase="...first name..." filename="dir-first_name.wav"/>
|
||||
<prompt phrase="There were no matching results." filename="dir-no_matching_results.wav"/>
|
||||
<prompt phrase="...results matched your search." filename="dir-result_match.wav"/>
|
||||
<prompt phrase="Your search returned too many results." filename="dir-too_many_result.wav"/>
|
||||
<prompt phrase="No more results." filename="dir-no_more_results.wav"/>
|
||||
<prompt phrase="Result number..." filename="dir-result_number.wav"/>
|
||||
<prompt phrase="...at extension..." filename="dir-at_extension.wav"/>
|
||||
<prompt phrase="To select this entry..." filename="dir-to_select_entry.wav"/>
|
||||
<prompt phrase="For the next entry..." filename="dir-for_next.wav"/>
|
||||
<prompt phrase="For the previous entry..." filename="dir-for_prev.wav"/>
|
||||
<prompt phrase="To start a new search..." filename="dir-start_new_search.wav"/>
|
||||
<prompt phrase="You need to specify a minimum of..." filename="dir-specify_mininum.wav"/>
|
||||
<prompt phrase="...letters of the person's name." filename="dir-letters_of_person_name.wav"/>
|
||||
<prompt phrase="Please try again." filename="dir-please_try_again.wav"/>
|
||||
<prompt phrase="press" filename="dir-press.wav" info="we can copy vm/vm-press.wav"/>
|
||||
<prompt phrase="For the next entry..." filename="dir-for_next.wav" note="re-recorded because original was wrong"/>
|
||||
<prompt phrase="Please enter the first few letters of the person's first or last name" filename="dir-enter_person_first_or_last.wav"/>
|
||||
<prompt phrase="Please enter the first few letters of the person's first or last name" filename="dir-enter_person_first_or_last.wav"/>
|
||||
</directory>
|
||||
<conference>
|
||||
<prompt phrase="NULL" filename="conf-ack.wav" type="tone"/>
|
||||
@ -287,14 +287,14 @@
|
||||
<prompt phrase="...has left the conference." filename="conf-has_left.wav"/>
|
||||
<prompt phrase="You are already muted." filename="conf-you_are_already_muted.wav"/>
|
||||
<prompt phrase="You are now bi-directionally muted." filename="conf-you_are_now_bidirectionally_muted.wav"/>
|
||||
<prompt phrase="Enter the number of listeners at this location, then press pound." filename="conf-number_of_listeners.wav"/>
|
||||
<prompt phrase="...listeners in this conference." filename="conf-listeners_in_conference.wav"/>
|
||||
<prompt phrase="...listener in this conference." filename="conf-listener_in_conference.wav"/>
|
||||
<prompt phrase="...members in this conference." filename="conf-members_in_conference.wav"/>
|
||||
<prompt phrase="This conference is in Q and A mode." filename="conference/conf-conference_is_in_qna_mode.wav"/>
|
||||
<prompt phrase="Q and A mode..." filename="conference/conf-qna_mode.wav"/>
|
||||
<prompt phrase="Entry sound..." filename="conference/conf-entry_sound.wav"/>
|
||||
<prompt phrase="Exit sound..." filename="conference/conf-exit_sound.wav"/>
|
||||
<prompt phrase="Enter the number of listeners at this location, then press pound." filename="conf-number_of_listeners.wav"/>
|
||||
<prompt phrase="...listeners in this conference." filename="conf-listeners_in_conference.wav"/>
|
||||
<prompt phrase="...listener in this conference." filename="conf-listener_in_conference.wav"/>
|
||||
<prompt phrase="...members in this conference." filename="conf-members_in_conference.wav"/>
|
||||
<prompt phrase="This conference is in Q and A mode." filename="conference/conf-conference_is_in_qna_mode.wav"/>
|
||||
<prompt phrase="Q and A mode..." filename="conference/conf-qna_mode.wav"/>
|
||||
<prompt phrase="Entry sound..." filename="conference/conf-entry_sound.wav"/>
|
||||
<prompt phrase="Exit sound..." filename="conference/conf-exit_sound.wav"/>
|
||||
</conference>
|
||||
<ivr>
|
||||
<prompt phrase="Account number" filename="ivr-account_number.wav"/>
|
||||
@ -398,21 +398,21 @@
|
||||
<prompt phrase="Thank you for calling. If you know your party's extension, please enter it now. For a directory, press..." filename="ivr-generic_greeting.wav"/>
|
||||
<prompt phrase="...file..." filename="ivr-file.wav"/>
|
||||
<prompt phrase="...files..." filename="ivr-files-.wav"/>
|
||||
<prompt phrase="For a wakeup call..." filename="ivr-for_a_wakeup_call.wav"/>
|
||||
<prompt phrase="This is your wakeup call." filename="ivr-this_is_your_wakeup_call.wav"/>
|
||||
<prompt phrase="To request a wakeup call..." filename="ivr-request_wakeup_call.wav"/>
|
||||
<prompt phrase="To confirm a wakeup call..." filename="ivr-confirm_wakeup_call.wav"/>
|
||||
<prompt phrase="To cancel a wakeup call..." filename="ivr-cancel_wakeup_call.wav"/>
|
||||
<prompt phrase="You have requested a wakeup call for..." filename="ivr-requested_wakeup_call_for.wav"/>
|
||||
<prompt phrase="You have not requested a wakeup call." filename="ivr-not_requested_wakeup_call.wav"/>
|
||||
<prompt phrase="Your wakeup call has been cancelled." filename="ivr-wakeup_call_cancelled.wav"/>
|
||||
<prompt phrase="For a daily wakeup call..." filename="ivr-for_daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Daily wakeup call..." filename="ivr-daily_wakeup_call.wav"/>
|
||||
<prompt phrase="For daily wakeup calls..." filename="ivr-for_daily_wakeup_calls.wav"/>
|
||||
<prompt phrase="For a one-time wakeup call..." filename="ivr-for_one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="One-time wakeup call..." filename="ivr-one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="...wakeup call..." filename="ivr-wakeup_call.wav"/>
|
||||
<prompt phrase="Wakey wakey sunshine!" filename="ivr-wakey_wakey_sunshine.wav"/>
|
||||
<prompt phrase="For a wakeup call..." filename="ivr-for_a_wakeup_call.wav"/>
|
||||
<prompt phrase="This is your wakeup call." filename="ivr-this_is_your_wakeup_call.wav"/>
|
||||
<prompt phrase="To request a wakeup call..." filename="ivr-request_wakeup_call.wav"/>
|
||||
<prompt phrase="To confirm a wakeup call..." filename="ivr-confirm_wakeup_call.wav"/>
|
||||
<prompt phrase="To cancel a wakeup call..." filename="ivr-cancel_wakeup_call.wav"/>
|
||||
<prompt phrase="You have requested a wakeup call for..." filename="ivr-requested_wakeup_call_for.wav"/>
|
||||
<prompt phrase="You have not requested a wakeup call." filename="ivr-not_requested_wakeup_call.wav"/>
|
||||
<prompt phrase="Your wakeup call has been cancelled." filename="ivr-wakeup_call_cancelled.wav"/>
|
||||
<prompt phrase="For a daily wakeup call..." filename="ivr-for_daily_wakeup_call.wav"/>
|
||||
<prompt phrase="Daily wakeup call..." filename="ivr-daily_wakeup_call.wav"/>
|
||||
<prompt phrase="For daily wakeup calls..." filename="ivr-for_daily_wakeup_calls.wav"/>
|
||||
<prompt phrase="For a one-time wakeup call..." filename="ivr-for_one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="One-time wakeup call..." filename="ivr-one_time_wakeup_call.wav"/>
|
||||
<prompt phrase="...wakeup call..." filename="ivr-wakeup_call.wav"/>
|
||||
<prompt phrase="Wakey wakey sunshine!" filename="ivr-wakey_wakey_sunshine.wav"/>
|
||||
<prompt phrase="Welcome." filename="ivr-welcome.wav"/>
|
||||
<prompt phrase="Welcome to..." filename="ivr-welcome_to.wav"/>
|
||||
<prompt phrase="Good morning." filename="ivr-good_morning.wav"/>
|
||||
@ -439,67 +439,64 @@
|
||||
<prompt phrase="Congratulations, you pressed star. This does not mean you ARE a star. It simply means that you can press buttons and probably have fingers." filename="ivr-congratulations_you_pressed_star.wav"/>
|
||||
<prompt phrase="All of our engineers are busy assisting other sales guys with demonstrating how cool the CudaTel is." filename="ivr-engineers_busy_assisting_other_sales.wav"/>
|
||||
<prompt phrase="This message will self-destruct in 5, 4, 3, 2, 1..." filename="ivr-message_self_destruct.wav"/>
|
||||
<prompt phrase="All your call are belong to us." filename="ivr-all_your_call_are_belong_to_us.wav"/>
|
||||
<prompt phrase="I just love the way you press those touch tones!" filename="ivr-love_those_touch_tones.wav"/>
|
||||
<prompt phrase="Yes, we have no bananas." filename="ivr-yes_we_have_no_bananas.wav"/>
|
||||
<prompt phrase="Dude, you suck!" filename="ivr-dude_you_suck.wav"/>
|
||||
<prompt phrase="Your call is very important to us, but your sanity is not, so we will be happy to keep you on hold, forever torturing you with our annoying hold music." filename="ivr-on_hold_indefinitely.wav"/>
|
||||
<prompt phrase="...has left the building." filename="ivr-has_left_the_building.wav"/>
|
||||
<prompt phrase="This phone is unassigned and may not be used to make external calls." filename="ivr-phone_is_unassigned.wav"/>
|
||||
<prompt phrase="This phone is not configured properly." filename="ivr-phone_not_configured.wav"/>
|
||||
<prompt phrase="Congratulations! This phone is configured properly and may now be assigned to a user." filename="ivr-phone_is_configured_properly.wav"/>
|
||||
<prompt phrase="Please contact the system administrator for assistance." filename="ivr-contact_system_administrator.wav"/>
|
||||
<prompt phrase="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
|
||||
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
|
||||
<prompt phrase="There are no calls waiting in this queue." filename="ivr-no_calls_waiting_in_queue.wav"/>
|
||||
<prompt phrase="You are caller number one. Of course, *every* caller is number one in our book so you may be waiting a while." filename="ivr-youre_number_one.wav"/>
|
||||
<prompt phrase="...has called emergency services" filename="ivr-has_called_emergency_services.wav"/>
|
||||
<prompt phrase="There are..." filename="ivr-there_are.wav"/>
|
||||
<prompt phrase="Please enter the source telephone number, then press pound." filename="ivr-enter_source_telephone_number.wav"/>
|
||||
<prompt phrase="Please enter the destination telephone number, then press pound." filename="ivr-enter_destination_telephone_number.wav"/>
|
||||
<prompt phrase="Recording started." filename="ivr-recording_started.wav"/>
|
||||
<prompt phrase="Recording stopped." filename="ivr-recording_stopped.wav"/>
|
||||
<prompt phrase="Recording paused." filename="ivr-recording_paused.wav"/>
|
||||
<prompt phrase="Recording deleted." filename="ivr-recording_deleted.wav"/>
|
||||
<prompt phrase="You are no longer in queue." filename="ivr-no_longer_in_queue.wav"/>
|
||||
<prompt phrase="...withdrawn." filename="ivr-withdrawn.wav"/>
|
||||
<prompt phrase="question..." filename="ivr-question.wav"/>
|
||||
<prompt phrase="...questions." filename="ivr-questions.wav"/>
|
||||
<prompt phrase="...has been answered." filename="ivr-has_been_answered.wav"/>
|
||||
<prompt phrase="...has been removed." filename="ivr-has_been_removed.wav"/>
|
||||
<prompt phrase="No questions in queue." filename="ivr-no_questions_in_queue.wav"/>
|
||||
<prompt phrase="...is now on." filename="ivr/ivr_is_now_on.wav"/>
|
||||
<prompt phrase="...is now off." filename="ivr/ivr_is_now_off.wav"/>
|
||||
<prompt phrase="This phone is not allowed to make external calls." filename="ivr-phone_not_make_external_calls.wav"/>
|
||||
<prompt phrase="I.D. number..." filename="ivr-id_number.wav"/>
|
||||
<prompt phrase="To skip these instructions..." filename="ivr-skip_instructions.wav"/>
|
||||
<prompt phrase="Hang up the call without pressing a key to discard the recording." filename="ivr-hangup_to_discard.wav"/>
|
||||
<prompt phrase="...or press..." filename="ivr-or_press.wav"/>
|
||||
<prompt phrase="For English, press..." filename="ivr-for_english_press.wav"/>
|
||||
<prompt phrase="Your call cannot be completed as dialed." filename="ivr-call_cannot_be_completed_as_dialed.wav"/>
|
||||
<prompt phrase="Please check the number and try again." filename="ivr-please_check_number_try_again.wav"/>
|
||||
<prompt phrase="Failure reason is..." filename="ivr-failure_reason_is.wav"/>
|
||||
<prompt phrase="Unallocated number" filename="ivr-unallocated_number.wav"/>
|
||||
<prompt phrase="No user response" filename="ivr-no_user_response.wav"/>
|
||||
<prompt phrase="Invalid number format" filename="ivr-invalid_number_format.wav"/>
|
||||
<prompt phrase="Gateway down" filename="ivr-gateway_down.wav"/>
|
||||
<prompt phrase="No route to destination" filename="ivr-no_route_destination.wav"/>
|
||||
<prompt phrase="User busy" filename="ivr-user_busy.wav"/>
|
||||
<prompt phrase="Call rejected" filename="ivr-call_rejected.wav"/>
|
||||
<prompt phrase="Normal unspecified" filename="ivr-normal_unspecified.wav"/>
|
||||
<prompt phrase="Incompatible destination" filename="ivr-incompatible_destination.wav"/>
|
||||
<prompt phrase="Normal clearing" filename="ivr-normal_clearing.wav"/>
|
||||
|
||||
<prompt phrase="All your call are belong to us." filename="ivr-all_your_call_are_belong_to_us.wav"/>
|
||||
<prompt phrase="I just love the way you press those touch tones!" filename="ivr-love_those_touch_tones.wav"/>
|
||||
<prompt phrase="Yes, we have no bananas." filename="ivr-yes_we_have_no_bananas.wav"/>
|
||||
<prompt phrase="Dude, you suck!" filename="ivr-dude_you_suck.wav"/>
|
||||
<prompt phrase="Your call is very important to us, but your sanity is not, so we will be happy to keep you on hold, forever torturing you with our annoying hold music." filename="ivr-on_hold_indefinitely.wav"/>
|
||||
<prompt phrase="...has left the building." filename="ivr-has_left_the_building.wav"/>
|
||||
<prompt phrase="This phone is unassigned and may not be used to make external calls." filename="ivr-phone_is_unassigned.wav"/>
|
||||
<prompt phrase="This phone is not configured properly." filename="ivr-phone_not_configured.wav"/>
|
||||
<prompt phrase="Congratulations! This phone is configured properly and may now be assigned to a user." filename="ivr-phone_is_configured_properly.wav"/>
|
||||
<prompt phrase="Please contact the system administrator for assistance." filename="ivr-contact_system_administrator.wav"/>
|
||||
<prompt phrase="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
|
||||
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
|
||||
<prompt phrase="There are no calls waiting in this queue." filename="ivr-no_calls_waiting_in_queue.wav"/>
|
||||
<prompt phrase="You are caller number one. Of course, *every* caller is number one in our book so you may be waiting a while." filename="ivr-youre_number_one.wav"/>
|
||||
<prompt phrase="...has called emergency services" filename="ivr-has_called_emergency_services.wav"/>
|
||||
<prompt phrase="There are..." filename="ivr-there_are.wav"/>
|
||||
<prompt phrase="Please enter the source telephone number, then press pound." filename="ivr-enter_source_telephone_number.wav"/>
|
||||
<prompt phrase="Please enter the destination telephone number, then press pound." filename="ivr-enter_destination_telephone_number.wav"/>
|
||||
<prompt phrase="Recording started." filename="ivr-recording_started.wav"/>
|
||||
<prompt phrase="Recording stopped." filename="ivr-recording_stopped.wav"/>
|
||||
<prompt phrase="Recording paused." filename="ivr-recording_paused.wav"/>
|
||||
<prompt phrase="Recording deleted." filename="ivr-recording_deleted.wav"/>
|
||||
<prompt phrase="You are no longer in queue." filename="ivr-no_longer_in_queue.wav"/>
|
||||
<prompt phrase="...withdrawn." filename="ivr-withdrawn.wav"/>
|
||||
<prompt phrase="question..." filename="ivr-question.wav"/>
|
||||
<prompt phrase="...questions." filename="ivr-questions.wav"/>
|
||||
<prompt phrase="...has been answered." filename="ivr-has_been_answered.wav"/>
|
||||
<prompt phrase="...has been removed." filename="ivr-has_been_removed.wav"/>
|
||||
<prompt phrase="No questions in queue." filename="ivr-no_questions_in_queue.wav"/>
|
||||
<prompt phrase="...is now on." filename="ivr/ivr_is_now_on.wav"/>
|
||||
<prompt phrase="...is now off." filename="ivr/ivr_is_now_off.wav"/>
|
||||
<prompt phrase="This phone is not allowed to make external calls." filename="ivr-phone_not_make_external_calls.wav"/>
|
||||
<prompt phrase="I.D. number..." filename="ivr-id_number.wav"/>
|
||||
<prompt phrase="To skip these instructions..." filename="ivr-skip_instructions.wav"/>
|
||||
<prompt phrase="Hang up the call without pressing a key to discard the recording." filename="ivr-hangup_to_discard.wav"/>
|
||||
<prompt phrase="...or press..." filename="ivr-or_press.wav"/>
|
||||
<prompt phrase="For English, press..." filename="ivr-for_english_press.wav"/>
|
||||
<prompt phrase="Your call cannot be completed as dialed." filename="ivr-call_cannot_be_completed_as_dialed.wav"/>
|
||||
<prompt phrase="Please check the number and try again." filename="ivr-please_check_number_try_again.wav"/>
|
||||
<prompt phrase="Failure reason is..." filename="ivr-failure_reason_is.wav"/>
|
||||
<prompt phrase="Unallocated number" filename="ivr-unallocated_number.wav"/>
|
||||
<prompt phrase="No user response" filename="ivr-no_user_response.wav"/>
|
||||
<prompt phrase="Invalid number format" filename="ivr-invalid_number_format.wav"/>
|
||||
<prompt phrase="Gateway down" filename="ivr-gateway_down.wav"/>
|
||||
<prompt phrase="No route to destination" filename="ivr-no_route_destination.wav"/>
|
||||
<prompt phrase="User busy" filename="ivr-user_busy.wav"/>
|
||||
<prompt phrase="Call rejected" filename="ivr-call_rejected.wav"/>
|
||||
<prompt phrase="Normal unspecified" filename="ivr-normal_unspecified.wav"/>
|
||||
<prompt phrase="Incompatible destination" filename="ivr-incompatible_destination.wav"/>
|
||||
<prompt phrase="Normal clearing" filename="ivr-normal_clearing.wav"/>
|
||||
<!-- The following phrases still need to be recorded -->
|
||||
<prompt phrase="This conference is full. Please contact the conference moderator." filename="conf-conference_is_full.wav"/>
|
||||
<prompt phrase="You do not have permission to perform this action." filename="ivr-not_have_permission.wav"/>
|
||||
<prompt phrase="You're doing it wrong, but I'll try to connect you anyway. (Douchebag!)" filename="ivr-youre_doing_it_wrong.wav"/>
|
||||
<prompt phrase="" filename=""/>
|
||||
<prompt phrase="" filename=""/>
|
||||
<prompt phrase="" filename=""/>
|
||||
|
||||
<prompt phrase="You do not have permission to perform this action." filename="ivr-not_have_permission.wav"/>
|
||||
<prompt phrase="You're doing it wrong, but I'll try to connect you anyway. (Douchebag!)" filename="ivr-youre_doing_it_wrong.wav"/>
|
||||
<prompt phrase="" filename=""/>
|
||||
<prompt phrase="" filename=""/>
|
||||
<prompt phrase="" filename=""/>
|
||||
</ivr>
|
||||
|
||||
<misc>
|
||||
<prompt phrase="This call has been secured" filename="call_secured.wav"/>
|
||||
<prompt phrase="Followed by pound" filename="followed.wav"/>
|
||||
@ -1046,3 +1043,9 @@
|
||||
</zrtp>
|
||||
</en>
|
||||
</language>
|
||||
<!--
|
||||
Local Variables:
|
||||
mode:xml
|
||||
indent-tabs-mode:nil
|
||||
End:
|
||||
-->
|
||||
|
126
freeswitch-sounds-music.spec
Normal file
126
freeswitch-sounds-music.spec
Normal file
@ -0,0 +1,126 @@
|
||||
%define prefix /opt/freeswitch
|
||||
%define _prefix %{prefix}
|
||||
|
||||
|
||||
Summary: FreeSWITCH Music on Hold soundfiles
|
||||
Name: freeswitch-sounds-music
|
||||
Version: 1.0.8
|
||||
Release: 1%{?dist}
|
||||
License: MPL
|
||||
Group: Productivity/Telephony/Servers
|
||||
Packager: Joseph L. Casale <jcasale@activenetwerx.com>
|
||||
URL: http://www.freeswitch.org
|
||||
Source0: http://files.freeswitch.org/%{name}-8000-%{version}.tar.gz
|
||||
Source1: http://files.freeswitch.org/%{name}-16000-%{version}.tar.gz
|
||||
Source2: http://files.freeswitch.org/%{name}-32000-%{version}.tar.gz
|
||||
Source3: http://files.freeswitch.org/%{name}-48000-%{version}.tar.gz
|
||||
BuildArch: noarch
|
||||
BuildRequires: bash
|
||||
Requires: freeswitch
|
||||
Requires: freeswitch-sounds-music-8000 = %{version}
|
||||
Requires: freeswitch-sounds-music-16000 = %{version}
|
||||
Requires: freeswitch-sounds-music-32000 = %{version}
|
||||
Requires: freeswitch-sounds-music-48000 = %{version}
|
||||
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
|
||||
%description
|
||||
FreeSWITCH Music On Hold soundfiles package that installs the 8KHz, 16KHz,
|
||||
32KHz and 48KHz RPMs
|
||||
|
||||
|
||||
%package -n freeswitch-sounds-music-8000
|
||||
Summary: FreeSWITCH 8kHz Music On Hold soundfiles
|
||||
Group: Productivity/Telephony/Servers
|
||||
BuildArch: noarch
|
||||
Requires: freeswitch
|
||||
|
||||
%description -n freeswitch-sounds-music-8000
|
||||
FreeSWITCH 8kHz Music On Hold soundfiles
|
||||
|
||||
|
||||
%package -n freeswitch-sounds-music-16000
|
||||
Summary: FreeSWITCH 16kHz Music On Hold soundfiles
|
||||
Group: Productivity/Telephony/Servers
|
||||
BuildArch: noarch
|
||||
Requires: freeswitch
|
||||
|
||||
%description -n freeswitch-sounds-music-16000
|
||||
FreeSWITCH 16kHz Music On Hold soundfiles
|
||||
|
||||
|
||||
%package -n freeswitch-sounds-music-32000
|
||||
Summary: FreeSWITCH 32kHz Music On Hold soundfiles
|
||||
Group: Productivity/Telephony/Servers
|
||||
BuildArch: noarch
|
||||
Requires: freeswitch
|
||||
|
||||
%description -n freeswitch-sounds-music-32000
|
||||
FreeSWITCH 32kHz Music On Hold soundfiles
|
||||
|
||||
|
||||
%package -n freeswitch-sounds-music-48000
|
||||
Summary: FreeSWITCH 48kHz Music On Hold soundfiles
|
||||
Group: Productivity/Telephony/Servers
|
||||
BuildArch: noarch
|
||||
Requires: freeswitch
|
||||
|
||||
%description -n freeswitch-sounds-music-48000
|
||||
FreeSWITCH 48kHz Music On Hold soundfiles
|
||||
|
||||
|
||||
%prep
|
||||
%setup -n music
|
||||
%setup -T -D -b 1 -n music
|
||||
%setup -T -D -b 2 -n music
|
||||
%setup -T -D -b 3 -n music
|
||||
|
||||
|
||||
%build
|
||||
|
||||
|
||||
%install
|
||||
%{__rm} -rf %{buildroot}
|
||||
%{__install} -d -m 0750 %{buildroot}/%{_prefix}/sounds/music/{8000,16000,32000,48000}
|
||||
%{__cp} -prv ./{8000,16000,32000,48000} %{buildroot}%{_prefix}/sounds/music
|
||||
|
||||
|
||||
%clean
|
||||
%{__rm} -rf %{buildroot}
|
||||
|
||||
|
||||
%post
|
||||
|
||||
|
||||
%postun
|
||||
|
||||
|
||||
%files
|
||||
|
||||
|
||||
%files -n freeswitch-sounds-music-8000
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_prefix}/sounds/music/8000
|
||||
%{_prefix}/sounds/music/8000/*.wav
|
||||
|
||||
|
||||
%files -n freeswitch-sounds-music-16000
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_prefix}/sounds/music/16000
|
||||
%{_prefix}/sounds/music/16000/*.wav
|
||||
|
||||
|
||||
%files -n freeswitch-sounds-music-32000
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_prefix}/sounds/music/32000
|
||||
%{_prefix}/sounds/music/32000/*.wav
|
||||
|
||||
|
||||
%files -n freeswitch-sounds-music-48000
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_prefix}/sounds/music/48000
|
||||
%{_prefix}/sounds/music/48000/*.wav
|
||||
|
||||
|
||||
%changelog
|
||||
* Sat Jul 16 2011 Joseph Casale <jcasale@activenetwerx.com> 1.0.8-1
|
||||
- Initial release
|
@ -432,12 +432,12 @@ export QA_RPATHS=$[ 0x0001|0x0002 ]
|
||||
APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_callcenter applications/mod_cidlookup applications/mod_cluechoo \
|
||||
applications/mod_commands applications/mod_conference applications/mod_curl applications/mod_db applications/mod_directory \
|
||||
applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum \
|
||||
applications/mod_esf applications/mod_expr"
|
||||
applications/mod_esf applications/mod_expr applications/mod_blacklist"
|
||||
APPLICATION_MODULES_FM="applications/mod_fifo applications/mod_fsv applications/mod_hash applications/mod_lcr applications/mod_limit \
|
||||
applications/mod_memcache"
|
||||
APPLICATION_MODULES_NY="applications/mod_nibblebill applications/mod_redis applications/mod_rss applications/mod_snom \
|
||||
applications/mod_soundtouch applications/mod_spandsp applications/mod_spy applications/mod_stress \
|
||||
applications/mod_valet_parking applications/mod_vmd applications/mod_voicemail"
|
||||
applications/mod_valet_parking applications/mod_vmd applications/mod_voicemail applications/mod_sms"
|
||||
|
||||
APPLICATIONS_MODULES="$APPLICATION_MODULES_AE $APPLICATION_MODULES_FM $APPLICATION_MODULES_NY $APPLICATION_MODULES_VZ"
|
||||
######################################################################################################################
|
||||
@ -751,8 +751,10 @@ fi
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/mime.types
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/acl.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/alsa.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/blacklist.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/callcenter.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_csv.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_mongodb.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_pg_csv.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_sqlite.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cepstral.conf.xml
|
||||
@ -807,6 +809,12 @@ fi
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/zeroconf.conf.xml
|
||||
######################################################################################################################
|
||||
#
|
||||
# Chatplans
|
||||
#
|
||||
######################################################################################################################
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/chatplan/default.xml
|
||||
######################################################################################################################
|
||||
#
|
||||
# Dialplans
|
||||
#
|
||||
######################################################################################################################
|
||||
@ -880,6 +888,7 @@ fi
|
||||
######################################################################################################################
|
||||
%{prefix}/mod/mod_amrwb.so*
|
||||
%{prefix}/mod/mod_avmd.so*
|
||||
%{prefix}/mod/mod_blacklist.so*
|
||||
%{prefix}/mod/mod_bv.so*
|
||||
%{prefix}/mod/mod_callcenter.so*
|
||||
%{prefix}/mod/mod_cdr_csv.so*
|
||||
@ -932,6 +941,7 @@ fi
|
||||
%{prefix}/mod/mod_silk.so*
|
||||
%{prefix}/mod/mod_siren.so*
|
||||
%{prefix}/mod/mod_skinny.so*
|
||||
%{prefix}/mod/mod_sms.so*
|
||||
%{prefix}/mod/mod_sndfile.so*
|
||||
%{prefix}/mod/mod_snom.so*
|
||||
%{prefix}/mod/mod_sofia.so*
|
||||
|
927
libs/.gitignore
vendored
927
libs/.gitignore
vendored
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ PICKY=-O2
|
||||
CFLAGS=$(BASE_FLAGS) $(PICKY)
|
||||
CXXFLAGS=$(BASE_FLAGS)
|
||||
MYLIB=libesl.a
|
||||
LIBS=-lncurses -lpthread -lesl -lm
|
||||
LIBS=-lncurses -lesl -lpthread -lm
|
||||
LDFLAGS=-L.
|
||||
OBJS=src/esl.o src/esl_event.o src/esl_threadmutex.o src/esl_config.o src/esl_json.o src/esl_buffer.o
|
||||
SRC=src/esl.c src/esl_json.c src/esl_event.c src/esl_threadmutex.c src/esl_config.c src/esl_oop.cpp src/esl_json.c src/esl_buffer.c
|
||||
@ -32,7 +32,7 @@ testclient: $(MYLIB) testclient.c
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) testclient.c -o testclient $(LDFLAGS) $(LIBS)
|
||||
|
||||
fs_cli: $(MYLIB) fs_cli.c
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) fs_cli.c -o fs_cli $(LDFLAGS) -L$(LIBEDIT_DIR)/src/.libs $(LIBS) -ledit
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) fs_cli.c -o fs_cli $(LDFLAGS) -L$(LIBEDIT_DIR)/src/.libs -ledit $(LIBS)
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
1032
libs/esl/fs_cli.c
1032
libs/esl/fs_cli.c
File diff suppressed because it is too large
Load Diff
@ -904,6 +904,31 @@ SWIGEXPORT jlong JNICALL Java_org_freeswitch_esl_eslJNI_ESLconnection_1sendEvent
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT jint JNICALL Java_org_freeswitch_esl_eslJNI_ESLconnection_1sendMSG(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jstring jarg3) {
|
||||
jint jresult = 0 ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
|
||||
(void)jenv;
|
||||
(void)jcls;
|
||||
(void)jarg1_;
|
||||
(void)jarg2_;
|
||||
arg1 = *(ESLconnection **)&jarg1;
|
||||
arg2 = *(ESLevent **)&jarg2;
|
||||
arg3 = 0;
|
||||
if (jarg3) {
|
||||
arg3 = (char *)jenv->GetStringUTFChars(jarg3, 0);
|
||||
if (!arg3) return 0;
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
jresult = (jint)result;
|
||||
if (arg3) jenv->ReleaseStringUTFChars(jarg3, (const char *)arg3);
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT jlong JNICALL Java_org_freeswitch_esl_eslJNI_ESLconnection_1recvEvent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) {
|
||||
jlong jresult = 0 ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
|
@ -82,6 +82,10 @@ public class ESLconnection {
|
||||
return (cPtr == 0) ? null : new ESLevent(cPtr, true);
|
||||
}
|
||||
|
||||
public int sendMSG(ESLevent send_me, String uuid) {
|
||||
return eslJNI.ESLconnection_sendMSG(swigCPtr, this, ESLevent.getCPtr(send_me), send_me, uuid);
|
||||
}
|
||||
|
||||
public ESLevent recvEvent() {
|
||||
long cPtr = eslJNI.ESLconnection_recvEvent(swigCPtr, this);
|
||||
return (cPtr == 0) ? null : new ESLevent(cPtr, true);
|
||||
|
@ -43,6 +43,7 @@ class eslJNI {
|
||||
public final static native long ESLconnection_api(long jarg1, ESLconnection jarg1_, String jarg2, String jarg3);
|
||||
public final static native long ESLconnection_bgapi(long jarg1, ESLconnection jarg1_, String jarg2, String jarg3, String jarg4);
|
||||
public final static native long ESLconnection_sendEvent(long jarg1, ESLconnection jarg1_, long jarg2, ESLevent jarg2_);
|
||||
public final static native int ESLconnection_sendMSG(long jarg1, ESLconnection jarg1_, long jarg2, ESLevent jarg2_, String jarg3);
|
||||
public final static native long ESLconnection_recvEvent(long jarg1, ESLconnection jarg1_);
|
||||
public final static native long ESLconnection_recvEventTimed(long jarg1, ESLconnection jarg1_, int jarg2);
|
||||
public final static native long ESLconnection_filter(long jarg1, ESLconnection jarg1_, String jarg2, String jarg3);
|
||||
|
@ -2632,6 +2632,43 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static int _wrap_ESLconnection_sendMSG(lua_State* L) {
|
||||
int SWIG_arg = -1;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
|
||||
SWIG_check_num_args("sendMSG",2,3)
|
||||
if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("sendMSG",1,"ESLconnection *");
|
||||
if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("sendMSG",2,"ESLevent *");
|
||||
if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("sendMSG",3,"char const *");
|
||||
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){
|
||||
SWIG_fail_ptr("ESLconnection_sendMSG",1,SWIGTYPE_p_ESLconnection);
|
||||
}
|
||||
|
||||
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L,2,(void**)&arg2,SWIGTYPE_p_ESLevent,0))){
|
||||
SWIG_fail_ptr("ESLconnection_sendMSG",2,SWIGTYPE_p_ESLevent);
|
||||
}
|
||||
|
||||
if(lua_gettop(L)>=3){
|
||||
arg3 = (char *)lua_tostring(L, 3);
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
SWIG_arg=0;
|
||||
lua_pushnumber(L, (lua_Number) result); SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
||||
if(0) SWIG_fail;
|
||||
|
||||
fail:
|
||||
lua_error(L);
|
||||
return SWIG_arg;
|
||||
}
|
||||
|
||||
|
||||
static int _wrap_ESLconnection_recvEvent(lua_State* L) {
|
||||
int SWIG_arg = -1;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@ -2917,6 +2954,7 @@ static swig_lua_method swig_ESLconnection_methods[] = {
|
||||
{"api", _wrap_ESLconnection_api},
|
||||
{"bgapi", _wrap_ESLconnection_bgapi},
|
||||
{"sendEvent", _wrap_ESLconnection_sendEvent},
|
||||
{"sendMSG", _wrap_ESLconnection_sendMSG},
|
||||
{"recvEvent", _wrap_ESLconnection_recvEvent},
|
||||
{"recvEventTimed", _wrap_ESLconnection_recvEventTimed},
|
||||
{"filter", _wrap_ESLconnection_filter},
|
||||
|
@ -286,6 +286,9 @@ class ESLPINVOKE {
|
||||
[DllImport("ESL", EntryPoint="CSharp_ESLconnection_SendEvent")]
|
||||
public static extern IntPtr ESLconnection_SendEvent(HandleRef jarg1, HandleRef jarg2);
|
||||
|
||||
[DllImport("ESL", EntryPoint="CSharp_ESLconnection_sendMSG")]
|
||||
public static extern int ESLconnection_sendMSG(HandleRef jarg1, HandleRef jarg2, string jarg3);
|
||||
|
||||
[DllImport("ESL", EntryPoint="CSharp_ESLconnection_RecvEvent")]
|
||||
public static extern IntPtr ESLconnection_RecvEvent(HandleRef jarg1);
|
||||
|
||||
|
@ -92,6 +92,11 @@ public class ESLconnection : IDisposable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int sendMSG(ESLevent send_me, string uuid) {
|
||||
int ret = ESLPINVOKE.ESLconnection_sendMSG(swigCPtr, ESLevent.getCPtr(send_me), uuid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ESLevent RecvEvent() {
|
||||
IntPtr cPtr = ESLPINVOKE.ESLconnection_RecvEvent(swigCPtr);
|
||||
ESLevent ret = (cPtr == IntPtr.Zero) ? null : new ESLevent(cPtr, true);
|
||||
|
@ -743,6 +743,22 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_ESLconnection_SendEvent(void * jarg1, void
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT int SWIGSTDCALL CSharp_ESLconnection_sendMSG(void * jarg1, void * jarg2, char * jarg3) {
|
||||
int jresult ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
|
||||
arg1 = (ESLconnection *)jarg1;
|
||||
arg2 = (ESLevent *)jarg2;
|
||||
arg3 = (char *)jarg3;
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
jresult = result;
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
||||
SWIGEXPORT void * SWIGSTDCALL CSharp_ESLconnection_RecvEvent(void * jarg1) {
|
||||
void * jresult ;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
|
@ -138,6 +138,7 @@ sub DESTROY {
|
||||
*api = *ESLc::ESLconnection_api;
|
||||
*bgapi = *ESLc::ESLconnection_bgapi;
|
||||
*sendEvent = *ESLc::ESLconnection_sendEvent;
|
||||
*sendMSG = *ESLc::ESLconnection_sendMSG;
|
||||
*recvEvent = *ESLc::ESLconnection_recvEvent;
|
||||
*recvEventTimed = *ESLc::ESLconnection_recvEventTimed;
|
||||
*filter = *ESLc::ESLconnection_filter;
|
||||
|
@ -3282,6 +3282,57 @@ XS(_wrap_ESLconnection_sendEvent) {
|
||||
}
|
||||
|
||||
|
||||
XS(_wrap_ESLconnection_sendMSG) {
|
||||
{
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
void *argp2 = 0 ;
|
||||
int res2 = 0 ;
|
||||
int res3 ;
|
||||
char *buf3 = 0 ;
|
||||
int alloc3 = 0 ;
|
||||
int argvi = 0;
|
||||
dXSARGS;
|
||||
|
||||
if ((items < 2) || (items > 3)) {
|
||||
SWIG_croak("Usage: ESLconnection_sendMSG(self,send_me,uuid);");
|
||||
}
|
||||
res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_ESLconnection, 0 | 0 );
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ESLconnection_sendMSG" "', argument " "1"" of type '" "ESLconnection *""'");
|
||||
}
|
||||
arg1 = reinterpret_cast< ESLconnection * >(argp1);
|
||||
res2 = SWIG_ConvertPtr(ST(1), &argp2,SWIGTYPE_p_ESLevent, 0 | 0 );
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ESLconnection_sendMSG" "', argument " "2"" of type '" "ESLevent *""'");
|
||||
}
|
||||
arg2 = reinterpret_cast< ESLevent * >(argp2);
|
||||
if (items > 2) {
|
||||
res3 = SWIG_AsCharPtrAndSize(ST(2), &buf3, NULL, &alloc3);
|
||||
if (!SWIG_IsOK(res3)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ESLconnection_sendMSG" "', argument " "3"" of type '" "char const *""'");
|
||||
}
|
||||
arg3 = reinterpret_cast< char * >(buf3);
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
ST(argvi) = SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
|
||||
|
||||
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
XSRETURN(argvi);
|
||||
fail:
|
||||
|
||||
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
SWIG_croak_null();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XS(_wrap_ESLconnection_recvEvent) {
|
||||
{
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@ -3785,6 +3836,7 @@ static swig_command_info swig_commands[] = {
|
||||
{"ESLc::ESLconnection_api", _wrap_ESLconnection_api},
|
||||
{"ESLc::ESLconnection_bgapi", _wrap_ESLconnection_bgapi},
|
||||
{"ESLc::ESLconnection_sendEvent", _wrap_ESLconnection_sendEvent},
|
||||
{"ESLc::ESLconnection_sendMSG", _wrap_ESLconnection_sendMSG},
|
||||
{"ESLc::ESLconnection_recvEvent", _wrap_ESLconnection_recvEvent},
|
||||
{"ESLc::ESLconnection_recvEventTimed", _wrap_ESLconnection_recvEventTimed},
|
||||
{"ESLc::ESLconnection_filter", _wrap_ESLconnection_filter},
|
||||
|
@ -174,6 +174,14 @@ class ESLconnection {
|
||||
return is_resource($r) ? new ESLevent($r) : $r;
|
||||
}
|
||||
|
||||
function sendMSG($send_me,$uuid=null) {
|
||||
switch (func_num_args()) {
|
||||
case 1: $r=ESLconnection_sendMSG($this->_cPtr,$send_me); break;
|
||||
default: $r=ESLconnection_sendMSG($this->_cPtr,$send_me,$uuid);
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
function recvEvent() {
|
||||
$r=ESLconnection_recvEvent($this->_cPtr);
|
||||
return is_resource($r) ? new ESLevent($r) : $r;
|
||||
|
@ -2244,6 +2244,48 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendMSG) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
zval **args[3];
|
||||
int arg_count;
|
||||
|
||||
SWIG_ResetError();
|
||||
arg_count = ZEND_NUM_ARGS();
|
||||
if(arg_count<2 || arg_count>3 ||
|
||||
zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
{
|
||||
if(SWIG_ConvertPtr(*args[0], (void **) &arg1, SWIGTYPE_p_ESLconnection, 0) < 0) {
|
||||
SWIG_PHP_Error(E_ERROR, "Type error in argument 1 of ESLconnection_sendMSG. Expected SWIGTYPE_p_ESLconnection");
|
||||
}
|
||||
}
|
||||
if(!arg1) SWIG_PHP_Error(E_ERROR, "this pointer is NULL");
|
||||
{
|
||||
if(SWIG_ConvertPtr(*args[1], (void **) &arg2, SWIGTYPE_p_ESLevent, 0) < 0) {
|
||||
SWIG_PHP_Error(E_ERROR, "Type error in argument 2 of ESLconnection_sendMSG. Expected SWIGTYPE_p_ESLevent");
|
||||
}
|
||||
}
|
||||
if(arg_count > 2) {
|
||||
/*@SWIG:/usr/local/share/swig/1.3.35/php4/utils.i,26,CONVERT_STRING_IN@*/
|
||||
convert_to_string_ex(args[2]);
|
||||
arg3 = (char *) Z_STRVAL_PP(args[2]);
|
||||
/*@SWIG@*/;
|
||||
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
{
|
||||
ZVAL_LONG(return_value,result);
|
||||
}
|
||||
return;
|
||||
fail:
|
||||
zend_error(SWIG_ErrorCode(),SWIG_ErrorMsg());
|
||||
}
|
||||
|
||||
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_recvEvent) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *result = 0 ;
|
||||
@ -2651,6 +2693,7 @@ static zend_function_entry ESL_functions[] = {
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_api,_wrap_ESLconnection_api,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_bgapi,_wrap_ESLconnection_bgapi,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_sendevent,_wrap_ESLconnection_sendEvent,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_sendmsg,_wrap_ESLconnection_sendMSG,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_recvevent,_wrap_ESLconnection_recvEvent,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_recveventtimed,_wrap_ESLconnection_recvEventTimed,NULL)
|
||||
SWIG_ZEND_NAMED_FE(eslconnection_filter,_wrap_ESLconnection_filter,NULL)
|
||||
|
@ -60,6 +60,7 @@ ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendRecv);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_api);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_bgapi);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendEvent);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_sendMSG);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_recvEvent);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_recvEventTimed);
|
||||
ZEND_NAMED_FUNCTION(_wrap_ESLconnection_filter);
|
||||
|
@ -87,6 +87,7 @@ class ESLconnection:
|
||||
def api(*args): return apply(_ESL.ESLconnection_api, args)
|
||||
def bgapi(*args): return apply(_ESL.ESLconnection_bgapi, args)
|
||||
def sendEvent(*args): return apply(_ESL.ESLconnection_sendEvent, args)
|
||||
def sendMSG(*args): return apply(_ESL.ESLconnection_sendMSG, args)
|
||||
def recvEvent(*args): return apply(_ESL.ESLconnection_recvEvent, args)
|
||||
def recvEventTimed(*args): return apply(_ESL.ESLconnection_recvEventTimed, args)
|
||||
def filter(*args): return apply(_ESL.ESLconnection_filter, args)
|
||||
|
@ -4370,6 +4370,58 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN PyObject *_wrap_ESLconnection_sendMSG(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||
PyObject *resultobj = 0;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
void *argp2 = 0 ;
|
||||
int res2 = 0 ;
|
||||
int res3 ;
|
||||
char *buf3 = 0 ;
|
||||
int alloc3 = 0 ;
|
||||
PyObject * obj0 = 0 ;
|
||||
PyObject * obj1 = 0 ;
|
||||
PyObject * obj2 = 0 ;
|
||||
|
||||
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
|
||||
if (!PyArg_ParseTuple(args,(char *)"OO|O:ESLconnection_sendMSG",&obj0,&obj1,&obj2)) SWIG_fail;
|
||||
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ESLconnection, 0 | 0 );
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ESLconnection_sendMSG" "', argument " "1"" of type '" "ESLconnection *""'");
|
||||
}
|
||||
arg1 = reinterpret_cast< ESLconnection * >(argp1);
|
||||
res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ESLevent, 0 | 0 );
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ESLconnection_sendMSG" "', argument " "2"" of type '" "ESLevent *""'");
|
||||
}
|
||||
arg2 = reinterpret_cast< ESLevent * >(argp2);
|
||||
if (obj2) {
|
||||
res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3);
|
||||
if (!SWIG_IsOK(res3)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ESLconnection_sendMSG" "', argument " "3"" of type '" "char const *""'");
|
||||
}
|
||||
arg3 = reinterpret_cast< char * >(buf3);
|
||||
}
|
||||
{
|
||||
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
SWIG_PYTHON_THREAD_END_ALLOW;
|
||||
}
|
||||
resultobj = SWIG_From_int(static_cast< int >(result));
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
SWIG_PYTHON_THREAD_END_BLOCK;
|
||||
return resultobj;
|
||||
fail:
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
SWIG_PYTHON_THREAD_END_BLOCK;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN PyObject *_wrap_ESLconnection_recvEvent(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||
PyObject *resultobj = 0;
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@ -4859,6 +4911,7 @@ static PyMethodDef SwigMethods[] = {
|
||||
{ (char *)"ESLconnection_api", _wrap_ESLconnection_api, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_bgapi", _wrap_ESLconnection_bgapi, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_sendEvent", _wrap_ESLconnection_sendEvent, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_sendMSG", _wrap_ESLconnection_sendMSG, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_recvEvent", _wrap_ESLconnection_recvEvent, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_recvEventTimed", _wrap_ESLconnection_recvEventTimed, METH_VARARGS, NULL},
|
||||
{ (char *)"ESLconnection_filter", _wrap_ESLconnection_filter, METH_VARARGS, NULL},
|
||||
|
@ -3245,6 +3245,51 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN VALUE
|
||||
_wrap_ESLconnection_sendMSG(int argc, VALUE *argv, VALUE self) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
ESLevent *arg2 = (ESLevent *) 0 ;
|
||||
char *arg3 = (char *) NULL ;
|
||||
int result;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
void *argp2 = 0 ;
|
||||
int res2 = 0 ;
|
||||
int res3 ;
|
||||
char *buf3 = 0 ;
|
||||
int alloc3 = 0 ;
|
||||
VALUE vresult = Qnil;
|
||||
|
||||
if ((argc < 1) || (argc > 2)) {
|
||||
rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
|
||||
}
|
||||
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ESLconnection, 0 | 0 );
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "ESLconnection *","sendMSG", 1, self ));
|
||||
}
|
||||
arg1 = reinterpret_cast< ESLconnection * >(argp1);
|
||||
res2 = SWIG_ConvertPtr(argv[0], &argp2,SWIGTYPE_p_ESLevent, 0 | 0 );
|
||||
if (!SWIG_IsOK(res2)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "ESLevent *","sendMSG", 2, argv[0] ));
|
||||
}
|
||||
arg2 = reinterpret_cast< ESLevent * >(argp2);
|
||||
if (argc > 1) {
|
||||
res3 = SWIG_AsCharPtrAndSize(argv[1], &buf3, NULL, &alloc3);
|
||||
if (!SWIG_IsOK(res3)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res3), Ruby_Format_TypeError( "", "char const *","sendMSG", 3, argv[1] ));
|
||||
}
|
||||
arg3 = reinterpret_cast< char * >(buf3);
|
||||
}
|
||||
result = (int)(arg1)->sendMSG(arg2,(char const *)arg3);
|
||||
vresult = SWIG_From_int(static_cast< int >(result));
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
return vresult;
|
||||
fail:
|
||||
if (alloc3 == SWIG_NEWOBJ) delete[] buf3;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN VALUE
|
||||
_wrap_ESLconnection_recvEvent(int argc, VALUE *argv, VALUE self) {
|
||||
ESLconnection *arg1 = (ESLconnection *) 0 ;
|
||||
@ -3958,6 +4003,7 @@ SWIGEXPORT void Init_ESL(void) {
|
||||
rb_define_method(cESLconnection.klass, "api", VALUEFUNC(_wrap_ESLconnection_api), -1);
|
||||
rb_define_method(cESLconnection.klass, "bgapi", VALUEFUNC(_wrap_ESLconnection_bgapi), -1);
|
||||
rb_define_method(cESLconnection.klass, "sendEvent", VALUEFUNC(_wrap_ESLconnection_sendEvent), -1);
|
||||
rb_define_method(cESLconnection.klass, "sendMSG", VALUEFUNC(_wrap_ESLconnection_sendMSG), -1);
|
||||
rb_define_method(cESLconnection.klass, "recvEvent", VALUEFUNC(_wrap_ESLconnection_recvEvent), -1);
|
||||
rb_define_method(cESLconnection.klass, "recvEventTimed", VALUEFUNC(_wrap_ESLconnection_recvEventTimed), -1);
|
||||
rb_define_method(cESLconnection.klass, "filter", VALUEFUNC(_wrap_ESLconnection_filter), -1);
|
||||
|
@ -534,6 +534,39 @@ ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, con
|
||||
}
|
||||
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_sendmsg(esl_handle_t *handle, esl_event_t *event, const char *uuid)
|
||||
{
|
||||
char cmd_buf[128] = "sendmsg\n";
|
||||
char *txt;
|
||||
|
||||
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
if (uuid) {
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "sendmsg %s\n", uuid);
|
||||
}
|
||||
|
||||
esl_event_serialize(event, &txt, ESL_FALSE);
|
||||
esl_log(ESL_LOG_DEBUG, "%s%s\n", cmd_buf, txt);
|
||||
|
||||
if (send(handle->sock, cmd_buf, strlen(cmd_buf), 0) <= 0) goto fail;
|
||||
if (send(handle->sock, txt, strlen(txt), 0) <= 0) goto fail;
|
||||
|
||||
free(txt);
|
||||
|
||||
return esl_recv(handle);
|
||||
|
||||
fail:
|
||||
|
||||
handle->connected = 0;
|
||||
|
||||
free(txt);
|
||||
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_filter(esl_handle_t *handle, const char *header, const char *value)
|
||||
{
|
||||
char send_buf[1024] = "";
|
||||
|
@ -270,8 +270,9 @@ ESL_DECLARE(char *) esl_event_get_header_idx(esl_event_t *event, const char *hea
|
||||
}
|
||||
|
||||
return hp->value;
|
||||
|
||||
}
|
||||
} else if (!strcmp(header_name, "_body")) {
|
||||
return event->body;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -414,6 +415,10 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st
|
||||
int index = 0;
|
||||
char *real_header_name = NULL;
|
||||
|
||||
if (!strcmp(header_name, "_body")) {
|
||||
esl_event_set_body(event, data);
|
||||
}
|
||||
|
||||
if ((index_ptr = strchr(header_name, '['))) {
|
||||
index_ptr++;
|
||||
index = atoi(index_ptr);
|
||||
@ -604,6 +609,17 @@ ESL_DECLARE(esl_status_t) esl_event_add_header_string(esl_event_t *event, esl_st
|
||||
return ESL_FAIL;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_event_set_body(esl_event_t *event, const char *body)
|
||||
{
|
||||
esl_safe_free(event->body);
|
||||
|
||||
if (body) {
|
||||
event->body = DUP(body);
|
||||
}
|
||||
|
||||
return ESL_SUCCESS;
|
||||
}
|
||||
|
||||
ESL_DECLARE(esl_status_t) esl_event_add_body(esl_event_t *event, const char *fmt, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -791,7 +807,7 @@ ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, es
|
||||
if (encode) {
|
||||
esl_url_encode(hp->value, encode_buf, encode_len);
|
||||
} else {
|
||||
esl_snprintf(encode_buf, encode_len, "[%s]", hp->value);
|
||||
esl_snprintf(encode_buf, encode_len, "%s", hp->value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -205,6 +205,15 @@ ESLevent *ESLconnection::sendEvent(ESLevent *send_me)
|
||||
return new ESLevent("server_disconnected");
|
||||
}
|
||||
|
||||
int ESLconnection::sendMSG(ESLevent *send_me, const char *uuid)
|
||||
{
|
||||
if (esl_sendmsg(&handle, send_me->event, uuid) == ESL_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ESLevent *ESLconnection::recvEvent()
|
||||
{
|
||||
if (esl_recv_event(&handle, 1, NULL) == ESL_SUCCESS) {
|
||||
|
@ -61,12 +61,22 @@ typedef enum {
|
||||
|
||||
#ifdef WIN32
|
||||
#define ESL_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED
|
||||
#define ESL_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FGREEN FOREGROUND_GREEN
|
||||
#define ESL_SEQ_BRED FOREGROUND_RED
|
||||
#define ESL_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED
|
||||
#define ESL_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BGREEN FOREGROUND_GREEN
|
||||
#define ESL_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN
|
||||
#define ESL_SEQ_DEFAULT_COLOR ESL_SEQ_FWHITE
|
||||
#define ESL_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BBLUE FOREGROUND_BLUE
|
||||
#define ESL_SEQ_FBLACK 0 | FOREGROUND_INTENSITY
|
||||
#define ESL_SEQ_BBLACK 0
|
||||
#else
|
||||
#define ESL_SEQ_ESC "\033["
|
||||
/* Ansi Control character suffixes */
|
||||
@ -397,6 +407,14 @@ ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, con
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_sendevent(esl_handle_t *handle, esl_event_t *event);
|
||||
|
||||
/*!
|
||||
\brief Send an event as a message to be parsed
|
||||
\param handle Handle to which the event should be sent
|
||||
\param event Event to be sent
|
||||
\param uuid a specific uuid if not the default
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_sendmsg(esl_handle_t *handle, esl_event_t *event, const char *uuid);
|
||||
|
||||
/*!
|
||||
\brief Connect a handle to a host/port with a specific password. This will also authenticate against the server
|
||||
\param handle Handle to connect
|
||||
|
@ -298,6 +298,7 @@ ESL_DECLARE(esl_status_t) esl_event_create_json(esl_event_t **event, const char
|
||||
\note the body parameter can be shadowed by the esl_event_reserve_subclass_detailed function
|
||||
*/
|
||||
ESL_DECLARE(esl_status_t) esl_event_add_body(esl_event_t *event, const char *fmt, ...);
|
||||
ESL_DECLARE(esl_status_t) esl_event_set_body(esl_event_t *event, const char *body);
|
||||
|
||||
/*!
|
||||
\brief Create a new event assuming it will not be custom event and therefore hiding the unused parameters
|
||||
|
@ -86,6 +86,7 @@ class ESLconnection {
|
||||
ESLevent *api(const char *cmd, const char *arg = NULL);
|
||||
ESLevent *bgapi(const char *cmd, const char *arg = NULL, const char *job_uuid = NULL);
|
||||
ESLevent *sendEvent(ESLevent *send_me);
|
||||
int sendMSG(ESLevent *send_me, const char *uuid = NULL);
|
||||
ESLevent *recvEvent();
|
||||
ESLevent *recvEventTimed(int ms);
|
||||
ESLevent *filter(const char *header, const char *value);
|
||||
|
@ -248,6 +248,14 @@ ftmod_r2_la_LDFLAGS = -shared -module -avoid-version -lopenr2
|
||||
ftmod_r2_la_LIBADD = libfreetdm.la
|
||||
endif
|
||||
|
||||
if HAVE_MISDN
|
||||
mod_LTLIBRARIES += ftmod_misdn.la
|
||||
ftmod_misdn_la_SOURCES = $(SRC)/ftmod/ftmod_misdn/ftmod_misdn.c
|
||||
ftmod_misdn_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) $(MISDN_CFLAGS)
|
||||
ftmod_misdn_la_LDFLAGS = -shared -module -avoid-version
|
||||
ftmod_misdn_la_LIBADD = libfreetdm.la
|
||||
endif
|
||||
|
||||
dox doxygen:
|
||||
doxygen $(FT_SRCDIR)/docs/Doxygen.conf
|
||||
|
||||
|
@ -54,6 +54,9 @@ fi
|
||||
|
||||
AC_SUBST([confdir])
|
||||
|
||||
DEFAULT_INCLUDES="-I. -I./src/include -I$(srcdir)"
|
||||
AC_SUBST([DEFAULT_INCLUDES])
|
||||
|
||||
# Where to install the modules
|
||||
AC_ARG_WITH([modinstdir],
|
||||
[AS_HELP_STRING([--with-modinstdir=DIR], [Install modules into this location (default: ${prefix}/mod)])],
|
||||
@ -364,6 +367,42 @@ then
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_LIBISDN], [test "${HAVE_LIBISDN}" = "yes"])
|
||||
|
||||
|
||||
##
|
||||
# mISDN dependencies
|
||||
#
|
||||
HAVE_MISDN="no"
|
||||
AC_ARG_WITH([misdn],
|
||||
[AS_HELP_STRING([--with-misdn], [Install ftmod_misdn (mISDN I/O plugin)])],
|
||||
[case "${withval}" in
|
||||
no|yes) with_misdn="${withval}" ;;
|
||||
*) AC_MSG_ERROR([Invalid value \"${with_misdn}\" for --with-misdn option]) ;;
|
||||
esac],
|
||||
[with_misdn="auto"]
|
||||
)
|
||||
AS_IF([test "${with_misdn}" != "no"],
|
||||
[AC_MSG_RESULT([${as_nl}<<>> ftmod_misdn (Linux mISDN I/O plugin)])
|
||||
AC_CHECK_FUNCS([timerfd_create],,
|
||||
[AS_IF([test "${with_misdn}" = "yes"],
|
||||
[AC_MSG_ERROR([no timerfd support in libc])],
|
||||
[AC_MSG_NOTICE([no timerfd support in libc])]
|
||||
)]
|
||||
)
|
||||
AC_CHECK_HEADER([mISDN/mISDNif.h],,
|
||||
[AS_IF([test "${with_misdn}" = "yes"],
|
||||
[AC_MSG_ERROR([mISDN/mISDNif.h not found])],
|
||||
[AC_MSG_NOTICE([mISDN/mISDNif.h not found])]
|
||||
)],
|
||||
[#include <sys/socket.h>]
|
||||
)
|
||||
AS_IF([test "${ac_cv_func_timerfd_create}" = "yes" -a "${ac_cv_header_mISDN_mISDNif_h}" = "yes"],
|
||||
[HAVE_MISDN="yes"],
|
||||
[AC_MSG_NOTICE([Some required dependencies are missing, module disabled])]
|
||||
)]
|
||||
)
|
||||
AM_CONDITIONAL([HAVE_MISDN], [test "${HAVE_MISDN}" = "yes"])
|
||||
|
||||
|
||||
AC_MSG_RESULT([${as_nl}<<>> Creating output files])
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
@ -389,6 +428,7 @@ AC_MSG_RESULT([
|
||||
ftmod_pritap....................... ${HAVE_PRITAP}
|
||||
I/O:
|
||||
ftmod_wanpipe...................... ${HAVE_LIBSANGOMA}
|
||||
ftmod_misdn........................ ${HAVE_MISDN}
|
||||
|
||||
===============================================================================
|
||||
])
|
||||
|
@ -34,6 +34,15 @@
|
||||
#include <switch.h>
|
||||
#include "freetdm.h"
|
||||
|
||||
//#define CUDATEL_DEBUG
|
||||
#ifdef CUDATEL_DEBUG
|
||||
#ifndef _BSD_SOURCE
|
||||
#define _BSD_SOURCE
|
||||
#endif
|
||||
#include <execinfo.h>
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
|
||||
#ifndef __FUNCTION__
|
||||
#define __FUNCTION__ __SWITCH_FUNC__
|
||||
#endif
|
||||
@ -495,7 +504,14 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
switch_channel_t *channel = NULL;
|
||||
private_t *tech_pvt = NULL;
|
||||
ftdm_chan_type_t chantype;
|
||||
const char *name = NULL;
|
||||
int span_id = 0;
|
||||
int chan_id = 0;
|
||||
int t = 0;
|
||||
uint32_t tokencnt;
|
||||
char *uuid = NULL;
|
||||
const char *token = NULL;
|
||||
uint8_t uuid_found = 0;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
@ -503,13 +519,64 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
/* ignore any further I/O requests, we're hanging up already! */
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
|
||||
span_id = tech_pvt->ftdmchan ? ftdm_channel_get_span_id(tech_pvt->ftdmchan) : 0;
|
||||
chan_id = tech_pvt->ftdmchan ? ftdm_channel_get_id(tech_pvt->ftdmchan) : 0;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP ENTER\n", span_id, chan_id, name);
|
||||
|
||||
/* First verify this call has a device attached */
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s does not have any ftdmchan attached\n", name);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now verify the device is still attached to this call :-)
|
||||
* Sometimes the FS core takes too long (more than 3 seconds) in calling
|
||||
* channel_on_hangup() and the FreeTDM core decides to take the brute
|
||||
* force approach and hangup and detach themselves from the call. Later
|
||||
* when FS finally comes around, we might end up hanging up the device
|
||||
* attached to another call, this verification avoids that. */
|
||||
uuid = switch_core_session_get_uuid(session);
|
||||
tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
|
||||
for (t = 0; t < tokencnt; t++) {
|
||||
token = ftdm_channel_get_token(tech_pvt->ftdmchan, t);
|
||||
if (!zstr(token) && !strcasecmp(uuid, token)) {
|
||||
uuid_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!uuid_found) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Device [%d:%d] is no longer attached to %s. Nothing to do.\n", span_id, chan_id, name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef CUDATEL_DEBUG
|
||||
{
|
||||
pid_t tid = 0;
|
||||
size_t size = 0;
|
||||
char **symbols = NULL;
|
||||
void *stacktrace[50];
|
||||
int si = 0;
|
||||
size = backtrace(stacktrace, ftdm_array_len(stacktrace));
|
||||
symbols = backtrace_symbols(stacktrace, size);
|
||||
tid = syscall(SYS_gettid);
|
||||
for (si = 0; si < size; si++) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d][tid:%d] %s -> %s\n",
|
||||
span_id, chan_id, tid, name, symbols[si]);
|
||||
}
|
||||
free(symbols);
|
||||
}
|
||||
#endif
|
||||
|
||||
ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session));
|
||||
|
||||
chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);
|
||||
chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);
|
||||
switch (chantype) {
|
||||
case FTDM_CHAN_TYPE_FXO:
|
||||
case FTDM_CHAN_TYPE_EM:
|
||||
@ -520,7 +587,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
case FTDM_CHAN_TYPE_FXS:
|
||||
{
|
||||
if (!ftdm_channel_call_check_busy(tech_pvt->ftdmchan) && !ftdm_channel_call_check_done(tech_pvt->ftdmchan)) {
|
||||
tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
|
||||
if (tokencnt) {
|
||||
cycle_foreground(tech_pvt->ftdmchan, 0, NULL);
|
||||
} else {
|
||||
@ -548,9 +614,6 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
|
||||
end:
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
|
||||
switch_mutex_lock(globals.mutex);
|
||||
globals.calls--;
|
||||
if (globals.calls < 0) {
|
||||
@ -558,6 +621,7 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
||||
}
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[%d:%d] %s CHANNEL HANGUP EXIT\n", span_id, chan_id, name);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -629,6 +693,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
int total_to;
|
||||
int chunk, do_break = 0;
|
||||
uint32_t span_id, chan_id;
|
||||
const char *name = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
@ -636,17 +701,18 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "TFLAG_DEAD is set\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
/* Digium Cards sometimes timeout several times in a row here.
|
||||
Yes, we support digium cards, ain't we nice.......
|
||||
@ -678,7 +744,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
}
|
||||
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "TFLAG_IO is not set\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -686,7 +752,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, chunk);
|
||||
|
||||
if (status == FTDM_FAIL) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to wait for I/O\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -694,7 +760,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_HOLD)) {
|
||||
total_to -= chunk;
|
||||
if (total_to <= 0) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Too many timeouts while waiting for I/O\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Too many timeouts while waiting I/O in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@ -707,9 +773,9 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
|
||||
len = tech_pvt->read_frame.buflen;
|
||||
if (ftdm_channel_read(tech_pvt->ftdmchan, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "failed to read from device %d:%d\n", span_id, chan_id);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
if (++tech_pvt->read_error > FTDM_MAX_READ_WRITE_ERRORS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "too many I/O read errors on device %d:%d!\n", span_id, chan_id);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "too many I/O read errors on channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
@ -730,18 +796,18 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
for (p = dtmf; p && *p; p++) {
|
||||
if (is_dtmf(*p)) {
|
||||
_dtmf.digit = *p;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s\n", *p, switch_channel_get_name(channel));
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id);
|
||||
switch_channel_queue_dtmf(channel, &_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "clearing IO in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
|
||||
@ -750,8 +816,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
private_t *tech_pvt = NULL;
|
||||
ftdm_size_t len;
|
||||
unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
|
||||
const char *name = "(none)";
|
||||
ftdm_wait_flag_t wflags = FTDM_WRITE;
|
||||
uint32_t span_id, chan_id;
|
||||
uint32_t span_id = 0, chan_id = 0;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
@ -759,7 +826,17 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
name = switch_channel_get_name(channel);
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
@ -768,17 +845,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
}
|
||||
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!tech_pvt->ftdmchan) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan);
|
||||
|
||||
|
||||
if (switch_test_flag(frame, SFF_CNG)) {
|
||||
frame->data = data;
|
||||
frame->buflen = sizeof(data);
|
||||
@ -793,16 +863,16 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10);
|
||||
|
||||
if (!(wflags & FTDM_WRITE)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready)\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write note ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
len = frame->datalen;
|
||||
if (ftdm_channel_write(tech_pvt->ftdmchan, frame->data, frame->buflen, &len) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "failed to write to device %d:%d\n", span_id, chan_id);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
if (++tech_pvt->write_error > FTDM_MAX_READ_WRITE_ERRORS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG,
|
||||
SWITCH_LOG_ERROR, "too many I/O write errors on device %d:%d!\n", span_id, chan_id);
|
||||
SWITCH_LOG_ERROR, "Too many I/O write errors on channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
@ -812,7 +882,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error writing to channel %s device %d:%d!\n", name, span_id, chan_id);
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
@ -2370,7 +2440,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_channel_hangup(channel, caller_data->hangup_cause);
|
||||
ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
}
|
||||
@ -3802,9 +3871,139 @@ typedef switch_status_t (*ftdm_cli_function_t)(ftdm_cli_entry_t *cli, const char
|
||||
int argc, char *argv[])
|
||||
static void print_usage(switch_stream_handle_t *stream, ftdm_cli_entry_t *cli);
|
||||
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_voice_detect)
|
||||
|
||||
typedef struct cmd_ioread_data {
|
||||
int num_times;
|
||||
uint32_t interval;
|
||||
ftdm_span_t *span;
|
||||
ftdm_channel_t *fchan;
|
||||
switch_memory_pool_t *pool;
|
||||
int already_open;
|
||||
} cmd_ioread_data_t;
|
||||
|
||||
static void *SWITCH_THREAD_FUNC ioread_thread(switch_thread_t *thread, void *obj)
|
||||
{
|
||||
print_usage(stream, cli);
|
||||
ftdm_wait_flag_t wflags = FTDM_READ;
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
unsigned char iobuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
||||
cmd_ioread_data_t *data = obj;
|
||||
int span_id = ftdm_span_get_id(data->span);
|
||||
int chan_id = ftdm_channel_get_id(data->fchan);
|
||||
ftdm_size_t len = ftdm_channel_get_io_packet_len(data->fchan);
|
||||
ftdm_size_t origlen = len;
|
||||
unsigned int pbuf[5];
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
"Started ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n",
|
||||
data->num_times, data->interval, len, span_id, chan_id);
|
||||
|
||||
while (ftdm_running() && data->num_times > 0) {
|
||||
data->num_times--;
|
||||
|
||||
wflags = FTDM_READ;
|
||||
|
||||
status = ftdm_channel_wait(data->fchan, &wflags, (data->interval * 10));
|
||||
|
||||
if (status == FTDM_FAIL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to wait for IO in device %d:%d!\n", span_id, chan_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status == FTDM_TIMEOUT) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Timed out while waiting I/O in device %d:%d!\n", span_id, chan_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
len = origlen;
|
||||
if (ftdm_channel_read(data->fchan, iobuf, &len) != FTDM_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from device %d:%d!\n", span_id, chan_id);
|
||||
continue;
|
||||
}
|
||||
pbuf[0] = iobuf[0];
|
||||
pbuf[1] = iobuf[1];
|
||||
pbuf[2] = iobuf[2];
|
||||
pbuf[3] = iobuf[3];
|
||||
pbuf[4] = iobuf[4];
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read 0x%1X 0x%1X 0x%1X 0x%1X 0x%1X\n",
|
||||
pbuf[0], pbuf[1], pbuf[2], pbuf[3], pbuf[4]);
|
||||
}
|
||||
|
||||
if (!data->already_open) {
|
||||
ftdm_channel_close(&data->fchan);
|
||||
}
|
||||
|
||||
switch_core_destroy_memory_pool(&data->pool);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
"Done ioread thread (times = %d, interval = %ums, len = %"FTDM_SIZE_FMT", span = %d, chan = %d\n",
|
||||
data->num_times, data->interval, origlen, span_id, chan_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FTDM_CLI_DECLARE(ftdm_cmd_ioread)
|
||||
{
|
||||
char *span_name = NULL;
|
||||
int channo = 0;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
switch_threadattr_t *attr = NULL;
|
||||
switch_thread_t *thread = NULL;
|
||||
|
||||
cmd_ioread_data_t *thdata;
|
||||
cmd_ioread_data_t data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.num_times = 1;
|
||||
|
||||
if (argc < 3) {
|
||||
print_usage(stream, cli);
|
||||
goto end;
|
||||
}
|
||||
|
||||
span_name = argv[1];
|
||||
|
||||
ftdm_span_find_by_name(span_name, &data.span);
|
||||
if (!data.span) {
|
||||
stream->write_function(stream, "-ERR span %s not found\n", span_name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
channo = atoi(argv[2]);
|
||||
|
||||
status = ftdm_channel_open(ftdm_span_get_id(data.span), channo, &data.fchan);
|
||||
if (!data.fchan || (status != FTDM_SUCCESS && status != FTDM_EBUSY)) {
|
||||
stream->write_function(stream, "-ERR Failed to open channel %d in span %s\n", channo, span_name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (status == FTDM_EBUSY) {
|
||||
data.already_open = 1;
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
data.num_times = atoi(argv[3]);
|
||||
if (data.num_times < 1) {
|
||||
data.num_times = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 4) {
|
||||
data.interval = atoi(argv[4]);
|
||||
}
|
||||
|
||||
if (data.interval <= 0 || data.interval > 10000) {
|
||||
data.interval = ftdm_channel_get_io_interval(data.fchan);
|
||||
}
|
||||
|
||||
switch_core_new_memory_pool(&data.pool);
|
||||
|
||||
thdata = switch_core_alloc(data.pool, sizeof(data));
|
||||
memcpy(thdata, &data, sizeof(*thdata));
|
||||
|
||||
switch_threadattr_create(&attr, data.pool);
|
||||
switch_threadattr_detach_set(attr, 1);
|
||||
switch_threadattr_stacksize_set(attr, SWITCH_THREAD_STACKSIZE);
|
||||
switch_thread_create(&thread, attr, ioread_thread, thdata, data.pool);
|
||||
|
||||
end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -4452,7 +4651,7 @@ static ftdm_cli_entry_t ftdm_cli_options[] =
|
||||
{ "dtmf", "on|off <span_id|span_name> [<chan_id>]", "::[on:off", ftdm_cmd_dtmf },
|
||||
{ "queuesize", "<rxsize> <txsize> <span_id|span_name> [<chan_id>]", "", ftdm_cmd_queuesize },
|
||||
{ "iostats", "enable|disable|flush|print <span_id|span_name> <chan_id>", "::[enable:disable:flush:print", ftdm_cmd_iostats },
|
||||
{ "voice_detect", "[on|off] <span_id|span_name> [<chan_id>]", "::[on:off", ftdm_cmd_voice_detect },
|
||||
{ "ioread", "<span_id|span_name> <chan_id> [num_times] [interval]", "", ftdm_cmd_ioread },
|
||||
|
||||
/* Fake handlers as they are handled within freetdm library,
|
||||
* we should provide a way inside freetdm to query for completions from signaling modules */
|
||||
|
@ -6,7 +6,7 @@ int main(int argc, char *argv[])
|
||||
int fd, b;
|
||||
short sln[512] = {0};
|
||||
teletone_dtmf_detect_state_t dtmf_detect = {0};
|
||||
char digit_str[128] = "";
|
||||
teletone_hit_type_t hit;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Arg Error!\n");
|
||||
@ -21,10 +21,31 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
while((b = read(fd, sln, 320)) > 0) {
|
||||
char digit_char;
|
||||
unsigned int dur;
|
||||
|
||||
teletone_dtmf_detect(&dtmf_detect, sln, b / 2);
|
||||
teletone_dtmf_get(&dtmf_detect, digit_str, sizeof(digit_str));
|
||||
if (*digit_str) {
|
||||
printf("digit: %s\n", digit_str);
|
||||
if ((hit = teletone_dtmf_get(&dtmf_detect, &digit_char, &dur))) {
|
||||
const char *hs = NULL;
|
||||
|
||||
|
||||
switch(hit) {
|
||||
case TT_HIT_BEGIN:
|
||||
hs = "begin";
|
||||
break;
|
||||
|
||||
case TT_HIT_MIDDLE:
|
||||
hs = "middle";
|
||||
break;
|
||||
|
||||
case TT_HIT_END:
|
||||
hs = "end";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("%s digit: %c\n", hs, digit_char);
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
|
@ -649,9 +649,6 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
|
||||
if (span->fio->span_destroy(span) != FTDM_SUCCESS) {
|
||||
status = FTDM_FAIL;
|
||||
}
|
||||
ftdm_safe_free(span->type);
|
||||
ftdm_safe_free(span->name);
|
||||
ftdm_safe_free(span->dtmf_hangup);
|
||||
}
|
||||
|
||||
/* destroy final basic resources of the span data structure */
|
||||
@ -1858,7 +1855,14 @@ static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm
|
||||
goto done;
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(check->mutex);
|
||||
ftdm_channel_lock(check);
|
||||
|
||||
if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
|
||||
/* let them know is already open, but return the channel anyway */
|
||||
status = FTDM_EBUSY;
|
||||
*ftdmchan = check;
|
||||
goto unlockchan;
|
||||
}
|
||||
|
||||
/* The following if's and gotos replace a big if (this || this || this || this) else { nothing; } */
|
||||
|
||||
@ -1905,7 +1909,7 @@ openchan:
|
||||
goto done;
|
||||
|
||||
unlockchan:
|
||||
ftdm_mutex_unlock(check->mutex);
|
||||
ftdm_channel_unlock(check);
|
||||
|
||||
done:
|
||||
ftdm_mutex_unlock(globals.mutex);
|
||||
@ -3855,7 +3859,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_process_media(ftdm_channel_t *ftdmchan, v
|
||||
uint8_t sln_buf[1024] = {0};
|
||||
int16_t *sln;
|
||||
ftdm_size_t slen = 0;
|
||||
char digit_str[80] = "";
|
||||
|
||||
if (ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
|
||||
sln = data;
|
||||
@ -3956,13 +3959,18 @@ 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)) {
|
||||
teletone_dtmf_detect(&ftdmchan->dtmf_detect, sln, (int)slen);
|
||||
teletone_dtmf_get(&ftdmchan->dtmf_detect, digit_str, sizeof(digit_str));
|
||||
teletone_hit_type_t hit;
|
||||
char digit_char;
|
||||
uint32_t dur;
|
||||
|
||||
if(*digit_str) {
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_CALLWAITING && (*digit_str == 'D' || *digit_str == 'A')) {
|
||||
if ((hit = teletone_dtmf_detect(&ftdmchan->dtmf_detect, sln, (int)slen)) == TT_HIT_END) {
|
||||
teletone_dtmf_get(&ftdmchan->dtmf_detect, &digit_char, &dur);
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_CALLWAITING && (digit_char == 'D' || digit_char == 'A')) {
|
||||
ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++;
|
||||
} else {
|
||||
char digit_str[2] = { digit_char, 0};
|
||||
|
||||
if (!ftdmchan->span->sig_dtmf || (ftdmchan->span->sig_dtmf(ftdmchan, (const char*)digit_str) != FTDM_BREAK)) {
|
||||
ftdm_channel_queue_dtmf(ftdmchan, digit_str);
|
||||
}
|
||||
@ -4568,7 +4576,7 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, const
|
||||
*configured = 0;
|
||||
*configured = span->fio->configure_span(span, str, chan_config->type, chan_config->name, chan_config->number);
|
||||
if (!*configured) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "%d:Failed to configure span", span->span_id);
|
||||
ftdm_log(FTDM_LOG_ERROR, "%d:Failed to configure span\n", span->span_id);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
@ -5468,10 +5476,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||
if (sigmsg->channel) {
|
||||
fchan = sigmsg->channel;
|
||||
ftdm_channel_lock(fchan);
|
||||
sigmsg->chan_id = fchan->chan_id;
|
||||
sigmsg->span_id = fchan->span_id;
|
||||
sigmsg->call_id = fchan->caller_data.call_id;
|
||||
sigmsg->call_priv = fchan->caller_data.priv;
|
||||
}
|
||||
|
||||
/* some core things to do on special events */
|
||||
@ -5561,6 +5565,14 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||
|
||||
}
|
||||
|
||||
if (fchan) {
|
||||
/* set members of the sigmsg that must be present for all events */
|
||||
sigmsg->chan_id = fchan->chan_id;
|
||||
sigmsg->span_id = fchan->span_id;
|
||||
sigmsg->call_id = fchan->caller_data.call_id;
|
||||
sigmsg->call_priv = fchan->caller_data.priv;
|
||||
}
|
||||
|
||||
/* if the signaling module uses a queue for signaling notifications, then enqueue it */
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||
ftdm_span_queue_signal(span, sigmsg);
|
||||
@ -5774,6 +5786,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1938,6 +1938,14 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_sleep(5000);
|
||||
}
|
||||
out:
|
||||
/* close d-channel, if set */
|
||||
if (isdn_data->dchan) {
|
||||
if (ftdm_channel_close(&isdn_data->dchan) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to close D-Channel %d:%d\n",
|
||||
ftdm_channel_get_span_id(isdn_data->dchan), ftdm_channel_get_id(isdn_data->dchan));
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", ftdm_span_get_id(span));
|
||||
|
||||
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
|
||||
|
1807
libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c
Normal file
1807
libs/freetdm/src/ftmod/ftmod_misdn/ftmod_misdn.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -69,6 +69,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
||||
set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
|
||||
set_redir_num(ftdmchan, &conEvnt.redirNmb);
|
||||
set_calling_name(ftdmchan, &conEvnt);
|
||||
|
||||
/* set_facility_ie will overwrite Calling Name for NI-2 if user specifies custom Facility IE */
|
||||
set_facility_ie(ftdmchan, &conEvnt.facilityStr);
|
||||
set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind);
|
||||
|
||||
|
@ -719,12 +719,19 @@ ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
|
||||
} else {
|
||||
switch (signal_data->switchtype) {
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
/* TODO: Need to send the caller ID as a facility IE */
|
||||
|
||||
#ifdef SNGISDN_SUPPORT_CALLING_NAME_IN_FACILITY
|
||||
{
|
||||
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
sng_isdn_encode_facility_caller_name(caller_data->cid_name, conEvnt->facilityStr.facilityStr.val, &conEvnt->facilityStr.facilityStr.len);
|
||||
conEvnt->facilityStr.eh.pres = PRSNT_NODEF;
|
||||
conEvnt->facilityStr.facilityStr.pres = PRSNT_NODEF;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case SNGISDN_SWITCH_EUROISDN:
|
||||
if (signal_data->signalling != SNGISDN_SIGNALING_NET) {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
/* follow through */
|
||||
case SNGISDN_SWITCH_5ESS:
|
||||
|
@ -39,6 +39,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef WP_DEBUG_IO
|
||||
#define _BSD_SOURCE
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
|
||||
#ifdef __sun
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
@ -99,6 +104,17 @@ static struct {
|
||||
uint32_t ring_off_ms;
|
||||
} wp_globals;
|
||||
|
||||
typedef struct {
|
||||
sangoma_wait_obj_t *waitobj;
|
||||
#ifdef WP_DEBUG_IO
|
||||
/* record the last reader threads */
|
||||
pid_t readers[10];
|
||||
int rindex;
|
||||
ftdm_time_t last_read;
|
||||
#endif
|
||||
} wp_channel_t;
|
||||
#define WP_GET_WAITABLE(fchan) ((wp_channel_t *)((fchan)->io_data))->waitobj
|
||||
|
||||
/* a bunch of this stuff should go into the wanpipe_tdm_api_iface.h */
|
||||
|
||||
FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
||||
@ -123,7 +139,7 @@ static __inline__ int tdmv_api_wait_socket(ftdm_channel_t *ftdmchan, int timeout
|
||||
int err;
|
||||
uint32_t inflags = *flags;
|
||||
uint32_t outflags = 0;
|
||||
sangoma_wait_obj_t *sangoma_wait_obj = ftdmchan->io_data;
|
||||
sangoma_wait_obj_t *sangoma_wait_obj = WP_GET_WAITABLE(ftdmchan);
|
||||
|
||||
if (timeout == -1) {
|
||||
timeout = SANGOMA_WAIT_INFINITE;
|
||||
@ -254,9 +270,13 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
||||
}
|
||||
|
||||
if (ftdm_span_add_channel(span, sockfd, type, &chan) == FTDM_SUCCESS) {
|
||||
wp_channel_t *wpchan = NULL;
|
||||
wanpipe_tdm_api_t tdm_api;
|
||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
wpchan = ftdm_calloc(1, sizeof(*wpchan));
|
||||
ftdm_assert(wpchan != NULL, "wpchan alloc failed\n");
|
||||
chan->io_data = wpchan;
|
||||
/* we need SANGOMA_DEVICE_WAIT_OBJ_SIG and not SANGOMA_DEVICE_WAIT_OBJ alone because we need to call
|
||||
* sangoma_wait_obj_sig to wake up any I/O waiters when closing the channel (typically on ftdm shutdown)
|
||||
* this adds an extra pair of file descriptors to the waitable object
|
||||
@ -266,7 +286,7 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
|
||||
ftdm_log(FTDM_LOG_ERROR, "failure create waitable object for s%dc%d\n", spanno, x);
|
||||
continue;
|
||||
}
|
||||
chan->io_data = sangoma_wait_obj;
|
||||
WP_GET_WAITABLE(chan) = sangoma_wait_obj;
|
||||
#endif
|
||||
|
||||
chan->physical_span_id = spanno;
|
||||
@ -580,9 +600,16 @@ static FIO_OPEN_FUNCTION(wanpipe_open)
|
||||
static FIO_CLOSE_FUNCTION(wanpipe_close)
|
||||
{
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
sangoma_wait_obj_t *waitobj = ftdmchan->io_data;
|
||||
sangoma_wait_obj_t *waitobj = WP_GET_WAITABLE(ftdmchan);
|
||||
/* kick any I/O waiters */
|
||||
sangoma_wait_obj_signal(waitobj);
|
||||
#ifdef WP_DEBUG_IO
|
||||
{
|
||||
wp_channel_t *wchan = ftdmchan->io_data;
|
||||
memset(wchan->readers, 0, sizeof(wchan->readers));
|
||||
wchan->rindex = 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
@ -860,7 +887,7 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t
|
||||
/* HDLC channels do not always transmit, so its ok for drivers to fill with idle
|
||||
* also do not report idle warning when we just started transmitting */
|
||||
if (ftdmchan->iostats.tx.packets && FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Tx idle changed from %d to %d\n",
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Tx idle changed from %d to %d\n",
|
||||
ftdmchan->iostats.tx.idle_packets, tx_stats->wp_api_tx_hdr_tx_idle_packets);
|
||||
}
|
||||
ftdmchan->iostats.tx.idle_packets = tx_stats->wp_api_tx_hdr_tx_idle_packets;
|
||||
@ -913,21 +940,21 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
|
||||
}
|
||||
|
||||
if (ftdmchan->iostats.rx.queue_len >= (0.8 * ftdmchan->iostats.rx.queue_size)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded 80% threshold (%d/%d)\n",
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length exceeded 80% threshold (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
|
||||
} else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue length reduced 80% threshold (%d/%d)\n",
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue length reduced 80% threshold (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
|
||||
}
|
||||
|
||||
if (ftdmchan->iostats.rx.queue_len >= ftdmchan->iostats.rx.queue_size) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n",
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue Full (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
|
||||
} else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue no longer full (%d/%d)\n",
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Rx Queue no longer full (%d/%d)\n",
|
||||
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
|
||||
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
|
||||
}
|
||||
@ -950,10 +977,44 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
|
||||
static FIO_READ_FUNCTION(wanpipe_read)
|
||||
{
|
||||
int rx_len = 0;
|
||||
int rq_len = (int)*datalen;
|
||||
wp_tdm_api_rx_hdr_t hdrframe;
|
||||
|
||||
memset(&hdrframe, 0, sizeof(hdrframe));
|
||||
#ifdef WP_DEBUG_IO
|
||||
wp_channel_t *wchan = ftdmchan->io_data;
|
||||
ftdm_time_t time_diff = 0;
|
||||
pid_t previous_thread = 1;
|
||||
pid_t current_thread = 0;
|
||||
int previous_thread_index = 0;
|
||||
|
||||
previous_thread_index = wchan->rindex == 0 ? (ftdm_array_len(wchan->readers) - 1) : wchan->rindex - 1;
|
||||
previous_thread = wchan->readers[previous_thread_index];
|
||||
current_thread = syscall(SYS_gettid);
|
||||
if (current_thread && current_thread != wchan->readers[wchan->rindex]) {
|
||||
if (!wchan->readers[wchan->rindex]) {
|
||||
wchan->readers[wchan->rindex] = current_thread;
|
||||
/* first read */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Initial reader thread is %d\n", current_thread);
|
||||
previous_thread = current_thread;
|
||||
} else {
|
||||
previous_thread = wchan->readers[wchan->rindex];
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Changed reader thread from %d to %d (rindex = %d)\n",
|
||||
previous_thread, current_thread, wchan->rindex);
|
||||
if (wchan->rindex == (ftdm_array_len(wchan->readers) - 1)) {
|
||||
wchan->rindex = 0;
|
||||
} else {
|
||||
wchan->rindex++;
|
||||
}
|
||||
wchan->readers[wchan->rindex] = current_thread;
|
||||
}
|
||||
}
|
||||
ftdm_time_t curr = ftdm_current_time_in_ms();
|
||||
if (wchan->last_read) {
|
||||
time_diff = curr - wchan->last_read;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&hdrframe, 0, sizeof(hdrframe));
|
||||
rx_len = sangoma_readmsg_tdm(ftdmchan->sockfd, &hdrframe, (int)sizeof(hdrframe), data, (int)*datalen, 0);
|
||||
*datalen = rx_len;
|
||||
|
||||
@ -963,14 +1024,20 @@ static FIO_READ_FUNCTION(wanpipe_read)
|
||||
}
|
||||
|
||||
if (rx_len < 0) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
|
||||
#ifdef WP_DEBUG_IO
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read %d bytes from sangoma device: %s (%d) "
|
||||
"(read time diff = %llums, prev thread = %d, curr thread = %d)\n", rq_len, strerror(errno), rx_len,
|
||||
time_diff, previous_thread, current_thread);
|
||||
#else
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read %d bytes from sangoma device: %s (%d)\n", rq_len, strerror(errno), rx_len);
|
||||
#endif
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
|
||||
wanpipe_read_stats(ftdmchan, &hdrframe);
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1116,7 +1183,7 @@ FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event)
|
||||
if (!ftdmchan->io_data) {
|
||||
continue; /* should never happen but happens when shutting down */
|
||||
}
|
||||
pfds[j] = ftdmchan->io_data;
|
||||
pfds[j] = WP_GET_WAITABLE(ftdmchan);
|
||||
inflags[j] = chan_events;
|
||||
#else
|
||||
memset(&pfds[j], 0, sizeof(pfds[j]));
|
||||
@ -1578,10 +1645,10 @@ static FIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
|
||||
{
|
||||
#ifdef LIBSANGOMA_VERSION
|
||||
if (ftdmchan->io_data) {
|
||||
sangoma_wait_obj_t *sangoma_wait_obj;
|
||||
sangoma_wait_obj = ftdmchan->io_data;
|
||||
ftdmchan->io_data = NULL;
|
||||
sangoma_wait_obj_t *sangoma_wait_obj = WP_GET_WAITABLE(ftdmchan);
|
||||
sangoma_wait_obj_delete(&sangoma_wait_obj);
|
||||
ftdm_safe_free(ftdmchan->io_data);
|
||||
ftdmchan->io_data = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1612,7 +1679,8 @@ static FIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
|
||||
*/
|
||||
static FIO_IO_LOAD_FUNCTION(wanpipe_init)
|
||||
{
|
||||
assert(fio != NULL);
|
||||
ftdm_assert(fio != NULL, "fio should not be null\n");
|
||||
|
||||
memset(&wanpipe_interface, 0, sizeof(wanpipe_interface));
|
||||
|
||||
wp_globals.codec_ms = 20;
|
||||
|
@ -4,10 +4,10 @@
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mftilla Public License Version
|
||||
* 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.mftilla.org/MPL/
|
||||
* 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
|
||||
@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the freetdm library. Any use or distribution of this
|
||||
* source code outside the scope of the freetdm library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
@ -2,13 +2,60 @@
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
|
||||
*
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Stephen Underwood <steveu@coppice.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* The the original interface designed by Steve Underwood was preserved to retain
|
||||
*the optimizations when considering DTMF tones though the names were changed in the interest
|
||||
* of namespace.
|
||||
*
|
||||
* Much less efficient expansion interface was added to allow for the detection of
|
||||
* a single arbitrary tone combination which may also exceed 2 simultaneous tones.
|
||||
* (controlled by compile time constant TELETONE_MAX_TONES)
|
||||
*
|
||||
* Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
* libteletone_detect.c Tone Detection Code
|
||||
*
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.h - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the freetdm library. Any use or distribution of this
|
||||
* source code outside the scope of the freetdm library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
@ -41,20 +88,6 @@
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.h - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBTELETONE_DETECT_H
|
||||
@ -101,6 +134,14 @@ extern "C" {
|
||||
#define BLOCK_LEN 102
|
||||
#define M_TWO_PI 2.0*M_PI
|
||||
|
||||
typedef enum {
|
||||
TT_HIT_NONE = 0,
|
||||
TT_HIT_BEGIN = 1,
|
||||
TT_HIT_MIDDLE = 2,
|
||||
TT_HIT_END = 3
|
||||
} teletone_hit_type_t;
|
||||
|
||||
|
||||
/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
|
||||
typedef struct {
|
||||
float v2;
|
||||
@ -114,16 +155,19 @@ extern "C" {
|
||||
int hit2;
|
||||
int hit3;
|
||||
int hit4;
|
||||
int mhit;
|
||||
int dur;
|
||||
int zc;
|
||||
|
||||
|
||||
teletone_goertzel_state_t row_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
|
||||
float energy;
|
||||
float lenergy;
|
||||
|
||||
int current_sample;
|
||||
char digits[TELETONE_MAX_DTMF_DIGITS + 1];
|
||||
char digit;
|
||||
int current_digits;
|
||||
int detected_digits;
|
||||
int lost_digits;
|
||||
@ -196,7 +240,7 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
\param samples the number of samples present in sample_buffer
|
||||
\return true when DTMF was detected or false when it is not
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples);
|
||||
/*!
|
||||
@ -206,9 +250,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
\param max the maximum length of buf
|
||||
\return the number of characters written to buf
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max);
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur);
|
||||
|
||||
/*!
|
||||
\brief Step through the Goertzel Algorithm for each sample in a buffer
|
||||
|
@ -2,6 +2,41 @@
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is libteletone
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
*
|
||||
* libteletone.h -- Tone Generator
|
||||
*
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -2,14 +2,62 @@
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is tone_detect.c - General telephony tone detection, and specific detection of DTMF.
|
||||
*
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Stephen Underwood <steveu@coppice.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* The the original interface designed by Steve Underwood was preserved to retain
|
||||
*the optimizations when considering DTMF tones though the names were changed in the interest
|
||||
* of namespace.
|
||||
*
|
||||
* Much less efficient expansion interface was added to allow for the detection of
|
||||
* a single arbitrary tone combination which may also exceed 2 simultaneous tones.
|
||||
* (controlled by compile time constant TELETONE_MAX_TONES)
|
||||
*
|
||||
* Copyright (C) 2006 Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
* libteletone_detect.c Tone Detection Code
|
||||
*
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.c - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -40,21 +88,6 @@
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*********************************************************************************
|
||||
*
|
||||
* Derived from tone_detect.c - General telephony tone detection, and specific
|
||||
* detection of DTMF.
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Despite my general liking of the GPL, I place this code in the
|
||||
* public domain for the benefit of all mankind - even the slimy
|
||||
* ones who might try to proprietize my work and use it to my
|
||||
* detriment.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <libteletone_detect.h>
|
||||
@ -67,7 +100,8 @@
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#define LOW_ENG 10000000
|
||||
#define ZC 2
|
||||
static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR];
|
||||
@ -132,8 +166,8 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
dtmf_detect_state->detected_digits = 0;
|
||||
dtmf_detect_state->lost_digits = 0;
|
||||
dtmf_detect_state->digits[0] = '\0';
|
||||
dtmf_detect_state->mhit = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
dtmf_detect_state->dur = 0;
|
||||
}
|
||||
|
||||
TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
|
||||
@ -266,7 +300,7 @@ TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples)
|
||||
{
|
||||
@ -281,6 +315,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
int best_col;
|
||||
char hit;
|
||||
int limit;
|
||||
teletone_hit_type_t r = 0;
|
||||
|
||||
hit = 0;
|
||||
for (sample = 0; sample < samples; sample = limit) {
|
||||
@ -317,6 +352,32 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
|
||||
}
|
||||
|
||||
if (dtmf_detect_state->zc > 0) {
|
||||
if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
|
||||
if (!--dtmf_detect_state->zc) {
|
||||
/* Reinitialise the detector for the next block */
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
dtmf_detect_state->dur -= samples;
|
||||
return TT_HIT_END;
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->dur += samples;
|
||||
dtmf_detect_state->lenergy = dtmf_detect_state->energy;
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
return TT_HIT_MIDDLE;
|
||||
} else if (dtmf_detect_state->digit) {
|
||||
return TT_HIT_END;
|
||||
}
|
||||
|
||||
|
||||
dtmf_detect_state->current_sample += (limit - sample);
|
||||
if (dtmf_detect_state->current_sample < BLOCK_LEN) {
|
||||
continue;
|
||||
@ -361,58 +422,55 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
back to back differing digits. More importantly, it
|
||||
can work with nasty phones that give a very wobbly start
|
||||
to a digit. */
|
||||
if (hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->mhit = hit;
|
||||
if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
|
||||
dtmf_detect_state->detected_digits++;
|
||||
if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits++] = hit;
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits] = '\0';
|
||||
dtmf_detect_state->digit = hit;
|
||||
} else {
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->zc = ZC;
|
||||
dtmf_detect_state->dur = 0;
|
||||
r = TT_HIT_BEGIN;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
|
||||
dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
|
||||
dtmf_detect_state->hit3 = hit;
|
||||
/* Reinitialise the detector for the next block */
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
|
||||
}
|
||||
if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
|
||||
dtmf_detect_state->mhit = 0;
|
||||
return(0);
|
||||
}
|
||||
return (hit);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max)
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
|
||||
{
|
||||
teletone_assert(dtmf_detect_state->current_digits <= TELETONE_MAX_DTMF_DIGITS);
|
||||
if (!dtmf_detect_state->digit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max > dtmf_detect_state->current_digits) {
|
||||
max = dtmf_detect_state->current_digits;
|
||||
*buf = dtmf_detect_state->digit;
|
||||
|
||||
*dur = dtmf_detect_state->dur;
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->dur = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
}
|
||||
if (max > 0) {
|
||||
memcpy (buf, dtmf_detect_state->digits, max);
|
||||
memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
|
||||
dtmf_detect_state->current_digits -= max;
|
||||
}
|
||||
buf[max] = '\0';
|
||||
return max;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
|
@ -1,5 +1,41 @@
|
||||
/*
|
||||
* libteletone_generate.c -- Tone Generator
|
||||
* libteletone
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is libteletone
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
*
|
||||
* libteletone.c -- Tone Generator
|
||||
*
|
||||
*
|
||||
*
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
@ -34,7 +70,6 @@
|
||||
*/
|
||||
|
||||
#include <libteletone.h>
|
||||
#include "private/ftdm_core.h"
|
||||
|
||||
#define SMAX 32767
|
||||
#define SMIN -32768
|
||||
@ -111,7 +146,7 @@ TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int b
|
||||
ts->decay_step = 0;
|
||||
ts->decay_factor = 1;
|
||||
if (buflen) {
|
||||
if ((ts->buffer = ftdm_calloc(buflen, sizeof(teletone_audio_t))) == 0) {
|
||||
if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) {
|
||||
return -1;
|
||||
}
|
||||
ts->datalen = buflen;
|
||||
@ -142,7 +177,7 @@ TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int b
|
||||
TELETONE_API(int) teletone_destroy_session(teletone_generation_session_t *ts)
|
||||
{
|
||||
if (ts->buffer) {
|
||||
ftdm_safe_free(ts->buffer);
|
||||
free(ts->buffer);
|
||||
ts->buffer = NULL;
|
||||
ts->samples = 0;
|
||||
}
|
||||
@ -270,6 +305,19 @@ TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone
|
||||
return ts->samples / ts->channels;
|
||||
}
|
||||
|
||||
/* don't ask */
|
||||
static char *my_strdup (const char *s)
|
||||
{
|
||||
size_t len = strlen (s) + 1;
|
||||
void *new = malloc (len);
|
||||
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (char *) memcpy (new, s, len);
|
||||
}
|
||||
|
||||
TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd)
|
||||
{
|
||||
char *data = NULL, *cur = NULL, *end = NULL;
|
||||
@ -280,7 +328,7 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
||||
}
|
||||
|
||||
do {
|
||||
if (!(data = ftdm_strdup(cmd))) {
|
||||
if (!(data = my_strdup(cmd))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -363,6 +411,9 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
||||
*e++ = '\0';
|
||||
}
|
||||
do {
|
||||
if (!p) {
|
||||
break;
|
||||
}
|
||||
if ((next = strchr(p, ',')) != 0) {
|
||||
*next++ = '\0';
|
||||
}
|
||||
@ -427,7 +478,7 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
|
||||
}
|
||||
}
|
||||
bottom:
|
||||
ftdm_safe_free(data);
|
||||
free(data);
|
||||
data = NULL;
|
||||
if (ts->LOOPS > 0) {
|
||||
ts->LOOPS--;
|
||||
|
@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
@ -54,8 +54,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
@ -100,7 +100,8 @@
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#define LOW_ENG 10000000
|
||||
#define ZC 2
|
||||
static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR];
|
||||
static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR];
|
||||
@ -165,8 +166,8 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
dtmf_detect_state->detected_digits = 0;
|
||||
dtmf_detect_state->lost_digits = 0;
|
||||
dtmf_detect_state->digits[0] = '\0';
|
||||
dtmf_detect_state->mhit = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
dtmf_detect_state->dur = 0;
|
||||
}
|
||||
|
||||
TELETONE_API(void) teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map)
|
||||
@ -299,7 +300,7 @@ TELETONE_API(int) teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples)
|
||||
{
|
||||
@ -314,6 +315,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
int best_col;
|
||||
char hit;
|
||||
int limit;
|
||||
teletone_hit_type_t r = 0;
|
||||
|
||||
hit = 0;
|
||||
for (sample = 0; sample < samples; sample = limit) {
|
||||
@ -350,6 +352,32 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
|
||||
}
|
||||
|
||||
if (dtmf_detect_state->zc > 0) {
|
||||
if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
|
||||
if (!--dtmf_detect_state->zc) {
|
||||
/* Reinitialise the detector for the next block */
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
dtmf_detect_state->dur -= samples;
|
||||
return TT_HIT_END;
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->dur += samples;
|
||||
dtmf_detect_state->lenergy = dtmf_detect_state->energy;
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
return TT_HIT_MIDDLE;
|
||||
} else if (dtmf_detect_state->digit) {
|
||||
return TT_HIT_END;
|
||||
}
|
||||
|
||||
|
||||
dtmf_detect_state->current_sample += (limit - sample);
|
||||
if (dtmf_detect_state->current_sample < BLOCK_LEN) {
|
||||
continue;
|
||||
@ -394,58 +422,55 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
back to back differing digits. More importantly, it
|
||||
can work with nasty phones that give a very wobbly start
|
||||
to a digit. */
|
||||
if (hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->mhit = hit;
|
||||
if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
|
||||
dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
|
||||
dtmf_detect_state->detected_digits++;
|
||||
if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits++] = hit;
|
||||
dtmf_detect_state->digits[dtmf_detect_state->current_digits] = '\0';
|
||||
dtmf_detect_state->digit = hit;
|
||||
} else {
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dtmf_detect_state->lost_digits++;
|
||||
}
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->zc = ZC;
|
||||
dtmf_detect_state->dur = 0;
|
||||
r = TT_HIT_BEGIN;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
|
||||
dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
|
||||
dtmf_detect_state->hit3 = hit;
|
||||
/* Reinitialise the detector for the next block */
|
||||
for (i = 0; i < GRID_FACTOR; i++) {
|
||||
goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
|
||||
goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
|
||||
goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
|
||||
}
|
||||
|
||||
dtmf_detect_state->energy = 0.0;
|
||||
dtmf_detect_state->current_sample = 0;
|
||||
|
||||
}
|
||||
if ((!dtmf_detect_state->mhit) || (dtmf_detect_state->mhit != hit)) {
|
||||
dtmf_detect_state->mhit = 0;
|
||||
return(0);
|
||||
}
|
||||
return (hit);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max)
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
|
||||
{
|
||||
teletone_assert(dtmf_detect_state->current_digits <= TELETONE_MAX_DTMF_DIGITS);
|
||||
if (!dtmf_detect_state->digit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max > dtmf_detect_state->current_digits) {
|
||||
max = dtmf_detect_state->current_digits;
|
||||
*buf = dtmf_detect_state->digit;
|
||||
|
||||
*dur = dtmf_detect_state->dur;
|
||||
|
||||
if (!dtmf_detect_state->zc) {
|
||||
dtmf_detect_state->dur = 0;
|
||||
dtmf_detect_state->digit = 0;
|
||||
}
|
||||
if (max > 0) {
|
||||
memcpy (buf, dtmf_detect_state->digits, max);
|
||||
memmove (dtmf_detect_state->digits, dtmf_detect_state->digits + max, dtmf_detect_state->current_digits - max);
|
||||
dtmf_detect_state->current_digits -= max;
|
||||
}
|
||||
buf[max] = '\0';
|
||||
return max;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
|
@ -54,8 +54,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
@ -134,6 +134,14 @@ extern "C" {
|
||||
#define BLOCK_LEN 102
|
||||
#define M_TWO_PI 2.0*M_PI
|
||||
|
||||
typedef enum {
|
||||
TT_HIT_NONE = 0,
|
||||
TT_HIT_BEGIN = 1,
|
||||
TT_HIT_MIDDLE = 2,
|
||||
TT_HIT_END = 3
|
||||
} teletone_hit_type_t;
|
||||
|
||||
|
||||
/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
|
||||
typedef struct {
|
||||
float v2;
|
||||
@ -147,16 +155,19 @@ extern "C" {
|
||||
int hit2;
|
||||
int hit3;
|
||||
int hit4;
|
||||
int mhit;
|
||||
int dur;
|
||||
int zc;
|
||||
|
||||
|
||||
teletone_goertzel_state_t row_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out[GRID_FACTOR];
|
||||
teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
|
||||
teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
|
||||
float energy;
|
||||
float lenergy;
|
||||
|
||||
int current_sample;
|
||||
char digits[TELETONE_MAX_DTMF_DIGITS + 1];
|
||||
char digit;
|
||||
int current_digits;
|
||||
int detected_digits;
|
||||
int lost_digits;
|
||||
@ -229,7 +240,7 @@ TELETONE_API(void) teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf
|
||||
\param samples the number of samples present in sample_buffer
|
||||
\return true when DTMF was detected or false when it is not
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
TELETONE_API(teletone_hit_type_t) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
int16_t sample_buffer[],
|
||||
int samples);
|
||||
/*!
|
||||
@ -239,9 +250,7 @@ TELETONE_API(int) teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detec
|
||||
\param max the maximum length of buf
|
||||
\return the number of characters written to buf
|
||||
*/
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||
char *buf,
|
||||
int max);
|
||||
TELETONE_API(int) teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur);
|
||||
|
||||
/*!
|
||||
\brief Step through the Goertzel Algorithm for each sample in a buffer
|
||||
|
@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
@ -33,8 +33,8 @@
|
||||
* Exception:
|
||||
* The author hereby grants the use of this source code under the
|
||||
* following license if and only if the source code is distributed
|
||||
* as part of the openzap library. Any use or distribution of this
|
||||
* source code outside the scope of the openzap library will nullify the
|
||||
* as part of the OpenZAP or FreeTDM library. Any use or distribution of this
|
||||
* source code outside the scope of the OpenZAP or FreeTDM library will nullify the
|
||||
* following license and reinact the MPL 1.1 as stated above.
|
||||
*
|
||||
* Copyright (c) 2007, Anthony Minessale II
|
||||
|
@ -107,7 +107,10 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
DEFAULT_INCLUDES="-I. -I./src/include -I$(srcdir)"
|
||||
|
||||
AC_SUBST(SOLINK)
|
||||
AC_SUBST(DEFAULT_INCLUDES)
|
||||
AC_SUBST(DYNAMIC_LIB_EXTEN)
|
||||
|
||||
AC_CHECK_LIB([dl], [dlopen])
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
AM_CFLAGS = -Isrc -Iinterface -fPIC -Wall -O3
|
||||
AM_CFLAGS = -Isrc -Iinterface -fPIC -O3
|
||||
AUTOMAKE_OPTS = gnu
|
||||
NAME = libSKP_SILK_SDK
|
||||
AM_CPPFLAGS = $(AM_CFLAGS)
|
||||
|
@ -169,7 +169,7 @@ struct switch_core_session {
|
||||
uint32_t track_id;
|
||||
switch_log_level_t loglevel;
|
||||
uint32_t soft_lock;
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
switch_ivr_dmachine_t *dmachine[2];
|
||||
plc_state_t *plc;
|
||||
};
|
||||
|
||||
@ -255,6 +255,7 @@ struct switch_runtime {
|
||||
uint32_t db_handle_timeout;
|
||||
int curl_count;
|
||||
int ssl_count;
|
||||
int cpu_count;
|
||||
};
|
||||
|
||||
extern struct switch_runtime runtime;
|
||||
|
@ -87,6 +87,10 @@ SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_
|
||||
|
||||
#define switch_channel_up(_channel) (switch_channel_check_signal(_channel, SWITCH_TRUE) || switch_channel_get_state(_channel) < CS_HANGUP)
|
||||
#define switch_channel_down(_channel) (switch_channel_check_signal(_channel, SWITCH_TRUE) || switch_channel_get_state(_channel) >= CS_HANGUP)
|
||||
|
||||
#define switch_channel_up_nosig(_channel) switch_channel_get_state(_channel) < CS_HANGUP
|
||||
#define switch_channel_down_nosig(_channel) switch_channel_get_state(_channel) >= CS_HANGUP
|
||||
|
||||
#define switch_channel_media_ack(_channel) (!switch_channel_test_cap(_channel, CC_MEDIA_ACK) || switch_channel_test_flag(_channel, CF_MEDIA_ACK))
|
||||
|
||||
SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state);
|
||||
@ -627,6 +631,9 @@ SWITCH_DECLARE(void) switch_channel_mark_hold(switch_channel_t *channel, switch_
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix);
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix);
|
||||
|
||||
SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension);
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
/* For Emacs:
|
||||
|
@ -712,12 +712,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_loglevel(switch_core_ses
|
||||
\return the log level
|
||||
*/
|
||||
SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_session_t *session);
|
||||
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec);
|
||||
SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine);
|
||||
SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target);
|
||||
SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session, switch_digit_action_target_t target);
|
||||
SWITCH_DECLARE(switch_digit_action_target_t) switch_ivr_dmachine_get_target(switch_ivr_dmachine_t *dmachine);
|
||||
SWITCH_DECLARE(void) switch_ivr_dmachine_set_target(switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data);
|
||||
|
||||
/*!
|
||||
@ -1975,8 +1978,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid,
|
||||
\brief Set the maximum priority the process can obtain
|
||||
\return 0 on success
|
||||
*/
|
||||
SWITCH_DECLARE(int32_t) set_high_priority(void);
|
||||
|
||||
SWITCH_DECLARE(int32_t) set_normal_priority(void);
|
||||
SWITCH_DECLARE(int32_t) set_auto_priority(void);
|
||||
SWITCH_DECLARE(int32_t) set_realtime_priority(void);
|
||||
SWITCH_DECLARE(int32_t) set_low_priority(void);
|
||||
|
||||
/*!
|
||||
\brief Change user and/or group of the running process
|
||||
@ -2101,8 +2107,10 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string);
|
||||
SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait);
|
||||
SWITCH_DECLARE(void) switch_cond_yield(switch_interval_time_t t);
|
||||
SWITCH_DECLARE(void) switch_cond_next(void);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *name, const char *proto, const char *from, const char *to,
|
||||
const char *subject, const char *body, const char *type, const char *hint);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_chat_send_args(const char *dest_proto, const char *proto, const char *from, const char *to,
|
||||
const char *subject, const char *body, const char *type, const char *hint);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_chat_send(const char *dest_proto, switch_event_t *message_event);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_chat_deliver(const char *dest_proto, switch_event_t **message_event);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_session_t *session, const char *cmds);
|
||||
|
||||
|
@ -540,6 +540,8 @@ SWITCH_DECLARE(int) switch_core_db_changes(switch_core_db_t *db);
|
||||
* literal.
|
||||
*/
|
||||
|
||||
SWITCH_DECLARE(char*)switch_sql_concat(void);
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
/* For Emacs:
|
||||
|
@ -156,6 +156,8 @@ SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *bod
|
||||
SWITCH_DECLARE_CONSTRUCTOR Event(const char *type, const char *subclass_name = NULL);
|
||||
SWITCH_DECLARE_CONSTRUCTOR Event(switch_event_t *wrap_me, int free_me = 0);
|
||||
virtual SWITCH_DECLARE_CONSTRUCTOR ~ Event();
|
||||
SWITCH_DECLARE(int) chat_execute(const char *app, const char *data = NULL);
|
||||
SWITCH_DECLARE(int) chat_send(const char *dest_proto = NULL);
|
||||
SWITCH_DECLARE(const char *) serialize(const char *format = NULL);
|
||||
SWITCH_DECLARE(bool) setPriority(switch_priority_t priority = SWITCH_PRIORITY_NORMAL);
|
||||
SWITCH_DECLARE(const char *) getHeader(const char *header_name);
|
||||
|
@ -103,7 +103,8 @@ struct switch_event {
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
EF_UNIQ_HEADERS = (1 << 0)
|
||||
EF_UNIQ_HEADERS = (1 << 0),
|
||||
EF_NO_CHAT_EXEC = (1 << 1)
|
||||
} switch_event_flag_t;
|
||||
|
||||
|
||||
@ -157,6 +158,8 @@ _Ret_opt_z_ SWITCH_DECLARE(char *) switch_event_get_header_idx(switch_event_t *e
|
||||
|
||||
#define switch_event_get_header_nil(e, h) switch_str_nil(switch_event_get_header(e,h))
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_rename_header(switch_event_t *event, const char *header_name, const char *new_header_name);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the body value from an event
|
||||
\param event the event to read the body from
|
||||
@ -207,6 +210,8 @@ SWITCH_DECLARE(void) switch_event_destroy(switch_event_t **event);
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_dup(switch_event_t **event, switch_event_t *todup);
|
||||
SWITCH_DECLARE(void) switch_event_merge(switch_event_t *event, switch_event_t *tomerge);
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_dup_reply(switch_event_t **event, switch_event_t *todup);
|
||||
|
||||
/*!
|
||||
\brief Fire an event with full arguement list
|
||||
\param file the calling file
|
||||
@ -321,6 +326,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_running(void);
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_add_body(switch_event_t *event, const char *fmt, ...) PRINTF_FUNCTION(2, 3);
|
||||
#endif
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_set_body(switch_event_t *event, const char *body);
|
||||
|
||||
SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const char *in);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_event_create_pres_in_detailed(_In_z_ char *file, _In_z_ char *func, _In_ int line,
|
||||
|
@ -464,7 +464,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess
|
||||
const char *cid_name_override,
|
||||
const char *cid_num_override,
|
||||
switch_caller_profile_t *caller_profile_override,
|
||||
switch_event_t *ovars, switch_originate_flag_t flags);
|
||||
switch_event_t *ovars, switch_originate_flag_t flags,
|
||||
switch_call_cause_t *cancel_cause);
|
||||
|
||||
SWITCH_DECLARE(void) switch_ivr_bridge_display(switch_core_session_t *session, switch_core_session_t *peer_session);
|
||||
|
||||
@ -930,6 +931,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_release_file_handle(switch_core_sessi
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp);
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_insert_file(switch_core_session_t *session, const char *file, const char *insert_file, switch_size_t sample_point);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_create_message_reply(switch_event_t **reply, switch_event_t *message, const char *new_proto);
|
||||
|
||||
/** @} */
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
@ -55,33 +55,35 @@ SWITCH_BEGIN_EXTERN_C
|
||||
struct switch_loadable_module_interface {
|
||||
/*! the name of the module */
|
||||
const char *module_name;
|
||||
/*! the table of endpoints the module has implmented */
|
||||
/*! the table of endpoints the module has implemented */
|
||||
switch_endpoint_interface_t *endpoint_interface;
|
||||
/*! the table of timers the module has implmented */
|
||||
/*! the table of timers the module has implemented */
|
||||
switch_timer_interface_t *timer_interface;
|
||||
/*! the table of dialplans the module has implmented */
|
||||
/*! the table of dialplans the module has implemented */
|
||||
switch_dialplan_interface_t *dialplan_interface;
|
||||
/*! the table of codecs the module has implmented */
|
||||
/*! the table of codecs the module has implemented */
|
||||
switch_codec_interface_t *codec_interface;
|
||||
/*! the table of applications the module has implmented */
|
||||
/*! the table of applications the module has implemented */
|
||||
switch_application_interface_t *application_interface;
|
||||
/*! the table of api functions the module has implmented */
|
||||
/*! the table of chat applications the module has implemented */
|
||||
switch_chat_application_interface_t *chat_application_interface;
|
||||
/*! the table of api functions the module has implemented */
|
||||
switch_api_interface_t *api_interface;
|
||||
/*! the table of file formats the module has implmented */
|
||||
/*! the table of file formats the module has implemented */
|
||||
switch_file_interface_t *file_interface;
|
||||
/*! the table of speech interfaces the module has implmented */
|
||||
/*! the table of speech interfaces the module has implemented */
|
||||
switch_speech_interface_t *speech_interface;
|
||||
/*! the table of directory interfaces the module has implmented */
|
||||
/*! the table of directory interfaces the module has implemented */
|
||||
switch_directory_interface_t *directory_interface;
|
||||
/*! the table of chat interfaces the module has implmented */
|
||||
/*! the table of chat interfaces the module has implemented */
|
||||
switch_chat_interface_t *chat_interface;
|
||||
/*! the table of say interfaces the module has implmented */
|
||||
/*! the table of say interfaces the module has implemented */
|
||||
switch_say_interface_t *say_interface;
|
||||
/*! the table of asr interfaces the module has implmented */
|
||||
/*! the table of asr interfaces the module has implemented */
|
||||
switch_asr_interface_t *asr_interface;
|
||||
/*! the table of management interfaces the module has implmented */
|
||||
/*! the table of management interfaces the module has implemented */
|
||||
switch_management_interface_t *management_interface;
|
||||
/*! the table of limit interfaces the module has implmented */
|
||||
/*! the table of limit interfaces the module has implemented */
|
||||
switch_limit_interface_t *limit_interface;
|
||||
switch_thread_rwlock_t *rwlock;
|
||||
int refs;
|
||||
@ -169,6 +171,15 @@ SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_inte
|
||||
*/
|
||||
SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(const char *name);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the chat application interface by it's registered name
|
||||
\param name the name of the chat application
|
||||
\return the desired chat application interface
|
||||
*/
|
||||
SWITCH_DECLARE(switch_chat_application_interface_t *) switch_loadable_module_get_chat_application_interface(const char *name);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_execute_chat_app(switch_event_t *message, const char *app, const char *data);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the API interface by it's registered name
|
||||
\param name the name of the API
|
||||
@ -335,6 +346,18 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void);
|
||||
break; \
|
||||
}
|
||||
|
||||
#define SWITCH_ADD_CHAT_APP(app_int, int_name, short_descript, long_descript, funcptr, syntax_string, app_flags) \
|
||||
for (;;) { \
|
||||
app_int = (switch_chat_application_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_CHAT_APPLICATION_INTERFACE); \
|
||||
app_int->interface_name = int_name; \
|
||||
app_int->chat_application_function = funcptr; \
|
||||
app_int->short_desc = short_descript; \
|
||||
app_int->long_desc = long_descript; \
|
||||
app_int->syntax = syntax_string; \
|
||||
app_int->flags = app_flags; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define SWITCH_ADD_DIALPLAN(dp_int, int_name, funcptr) \
|
||||
for (;;) { \
|
||||
dp_int = (switch_dialplan_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_DIALPLAN_INTERFACE); \
|
||||
|
@ -483,8 +483,8 @@ struct switch_chat_interface {
|
||||
/*! the name of the interface */
|
||||
const char *interface_name;
|
||||
/*! function to open the directory interface */
|
||||
switch_status_t (*chat_send) (const char *proto, const char *from, const char *to,
|
||||
const char *subject, const char *body, const char *type, const char *hint);
|
||||
switch_status_t (*chat_send) (switch_event_t *message_event);
|
||||
|
||||
switch_thread_rwlock_t *rwlock;
|
||||
int refs;
|
||||
switch_mutex_t *reflock;
|
||||
@ -681,6 +681,27 @@ struct switch_application_interface {
|
||||
struct switch_application_interface *next;
|
||||
};
|
||||
|
||||
/*! \brief A module interface to implement a chat application */
|
||||
struct switch_chat_application_interface {
|
||||
/*! the name of the interface */
|
||||
const char *interface_name;
|
||||
/*! function the application implements */
|
||||
switch_chat_application_function_t chat_application_function;
|
||||
/*! the long winded description of the application */
|
||||
const char *long_desc;
|
||||
/*! the short and sweet description of the application */
|
||||
const char *short_desc;
|
||||
/*! an example of the application syntax */
|
||||
const char *syntax;
|
||||
/*! flags to control behaviour */
|
||||
uint32_t flags;
|
||||
switch_thread_rwlock_t *rwlock;
|
||||
int refs;
|
||||
switch_mutex_t *reflock;
|
||||
switch_loadable_module_interface_t *parent;
|
||||
struct switch_chat_application_interface *next;
|
||||
};
|
||||
|
||||
/*! \brief A module interface to implement an api function */
|
||||
struct switch_api_interface {
|
||||
/*! the name of the interface */
|
||||
|
@ -74,6 +74,7 @@ SWITCH_DECLARE(void) switch_capture_regex(switch_regex_t *re, int match_count, c
|
||||
int *ovector, const char *var, switch_cap_callback_t callback, void *user_data);
|
||||
|
||||
SWITCH_DECLARE_NONSTD(void) switch_regex_set_var_callback(const char *var, const char *val, void *user_data);
|
||||
SWITCH_DECLARE_NONSTD(void) switch_regex_set_event_header_callback(const char *var, const char *val, void *user_data);
|
||||
|
||||
#define switch_regex_safe_free(re) if (re) {\
|
||||
switch_regex_free(re);\
|
||||
|
@ -182,6 +182,7 @@ SWITCH_BEGIN_EXTERN_C
|
||||
#define SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE "originator_video_codec"
|
||||
#define SWITCH_LOCAL_MEDIA_IP_VARIABLE "local_media_ip"
|
||||
#define SWITCH_LOCAL_MEDIA_PORT_VARIABLE "local_media_port"
|
||||
#define SWITCH_ADVERTISED_MEDIA_IP_VARIABLE "advertised_media_ip"
|
||||
#define SWITCH_REMOTE_MEDIA_IP_VARIABLE "remote_media_ip"
|
||||
#define SWITCH_REMOTE_MEDIA_PORT_VARIABLE "remote_media_port"
|
||||
#define SWITCH_REMOTE_VIDEO_IP_VARIABLE "remote_video_ip"
|
||||
@ -221,6 +222,14 @@ typedef enum {
|
||||
SWITCH_DTMF_APP
|
||||
} switch_dtmf_source_t;
|
||||
|
||||
typedef enum {
|
||||
DIGIT_TARGET_SELF,
|
||||
DIGIT_TARGET_PEER,
|
||||
DIGIT_TARGET_BOTH
|
||||
} switch_digit_action_target_t;
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
DTMF_FLAG_SKIP_PROCESS = (1 << 0)
|
||||
} dtmf_flag_t;
|
||||
@ -297,7 +306,8 @@ typedef enum {
|
||||
SCF_AUTO_SCHEMAS = (1 << 13),
|
||||
SCF_MINIMAL = (1 << 14),
|
||||
SCF_USE_NAT_MAPPING = (1 << 15),
|
||||
SCF_CLEAR_SQL = (1 << 16)
|
||||
SCF_CLEAR_SQL = (1 << 16),
|
||||
SCF_THREADED_SYSTEM_EXEC = (1 << 17)
|
||||
} switch_core_flag_enum_t;
|
||||
typedef uint32_t switch_core_flag_t;
|
||||
|
||||
@ -315,7 +325,8 @@ typedef enum {
|
||||
SWITCH_SAY_INTERFACE,
|
||||
SWITCH_ASR_INTERFACE,
|
||||
SWITCH_MANAGEMENT_INTERFACE,
|
||||
SWITCH_LIMIT_INTERFACE
|
||||
SWITCH_LIMIT_INTERFACE,
|
||||
SWITCH_CHAT_APPLICATION_INTERFACE
|
||||
} switch_module_interface_name_t;
|
||||
|
||||
typedef enum {
|
||||
@ -485,6 +496,7 @@ typedef enum {
|
||||
SWITCH_XML_SECTION_DIRECTORY = (1 << 1),
|
||||
SWITCH_XML_SECTION_DIALPLAN = (1 << 2),
|
||||
SWITCH_XML_SECTION_PHRASES = (1 << 3),
|
||||
SWITCH_XML_SECTION_CHATPLAN = (1 << 4),
|
||||
|
||||
/* Nothing after this line */
|
||||
SWITCH_XML_SECTION_MAX = (1 << 4)
|
||||
@ -672,15 +684,16 @@ typedef enum {
|
||||
This flag will treat every dtmf as if it were 50ms and queue it on recipt of the leading packet rather than at the end.
|
||||
*/
|
||||
|
||||
RTP_BUG_PAUSE_BETWEEN_DTMF = (1 << 7)
|
||||
|
||||
RTP_BUG_ACCEPT_ANY_PACKETS = (1 << 7)
|
||||
|
||||
/*
|
||||
Sonus says they need time to generate the dtmf so we should not send it so fast so with this flag we will wait a few clicks after each send to
|
||||
start sending the next one.
|
||||
Oracle's Contact Center Anywhere (CCA) likes to use a single RTP socket to send all its outbound audio.
|
||||
This messes up our ability to auto adjust to NATTED RTP and causes us to ignore its audio packets.
|
||||
This flag will allow compatibility with this dying product.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
} switch_rtp_bug_flag_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -857,6 +870,7 @@ typedef struct {
|
||||
uint16_t remote_port;
|
||||
const char *local_ip;
|
||||
uint16_t local_port;
|
||||
const char *sdp_o_line;
|
||||
} switch_t38_options_t;
|
||||
|
||||
/*!
|
||||
@ -1156,6 +1170,7 @@ typedef enum {
|
||||
CF_LAZY_ATTENDED_TRANSFER,
|
||||
CF_SIGNAL_DATA,
|
||||
CF_SIMPLIFY,
|
||||
CF_ZOMBIE_EXEC,
|
||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
||||
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
|
||||
CF_FLAG_MAX
|
||||
@ -1166,7 +1181,8 @@ typedef enum {
|
||||
CF_APP_TAGGED = (1 << 0),
|
||||
CF_APP_T38 = (1 << 1),
|
||||
CF_APP_T38_REQ = (1 << 2),
|
||||
CF_APP_T38_FAIL = (1 << 3)
|
||||
CF_APP_T38_FAIL = (1 << 3),
|
||||
CF_APP_T38_NEGOTIATED = (1 << 4)
|
||||
} switch_channel_app_flag_t;
|
||||
|
||||
|
||||
@ -1193,7 +1209,8 @@ typedef enum {
|
||||
SFF_PROXY_PACKET = (1 << 5),
|
||||
SFF_DYNAMIC = (1 << 6),
|
||||
SFF_ZRTP = (1 << 7),
|
||||
SFF_UDPTL_PACKET = (1 << 8)
|
||||
SFF_UDPTL_PACKET = (1 << 8),
|
||||
SFF_NOT_AUDIO = (1 << 9)
|
||||
} switch_frame_flag_enum_t;
|
||||
typedef uint32_t switch_frame_flag_t;
|
||||
|
||||
@ -1202,10 +1219,17 @@ typedef enum {
|
||||
SAF_NONE = 0,
|
||||
SAF_SUPPORT_NOMEDIA = (1 << 0),
|
||||
SAF_ROUTING_EXEC = (1 << 1),
|
||||
SAF_MEDIA_TAP = (1 << 2)
|
||||
SAF_MEDIA_TAP = (1 << 2),
|
||||
SAF_ZOMBIE_EXEC = (1 << 3)
|
||||
} switch_application_flag_enum_t;
|
||||
typedef uint32_t switch_application_flag_t;
|
||||
|
||||
typedef enum {
|
||||
SCAF_NONE = 0
|
||||
} switch_chat_application_flag_enum_t;
|
||||
typedef uint32_t switch_chat_application_flag_t;
|
||||
|
||||
|
||||
/*!
|
||||
\enum switch_signal_t
|
||||
\brief Signals to send to channels
|
||||
@ -1666,7 +1690,8 @@ typedef enum {
|
||||
SCSC_VERBOSE_EVENTS,
|
||||
SCSC_SHUTDOWN_CHECK,
|
||||
SCSC_PAUSE_CHECK,
|
||||
SCSC_READY_CHECK
|
||||
SCSC_READY_CHECK,
|
||||
SCSC_THREADED_SYSTEM_EXEC
|
||||
} switch_session_ctl_t;
|
||||
|
||||
typedef enum {
|
||||
@ -1713,6 +1738,7 @@ typedef struct switch_timer_interface switch_timer_interface_t;
|
||||
typedef struct switch_dialplan_interface switch_dialplan_interface_t;
|
||||
typedef struct switch_codec_interface switch_codec_interface_t;
|
||||
typedef struct switch_application_interface switch_application_interface_t;
|
||||
typedef struct switch_chat_application_interface switch_chat_application_interface_t;
|
||||
typedef struct switch_api_interface switch_api_interface_t;
|
||||
typedef struct switch_file_interface switch_file_interface_t;
|
||||
typedef struct switch_speech_interface switch_speech_interface_t;
|
||||
@ -1764,7 +1790,8 @@ typedef switch_status_t (*switch_core_codec_fmtp_parse_func_t) (const char *fmtp
|
||||
typedef switch_status_t (*switch_core_codec_destroy_func_t) (switch_codec_t *);
|
||||
|
||||
|
||||
|
||||
typedef switch_status_t (*switch_chat_application_function_t) (switch_event_t *, const char *);
|
||||
#define SWITCH_STANDARD_CHAT_APP(name) static switch_status_t name (switch_event_t *message, const char *data)
|
||||
|
||||
typedef void (*switch_application_function_t) (switch_core_session_t *, const char *);
|
||||
#define SWITCH_STANDARD_APP(name) static void name (switch_core_session_t *session, const char *data)
|
||||
|
@ -525,6 +525,18 @@ static inline char *switch_clean_name_string(char *s)
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Turn a string into a number (default if NULL)
|
||||
\param nptr the string
|
||||
\param dft the default
|
||||
\return the number version of the string or the default
|
||||
*/
|
||||
static inline int switch_safe_atoi(const char *nptr, int dft)
|
||||
{
|
||||
return nptr ? atoi(nptr) : dft;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Free a pointer and set it to NULL unless it already is NULL
|
||||
\param it the pointer
|
||||
|
2
src/mod/.gitignore
vendored
2
src/mod/.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/Makefile
|
||||
/Makefile.in
|
||||
/applications/mod_blacklist/Makefile
|
||||
/applications/mod_commands/Makefile
|
||||
/applications/mod_conference/Makefile
|
||||
/applications/mod_db/Makefile
|
||||
@ -14,6 +15,7 @@
|
||||
/applications/mod_fifo/Makefile
|
||||
/applications/mod_fsv/Makefile
|
||||
/applications/mod_limit/Makefile
|
||||
/applications/mod_sms/Makefile
|
||||
/applications/mod_spandsp/Makefile
|
||||
/applications/mod_spandsp/Makefile.in
|
||||
/applications/mod_spandsp/mod_spandsp.log
|
||||
|
343
src/mod/applications/mod_blacklist/mod_blacklist.c
Normal file
343
src/mod/applications/mod_blacklist/mod_blacklist.c
Normal file
@ -0,0 +1,343 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Mathieu Rene <mrene@avgs.ca>
|
||||
* Raymond Chandler <intralanman@freeswitch.org>
|
||||
*
|
||||
* mod_blacklist.c -- Blacklist module
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
|
||||
/* Prototypes */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_blacklist_shutdown);
|
||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_blacklist_runtime);
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_blacklist_load);
|
||||
|
||||
|
||||
SWITCH_MODULE_DEFINITION(mod_blacklist, mod_blacklist_load, mod_blacklist_shutdown, NULL);
|
||||
|
||||
typedef struct {
|
||||
switch_hash_t *list;
|
||||
switch_mutex_t *list_mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
} blacklist_t;
|
||||
|
||||
static struct {
|
||||
switch_hash_t *files;
|
||||
switch_hash_t *lists;
|
||||
switch_mutex_t *files_mutex;
|
||||
switch_mutex_t *lists_mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
} globals;
|
||||
|
||||
blacklist_t *blacklist_create(const char *name)
|
||||
{
|
||||
switch_memory_pool_t *pool = NULL;
|
||||
blacklist_t *bl = NULL;
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
bl = switch_core_alloc(pool, sizeof(*bl));
|
||||
switch_assert(bl);
|
||||
bl->pool = pool;
|
||||
|
||||
switch_core_hash_init(&bl->list, pool);
|
||||
switch_mutex_init(&bl->list_mutex, SWITCH_MUTEX_NESTED, pool);
|
||||
|
||||
return bl;
|
||||
}
|
||||
|
||||
void blacklist_free(blacklist_t *bl)
|
||||
{
|
||||
switch_core_destroy_memory_pool(&bl->pool);
|
||||
}
|
||||
|
||||
|
||||
void trim(char *string)
|
||||
{
|
||||
char *p;
|
||||
if ((p = strchr(string, '\n'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
if ((p = strchr(string, '\r'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static switch_status_t load_list(const char *name, const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if ((f = fopen(filename, "r"))) {
|
||||
char buf[1024] = {0};
|
||||
blacklist_t *bl = blacklist_create(name); /* Create a hashtable + mutex for that list */
|
||||
|
||||
while (fgets(buf, 1024, f)) {
|
||||
trim(buf);
|
||||
switch_core_hash_insert(bl->list, buf, (void *)SWITCH_TRUE);
|
||||
}
|
||||
|
||||
switch_core_hash_insert(globals.files, name, filename);
|
||||
switch_core_hash_insert(globals.lists, name, bl);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Loaded list [%s]\n", name);
|
||||
|
||||
fclose(f);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open [%s] to load list [%s]\n", filename, name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t do_config(switch_bool_t reload)
|
||||
{
|
||||
/* Load up blacklists */
|
||||
switch_xml_t xml, cfg, lists, list;
|
||||
switch_hash_index_t *hi;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg("mod_blacklist.conf", &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't load configuration section\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_mutex_lock(globals.lists_mutex);
|
||||
|
||||
/* Destroy any active lists */
|
||||
while ((hi = switch_hash_first(NULL, globals.lists))) {
|
||||
const void *key;
|
||||
void *val;
|
||||
switch_hash_this(hi, &key, NULL, &val);
|
||||
blacklist_free((blacklist_t*)val);
|
||||
switch_core_hash_delete(globals.lists, (const char*)key);
|
||||
}
|
||||
|
||||
if ((lists = switch_xml_child(cfg, "lists"))) {
|
||||
for (list = switch_xml_child(lists, "list"); list; list = list->next) {
|
||||
const char *name = switch_xml_attr_soft(list, "name");
|
||||
const char *filename = switch_xml_attr_soft(list, "filename");
|
||||
|
||||
if (zstr(name)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "list has no name\n");
|
||||
continue;
|
||||
}
|
||||
if (zstr(filename)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "list [%s] has no filename\n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
load_list(name, filename);
|
||||
}
|
||||
}
|
||||
|
||||
switch_mutex_unlock(globals.lists_mutex);
|
||||
|
||||
if (xml) {
|
||||
switch_xml_free(xml);
|
||||
xml = NULL;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define BLACKLIST_API_SYNTAX \
|
||||
"blacklist check <listname> <item>\n" \
|
||||
"blacklist add <listname> <item>\n" \
|
||||
"blacklist del <listname> <item>\n" \
|
||||
"blacklist reload\n" \
|
||||
"blacklist help\n"
|
||||
|
||||
SWITCH_STANDARD_API(blacklist_api_function)
|
||||
{
|
||||
char *data;
|
||||
int argc;
|
||||
char *argv[3];
|
||||
|
||||
data = strdup(cmd);
|
||||
trim(data);
|
||||
if (!(argc = switch_separate_string(data, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid usage\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "check")) {
|
||||
blacklist_t *bl = NULL;
|
||||
switch_bool_t result;
|
||||
|
||||
if (argc < 2 || zstr(argv[1]) || zstr(argv[2])) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Wrong syntax");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(globals.lists_mutex);
|
||||
bl = switch_core_hash_find(globals.lists, argv[1]);
|
||||
switch_mutex_unlock(globals.lists_mutex);
|
||||
|
||||
if (!bl) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown blacklist [%s]\n", argv[1]);
|
||||
stream->write_function(stream, "false");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(bl->list_mutex);
|
||||
result = (switch_bool_t)(intptr_t)switch_core_hash_find(bl->list, argv[2]);
|
||||
stream->write_function(stream, "%s", result ? "true" : "false");
|
||||
switch_mutex_unlock(bl->list_mutex);
|
||||
} else if (!strcasecmp(argv[0], "add")) {
|
||||
blacklist_t *bl = NULL;
|
||||
if (argc < 2 || zstr(argv[1]) || zstr(argv[2])) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Wrong syntax");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(globals.lists_mutex);
|
||||
bl = switch_core_hash_find(globals.lists, argv[1]);
|
||||
switch_mutex_unlock(globals.lists_mutex);
|
||||
|
||||
if (!bl) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown blacklist [%s]\n", argv[1]);
|
||||
stream->write_function(stream, "-ERR Unknown blacklist\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(bl->list_mutex);
|
||||
switch_core_hash_insert(bl->list, argv[2], (void*)SWITCH_TRUE);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added [%s] to list [%s]\n", argv[2], argv[1]);
|
||||
switch_mutex_unlock(bl->list_mutex);
|
||||
stream->write_function(stream, "+OK\n");
|
||||
} else if (!strcasecmp(argv[0], "del")) {
|
||||
blacklist_t *bl = NULL;
|
||||
if (argc < 2 || zstr(argv[1]) || zstr(argv[2])) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Wrong syntax");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(globals.lists_mutex);
|
||||
bl = switch_core_hash_find(globals.lists, argv[1]);
|
||||
switch_mutex_unlock(globals.lists_mutex);
|
||||
|
||||
if (!bl) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown blacklist [%s]\n", argv[1]);
|
||||
stream->write_function(stream, "-ERR Unknown blacklist\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(bl->list_mutex);
|
||||
switch_core_hash_insert(bl->list, argv[2], NULL);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Removed [%s] from list [%s]\n", argv[2], argv[1]);
|
||||
switch_mutex_unlock(bl->list_mutex);
|
||||
stream->write_function(stream, "+OK\n");
|
||||
} else if (!strcasecmp(argv[0], "dump")) {
|
||||
switch_hash_index_t *hi;
|
||||
void *val;
|
||||
const void *var;
|
||||
blacklist_t *bl = NULL;
|
||||
char *filename = NULL;
|
||||
switch_file_t *fd;
|
||||
|
||||
if (argc < 1 || zstr(argv[1])) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Missing blacklist name");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(globals.lists_mutex);
|
||||
bl = switch_core_hash_find(globals.lists, argv[1]);
|
||||
switch_mutex_unlock(globals.lists_mutex);
|
||||
|
||||
switch_mutex_lock(globals.files_mutex);
|
||||
filename = switch_core_hash_find(globals.files, argv[1]);
|
||||
switch_mutex_unlock(globals.files_mutex);
|
||||
|
||||
if (!bl) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown blacklist [%s]\n", argv[1]);
|
||||
stream->write_function(stream, "-ERR Unknown blacklist\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Dumping %s to %s\n", argv[1], filename);
|
||||
|
||||
switch_mutex_lock(globals.lists_mutex);
|
||||
if (switch_file_open(&fd, filename, SWITCH_FOPEN_WRITE, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, globals.pool) == SWITCH_STATUS_SUCCESS) {
|
||||
for (hi = switch_hash_first(NULL, bl->list); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
switch_file_printf(fd, "%s\n", (char *)var);
|
||||
}
|
||||
stream->write_function(stream, "+OK\n");
|
||||
}
|
||||
switch_mutex_unlock(globals.lists_mutex);
|
||||
} else if (!strcasecmp(argv[0], "reload")) {
|
||||
do_config(SWITCH_TRUE);
|
||||
stream->write_function(stream, "+OK\n");
|
||||
} else if (!strcasecmp(argv[0], "help")) {
|
||||
stream->write_function(stream, BLACKLIST_API_SYNTAX "+OK\n");
|
||||
} else if (!zstr(argv[0])) {
|
||||
stream->write_function(stream, "-ERR: No such command: %s (see 'blacklist help')\n", argv[0]);
|
||||
}
|
||||
|
||||
done:
|
||||
switch_safe_free(data);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_blacklist_load)
|
||||
{
|
||||
switch_api_interface_t *api_interface;
|
||||
//switch_application_interface_t *app_interface;
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
globals.pool = pool;
|
||||
|
||||
switch_core_hash_init(&globals.files, globals.pool);
|
||||
switch_mutex_init(&globals.files_mutex, SWITCH_MUTEX_NESTED, globals.pool);
|
||||
|
||||
switch_core_hash_init(&globals.lists, globals.pool);
|
||||
switch_mutex_init(&globals.lists_mutex, SWITCH_MUTEX_NESTED, globals.pool);
|
||||
|
||||
do_config(SWITCH_FALSE);
|
||||
|
||||
SWITCH_ADD_API(api_interface, "blacklist", "Control blacklists", blacklist_api_function, "");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_blacklist_shutdown)
|
||||
{
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4
|
||||
*/
|
@ -1840,6 +1840,15 @@ SWITCH_STANDARD_API(ctl_function)
|
||||
switch_core_session_ctl(SCSC_VERBOSE_EVENTS, &arg);
|
||||
|
||||
stream->write_function(stream, "+OK verbose_events is %s \n", arg ? "on" : "off");
|
||||
} else if (!strcasecmp(argv[0], "threaded_system_exec")) {
|
||||
arg = -1;
|
||||
if (argv[1]) {
|
||||
arg = switch_true(argv[1]);
|
||||
}
|
||||
|
||||
switch_core_session_ctl(SCSC_THREADED_SYSTEM_EXEC, &arg);
|
||||
|
||||
stream->write_function(stream, "+OK threaded_system_exec is %s \n", arg ? "true" : "false");
|
||||
|
||||
} else if (!strcasecmp(argv[0], "save_history")) {
|
||||
switch_core_session_ctl(SCSC_SAVE_HISTORY, NULL);
|
||||
@ -4020,12 +4029,12 @@ SWITCH_STANDARD_API(show_function)
|
||||
}
|
||||
if (strchr(argv[2], '%')) {
|
||||
sprintf(sql,
|
||||
"select * from channels where hostname='%s' and uuid like '%s' or name like '%s' or cid_name like '%s' or cid_num like '%s' order by created_epoch",
|
||||
hostname, argv[2], argv[2], argv[2], argv[2]);
|
||||
"select * from channels where hostname='%s' and uuid like '%s' or name like '%s' or cid_name like '%s' or cid_num like '%s' or presence_data like '%s' order by created_epoch",
|
||||
hostname, argv[2], argv[2], argv[2], argv[2], argv[2]);
|
||||
} else {
|
||||
sprintf(sql,
|
||||
"select * from channels where hostname='%s' and uuid like '%%%s%%' or name like '%%%s%%' or cid_name like '%%%s%%' or cid_num like '%%%s%%' order by created_epoch",
|
||||
hostname, argv[2], argv[2], argv[2], argv[2]);
|
||||
"select * from channels where hostname='%s' and uuid like '%%%s%%' or name like '%%%s%%' or cid_name like '%%%s%%' or cid_num like '%%%s%%' or presence_data like '%%%s%%' order by created_epoch",
|
||||
hostname, argv[2], argv[2], argv[2], argv[2], argv[2]);
|
||||
|
||||
}
|
||||
|
||||
@ -4069,11 +4078,11 @@ SWITCH_STANDARD_API(show_function)
|
||||
holder.print_title = 0;
|
||||
if ((cmdname = strchr(command, ' ')) && strcasecmp(cmdname, "as")) {
|
||||
*cmdname++ = '\0';
|
||||
switch_snprintf(sql, sizeof(sql) - 1,
|
||||
"select name, syntax, description, ikey from interfaces where hostname='%s' and type = 'api' and name = '%s' order by name",
|
||||
switch_snprintfv(sql, sizeof(sql),
|
||||
"select name, syntax, description, ikey from interfaces where hostname='%s' and type = 'api' and name = '%q' order by name",
|
||||
hostname, cmdname);
|
||||
} else {
|
||||
switch_snprintf(sql, sizeof(sql) - 1, "select name, syntax, description, ikey from interfaces where hostname='%s' and type = 'api' order by name", hostname);
|
||||
switch_snprintfv(sql, sizeof(sql), "select name, syntax, description, ikey from interfaces where hostname='%q' and type = 'api' order by name", hostname);
|
||||
}
|
||||
} else if (!strcasecmp(command, "nat_map")) {
|
||||
switch_snprintf(sql, sizeof(sql) - 1,
|
||||
@ -4262,6 +4271,21 @@ SWITCH_STANDARD_API(uuid_flush_dtmf_function)
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(uuid_zombie_exec_function)
|
||||
{
|
||||
switch_core_session_t *fsession;
|
||||
|
||||
if (!zstr(cmd) && (fsession = switch_core_session_locate(cmd))) {
|
||||
switch_channel_set_flag(switch_core_session_get_channel(fsession), CF_ZOMBIE_EXEC);
|
||||
switch_core_session_rwunlock(fsession);
|
||||
stream->write_function(stream, "+OK MMM Brains...\n");
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR no such session\n");
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define SETVAR_SYNTAX "<uuid> <var> [value]"
|
||||
SWITCH_STANDARD_API(uuid_setvar_function)
|
||||
{
|
||||
@ -5322,6 +5346,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_simplify", "Try to cut out of a call path / attended xfer", uuid_simplify_function, SIMPLIFY_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_jitterbuffer", "Try to cut out of a call path / attended xfer",
|
||||
uuid_jitterbuffer_function, JITTERBUFFER_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_zombie_exec", "Set zombie_exec flag on the specified uuid", uuid_zombie_exec_function, "<uuid>");
|
||||
SWITCH_ADD_API(commands_api_interface, "xml_flush_cache", "clear xml cache", xml_flush_function, "<id> <key> <val>");
|
||||
SWITCH_ADD_API(commands_api_interface, "xml_locate", "find some xml", xml_locate_function, "[root | <section> <tag> <tag_attr_name> <tag_attr_val>]");
|
||||
SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, "<command> <args>");
|
||||
@ -5389,7 +5414,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||
switch_console_set_complete("add show codec");
|
||||
switch_console_set_complete("add show complete");
|
||||
switch_console_set_complete("add show dialplan");
|
||||
switch_console_set_complete("add show distinct_channels");
|
||||
switch_console_set_complete("add show detailed_calls");
|
||||
switch_console_set_complete("add show bridged_calls");
|
||||
switch_console_set_complete("add show detailed_bridged_calls");
|
||||
switch_console_set_complete("add show endpoint");
|
||||
switch_console_set_complete("add show file");
|
||||
switch_console_set_complete("add show interfaces");
|
||||
|
@ -436,8 +436,8 @@ static switch_status_t conference_member_play_file(conference_member_t *member,
|
||||
static switch_status_t conference_member_say(conference_member_t *member, char *text, uint32_t leadin);
|
||||
static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop);
|
||||
static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_core_session_t *session, switch_memory_pool_t *pool);
|
||||
static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject,
|
||||
const char *body, const char *type, const char *hint);
|
||||
static switch_status_t chat_send(switch_event_t *message_event);
|
||||
|
||||
|
||||
static void launch_conference_record_thread(conference_obj_t *conference, char *path);
|
||||
static void launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b);
|
||||
@ -2705,19 +2705,16 @@ static void conference_loop_output(conference_member_t *member)
|
||||
if (event->event_id == SWITCH_EVENT_MESSAGE) {
|
||||
char *from = switch_event_get_header(event, "from");
|
||||
char *to = switch_event_get_header(event, "to");
|
||||
char *proto = switch_event_get_header(event, "proto");
|
||||
char *subject = switch_event_get_header(event, "subject");
|
||||
char *hint = switch_event_get_header(event, "hint");
|
||||
char *body = switch_event_get_body(event);
|
||||
char *p, *freeme = NULL;
|
||||
char *p;
|
||||
|
||||
if (to && from && body) {
|
||||
if ((p = strchr(to, '+')) && strncmp(to, CONF_CHAT_PROTO, strlen(CONF_CHAT_PROTO))) {
|
||||
freeme = switch_mprintf("%s+%s@%s", CONF_CHAT_PROTO, member->conference->name, member->conference->domain);
|
||||
to = freeme;
|
||||
switch_event_del_header(event, "to");
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM,
|
||||
"to", "%s+%s@%s", CONF_CHAT_PROTO, member->conference->name, member->conference->domain);
|
||||
}
|
||||
chat_send(proto, from, to, subject, body, NULL, hint);
|
||||
switch_safe_free(freeme);
|
||||
chat_send(event);
|
||||
}
|
||||
}
|
||||
switch_event_destroy(&event);
|
||||
@ -6379,12 +6376,26 @@ static void launch_conference_record_thread(conference_obj_t *conference, char *
|
||||
switch_thread_create(&thread, thd_attr, conference_record_thread_run, rec, rec->pool);
|
||||
}
|
||||
|
||||
static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject,
|
||||
const char *body, const char *type, const char *hint)
|
||||
static switch_status_t chat_send(switch_event_t *message_event)
|
||||
{
|
||||
char name[512] = "", *p, *lbuf = NULL;
|
||||
conference_obj_t *conference = NULL;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
const char *proto;
|
||||
const char *from;
|
||||
const char *to;
|
||||
//const char *subject;
|
||||
const char *body;
|
||||
//const char *type;
|
||||
const char *hint;
|
||||
|
||||
proto = switch_event_get_header(message_event, "proto");
|
||||
from = switch_event_get_header(message_event, "from");
|
||||
to = switch_event_get_header(message_event, "to");
|
||||
//subject = switch_event_get_header(message_event, "subject");
|
||||
body = switch_event_get_body(message_event);
|
||||
//type = switch_event_get_header(message_event, "type");
|
||||
hint = switch_event_get_header(message_event, "hint");
|
||||
|
||||
if ((p = strchr(to, '+'))) {
|
||||
to = ++p;
|
||||
@ -6401,7 +6412,7 @@ static switch_status_t chat_send(const char *proto, const char *from, const char
|
||||
}
|
||||
|
||||
if (!(conference = conference_find(name))) {
|
||||
switch_core_chat_send(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", "Conference not active.", NULL, NULL);
|
||||
switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", "Conference not active.", NULL, NULL);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
@ -6419,7 +6430,7 @@ static switch_status_t chat_send(const char *proto, const char *from, const char
|
||||
|
||||
switch_safe_free(lbuf);
|
||||
|
||||
switch_core_chat_send(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", stream.data, NULL, NULL);
|
||||
switch_core_chat_send_args(proto, CONF_CHAT_PROTO, to, hint && strchr(hint, '/') ? hint : from, "", stream.data, NULL, NULL);
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
@ -622,8 +622,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_db_load)
|
||||
/* register limit interfaces */
|
||||
SWITCH_ADD_LIMIT(limit_interface, "db", limit_incr_db, limit_release_db, limit_usage_db, limit_reset_db, limit_status_db, NULL);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_API(commands_api_interface, "db", "db get/set", db_api_function, "[insert|delete|select]/<realm>/<key>/<value>");
|
||||
switch_console_set_complete("add db insert");
|
||||
switch_console_set_complete("add db delete");
|
||||
|
@ -102,37 +102,50 @@ struct action_binding {
|
||||
char *input;
|
||||
char *string;
|
||||
char *value;
|
||||
switch_digit_action_target_t target;
|
||||
switch_core_session_t *session;
|
||||
};
|
||||
|
||||
static switch_status_t digit_nomatch_action_callback(switch_ivr_dmachine_match_t *match)
|
||||
{
|
||||
switch_core_session_t *session = (switch_core_session_t *) match->user_data;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
char str[DMACHINE_MAX_DIGIT_LEN + 2];
|
||||
switch_channel_t *channel;
|
||||
switch_event_t *event;
|
||||
switch_status_t status;
|
||||
switch_core_session_t *use_session = session;
|
||||
|
||||
if (switch_ivr_dmachine_get_target(match->dmachine) == DIGIT_TARGET_PEER) {
|
||||
if (switch_core_session_get_partner(session, &use_session) != SWITCH_STATUS_SUCCESS) {
|
||||
use_session = session;
|
||||
}
|
||||
}
|
||||
|
||||
channel = switch_core_session_get_channel(use_session);
|
||||
|
||||
|
||||
switch_channel_set_variable(channel, "last_non_matching_digits", match->match_digits);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Digit NOT match binding [%s]\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(use_session), SWITCH_LOG_DEBUG, "%s Digit NOT match binding [%s]\n",
|
||||
switch_channel_get_name(channel), match->match_digits);
|
||||
|
||||
if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "digits", match->match_digits);
|
||||
|
||||
if ((status = switch_core_session_queue_event(session, &event)) != SWITCH_STATUS_SUCCESS) {
|
||||
if ((status = switch_core_session_queue_event(use_session, &event)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_destroy(&event);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
|
||||
switch_core_session_get_name(session));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(use_session), SWITCH_LOG_WARNING, "%s event queue failure.\n",
|
||||
switch_core_session_get_name(use_session));
|
||||
}
|
||||
}
|
||||
|
||||
/* send it back around flagged to skip the dmachine */
|
||||
switch_snprintf(str, sizeof(str), "!%s", match->match_digits);
|
||||
|
||||
switch_channel_queue_dtmf_string(channel, str);
|
||||
/* send it back around and skip the dmachine */
|
||||
switch_channel_queue_dtmf_string(channel, match->match_digits);
|
||||
|
||||
if (use_session != session) {
|
||||
switch_core_session_rwunlock(use_session);
|
||||
}
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -143,9 +156,25 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||
switch_status_t status;
|
||||
int exec = 0;
|
||||
char *string = act->string;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(act->session);
|
||||
switch_channel_t *channel;
|
||||
switch_core_session_t *use_session = act->session;
|
||||
int x = 0;
|
||||
if (switch_ivr_dmachine_get_target(match->dmachine) == DIGIT_TARGET_PEER || act->target == DIGIT_TARGET_PEER || act->target == DIGIT_TARGET_BOTH) {
|
||||
if (switch_core_session_get_partner(act->session, &use_session) != SWITCH_STATUS_SUCCESS) {
|
||||
use_session = act->session;
|
||||
}
|
||||
}
|
||||
|
||||
top:
|
||||
x++;
|
||||
|
||||
string = act->string;
|
||||
exec = 0;
|
||||
|
||||
channel = switch_core_session_get_channel(use_session);
|
||||
|
||||
switch_channel_set_variable(channel, "last_matching_digits", match->match_digits);
|
||||
|
||||
|
||||
if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_DEBUG, "%s Digit match binding [%s][%s]\n",
|
||||
@ -163,31 +192,62 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute", exec == 2 ? "non-blocking" : "blocking");
|
||||
}
|
||||
|
||||
if ((status = switch_core_session_queue_event(act->session, &event)) != SWITCH_STATUS_SUCCESS) {
|
||||
if ((status = switch_core_session_queue_event(use_session, &event)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_destroy(&event);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
|
||||
switch_core_session_get_name(act->session));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(use_session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
|
||||
switch_core_session_get_name(use_session));
|
||||
}
|
||||
}
|
||||
|
||||
if (exec) {
|
||||
char *cmd = switch_core_session_sprintf(act->session, "%s::%s", string, act->value);
|
||||
switch_ivr_broadcast_in_thread(act->session, cmd, SMF_ECHO_ALEG|SMF_HOLD_BLEG);
|
||||
char *cmd = switch_core_session_sprintf(use_session, "%s::%s", string, act->value);
|
||||
switch_ivr_broadcast_in_thread(use_session, cmd, SMF_ECHO_ALEG | (act->target == DIGIT_TARGET_BOTH ? 0 : SMF_HOLD_BLEG));
|
||||
}
|
||||
|
||||
|
||||
if (use_session != act->session) {
|
||||
switch_core_session_rwunlock(use_session);
|
||||
|
||||
if (act->target == DIGIT_TARGET_BOTH) {
|
||||
use_session = act->session;
|
||||
goto top;
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define CLEAR_DIGIT_ACTION_USAGE "<realm>|all"
|
||||
static switch_digit_action_target_t str2target(const char *target_str)
|
||||
{
|
||||
if (!strcasecmp(target_str, "peer")) {
|
||||
return DIGIT_TARGET_PEER;
|
||||
}
|
||||
|
||||
if (!strcasecmp(target_str, "both")) {
|
||||
return DIGIT_TARGET_BOTH;
|
||||
}
|
||||
|
||||
return DIGIT_TARGET_SELF;
|
||||
}
|
||||
|
||||
#define CLEAR_DIGIT_ACTION_USAGE "<realm>|all[,target]"
|
||||
SWITCH_STANDARD_APP(clear_digit_action_function)
|
||||
{
|
||||
//switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
char *realm = (char *) data;
|
||||
char *realm = switch_core_session_strdup(session, data);
|
||||
char *target_str;
|
||||
switch_digit_action_target_t target = DIGIT_TARGET_SELF;
|
||||
|
||||
if ((dmachine = switch_core_session_get_dmachine(session))) {
|
||||
if ((target_str = strchr(realm, ','))) {
|
||||
*target_str++ = '\0';
|
||||
target = str2target(target_str);
|
||||
}
|
||||
|
||||
|
||||
if ((dmachine = switch_core_session_get_dmachine(session, target))) {
|
||||
if (zstr(realm) || !strcasecmp(realm, "all")) {
|
||||
switch_core_session_set_dmachine(session, NULL);
|
||||
switch_core_session_set_dmachine(session, NULL, target);
|
||||
switch_ivr_dmachine_destroy(&dmachine);
|
||||
} else {
|
||||
switch_ivr_dmachine_clear_realm(dmachine, realm);
|
||||
@ -195,49 +255,41 @@ SWITCH_STANDARD_APP(clear_digit_action_function)
|
||||
}
|
||||
}
|
||||
|
||||
#define DIGIT_ACTION_SET_REALM_USAGE "<realm>"
|
||||
#define DIGIT_ACTION_SET_REALM_USAGE "<realm>[,<target>]"
|
||||
SWITCH_STANDARD_APP(digit_action_set_realm_function)
|
||||
{
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
char *realm = (char *) data;
|
||||
char *realm = switch_core_session_strdup(session, data);
|
||||
char *target_str;
|
||||
switch_digit_action_target_t target = DIGIT_TARGET_SELF;
|
||||
|
||||
if ((target_str = strchr(realm, ','))) {
|
||||
*target_str++ = '\0';
|
||||
target = str2target(target_str);
|
||||
}
|
||||
|
||||
if (zstr(data)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", DIGIT_ACTION_SET_REALM_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((dmachine = switch_core_session_get_dmachine(session))) {
|
||||
if ((dmachine = switch_core_session_get_dmachine(session, target))) {
|
||||
switch_ivr_dmachine_set_realm(dmachine, realm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define BIND_DIGIT_ACTION_USAGE "<realm>,<digits|~regex>,<string>,<value>"
|
||||
SWITCH_STANDARD_APP(bind_digit_action_function)
|
||||
|
||||
static void bind_to_session(switch_core_session_t *session,
|
||||
const char *arg0, const char *arg1, const char *arg2, const char *arg3,
|
||||
switch_digit_action_target_t target, switch_digit_action_target_t bind_target)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
char *mydata;
|
||||
int argc = 0;
|
||||
char *argv[4] = { 0 };
|
||||
struct action_binding *act;
|
||||
switch_ivr_dmachine_t *dmachine;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (zstr(data)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
mydata = switch_core_session_strdup(session, data);
|
||||
|
||||
argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
||||
if (argc < 4 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2]) || zstr(argv[3])) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!(dmachine = switch_core_session_get_dmachine(session))) {
|
||||
if (!(dmachine = switch_core_session_get_dmachine(session, target))) {
|
||||
uint32_t digit_timeout = 1500;
|
||||
uint32_t input_timeout = 0;
|
||||
const char *var;
|
||||
@ -256,20 +308,69 @@ SWITCH_STANDARD_APP(bind_digit_action_function)
|
||||
}
|
||||
|
||||
switch_ivr_dmachine_create(&dmachine, "DPTOOLS", NULL, digit_timeout, input_timeout, NULL, digit_nomatch_action_callback, session);
|
||||
switch_core_session_set_dmachine(session, dmachine);
|
||||
switch_core_session_set_dmachine(session, dmachine, target);
|
||||
}
|
||||
|
||||
|
||||
act = switch_core_session_alloc(session, sizeof(*act));
|
||||
act->realm = argv[0];
|
||||
act->input = argv[1];
|
||||
act->string = argv[2];
|
||||
act->value = argv[3];
|
||||
act->realm = switch_core_session_strdup(session, arg0);
|
||||
act->input = switch_core_session_strdup(session, arg1);
|
||||
act->string = switch_core_session_strdup(session, arg2);
|
||||
act->value = switch_core_session_strdup(session, arg3);
|
||||
act->target = bind_target;
|
||||
act->session = session;
|
||||
|
||||
switch_ivr_dmachine_bind(dmachine, act->realm, act->input, 0, digit_action_callback, act);
|
||||
}
|
||||
|
||||
#define BIND_DIGIT_ACTION_USAGE "<realm>,<digits|~regex>,<string>,<value>[,<dtmf target leg>][,<event target leg>]"
|
||||
SWITCH_STANDARD_APP(bind_digit_action_function)
|
||||
{
|
||||
|
||||
char *mydata;
|
||||
int argc = 0;
|
||||
char *argv[6] = { 0 };
|
||||
switch_digit_action_target_t target, bind_target;
|
||||
char *target_str = "self", *bind_target_str = "self";
|
||||
|
||||
if (zstr(data)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
mydata = switch_core_session_strdup(session, data);
|
||||
|
||||
argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
|
||||
if (argc < 4 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2]) || zstr(argv[3])) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv[4]) {
|
||||
target_str = argv[4];
|
||||
}
|
||||
|
||||
if (argv[5]) {
|
||||
bind_target_str = argv[5];
|
||||
}
|
||||
|
||||
target = str2target(target_str);
|
||||
bind_target = str2target(bind_target_str);
|
||||
|
||||
|
||||
switch(target) {
|
||||
case DIGIT_TARGET_PEER:
|
||||
bind_to_session(session, argv[0], argv[1], argv[2], argv[3], DIGIT_TARGET_PEER, bind_target);
|
||||
break;
|
||||
case DIGIT_TARGET_BOTH:
|
||||
bind_to_session(session, argv[0], argv[1], argv[2], argv[3], DIGIT_TARGET_PEER, bind_target);
|
||||
bind_to_session(session, argv[0], argv[1], argv[2], argv[3], DIGIT_TARGET_SELF, bind_target);
|
||||
break;
|
||||
default:
|
||||
bind_to_session(session, argv[0], argv[1], argv[2], argv[3], DIGIT_TARGET_SELF, bind_target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR grammaron/grammaroff <gram_name> OR grammarsalloff OR pause OR resume OR start_input_timers OR stop OR param <name> <value>"
|
||||
SWITCH_STANDARD_APP(detect_speech_function)
|
||||
@ -904,6 +1005,18 @@ SWITCH_STANDARD_APP(eval_function)
|
||||
return;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(zombie_function)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (switch_channel_up(channel)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s MMM Brains....\n", switch_channel_get_name(channel));
|
||||
switch_channel_set_flag(channel, CF_ZOMBIE_EXEC);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_STANDARD_APP(hangup_function)
|
||||
{
|
||||
@ -1271,6 +1384,7 @@ SWITCH_STANDARD_APP(event_function)
|
||||
switch_assert(new);
|
||||
memcpy(new, val, len);
|
||||
event->subclass_name = new;
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, var, val);
|
||||
} else {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, var, val);
|
||||
}
|
||||
@ -1447,7 +1561,7 @@ SWITCH_STANDARD_API(chat_api_function)
|
||||
if (!zstr(cmd) && (lbuf = strdup(cmd))
|
||||
&& (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) >= 4) {
|
||||
|
||||
if (switch_core_chat_send(argv[0], "dp", argv[1], argv[2], "", argv[3], !zstr(argv[4]) ? argv[4] : NULL, "") == SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_core_chat_send_args(argv[0], "dp", argv[1], argv[2], "", argv[3], !zstr(argv[4]) ? argv[4] : NULL, "") == SWITCH_STATUS_SUCCESS) {
|
||||
stream->write_function(stream, "Sent");
|
||||
} else {
|
||||
stream->write_function(stream, "Error! Message Not Sent");
|
||||
@ -3270,44 +3384,51 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", WAIT_FOR_SILENCE_SYNTAX);
|
||||
}
|
||||
|
||||
static switch_status_t event_chat_send(const char *proto, const char *from, const char *to, const char *subject,
|
||||
const char *body, const char *type, const char *hint)
|
||||
static switch_status_t event_chat_send(switch_event_t *message_event)
|
||||
|
||||
{
|
||||
switch_event_t *event;
|
||||
const char *to;
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_RECV_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||
if (proto)
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Proto", proto);
|
||||
if (from)
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "From", from);
|
||||
if (subject)
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Subject", subject);
|
||||
if (hint)
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hint", hint);
|
||||
if (body)
|
||||
switch_event_add_body(event, "%s", body);
|
||||
if (to) {
|
||||
char *v;
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "To", to);
|
||||
if ((v = switch_core_get_variable_dup(to))) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Command", v);
|
||||
free(v);
|
||||
}
|
||||
switch_event_dup(&event, message_event);
|
||||
event->event_id = SWITCH_EVENT_RECV_MESSAGE;
|
||||
|
||||
if ((to = switch_event_get_header(event, "to"))) {
|
||||
char *v;
|
||||
if ((v = switch_core_get_variable_dup(to))) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Command", v);
|
||||
free(v);
|
||||
}
|
||||
|
||||
if (switch_event_fire(&event) == SWITCH_STATUS_SUCCESS) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_event_destroy(&event);
|
||||
}
|
||||
|
||||
if (switch_event_fire(&event) == SWITCH_STATUS_SUCCESS) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_event_destroy(&event);
|
||||
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
}
|
||||
|
||||
static switch_status_t api_chat_send(const char *proto, const char *from, const char *to, const char *subject,
|
||||
const char *body, const char *type, const char *hint)
|
||||
static switch_status_t api_chat_send(switch_event_t *message_event)
|
||||
{
|
||||
const char *proto;
|
||||
const char *from;
|
||||
const char *to;
|
||||
//const char *subject;
|
||||
//const char *body;
|
||||
const char *type;
|
||||
const char *hint;
|
||||
|
||||
proto = switch_event_get_header(message_event, "proto");
|
||||
from = switch_event_get_header(message_event, "from");
|
||||
to = switch_event_get_header(message_event, "to");
|
||||
//subject = switch_event_get_header(message_event, "subject");
|
||||
//body = switch_event_get_body(message_event);
|
||||
type = switch_event_get_header(message_event, "type");
|
||||
hint = switch_event_get_header(message_event, "hint");
|
||||
|
||||
|
||||
if (to) {
|
||||
char *v = NULL;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
@ -3330,7 +3451,7 @@ static switch_status_t api_chat_send(const char *proto, const char *from, const
|
||||
switch_api_execute(cmd, arg, NULL, &stream);
|
||||
|
||||
if (proto) {
|
||||
switch_core_chat_send(proto, "api", to, hint && strchr(hint, '/') ? hint : from, !zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL);
|
||||
switch_core_chat_send_args(proto, "api", to, hint && strchr(hint, '/') ? hint : from, !zstr(type) ? type : NULL, (char *) stream.data, NULL, NULL);
|
||||
}
|
||||
|
||||
switch_safe_free(stream.data);
|
||||
@ -3788,7 +3909,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "digit_action_set_realm", "change binding realm", "",
|
||||
digit_action_set_realm_function, DIGIT_ACTION_SET_REALM_USAGE, SAF_SUPPORT_NOMEDIA);
|
||||
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number",
|
||||
SAF_SUPPORT_NOMEDIA);
|
||||
@ -3812,7 +3932,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
||||
SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "strftime", "strftime", "strftime", strftime_function, "[<epoch>|]<format string>", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "phrase", "Say a Phrase", "Say a Phrase", phrase_function, "<macro_name>,<data>", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "eval", "Do Nothing", "Do Nothing", eval_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "eval", "Do Nothing", "Do Nothing", eval_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "stop", "Do Nothing", "Do Nothing", eval_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "set_zombie_exec", "Enable Zombie Execution", "Enable Zombie Execution",
|
||||
zombie_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "pre_answer", "Pre-Answer the call", "Pre-Answer the call for a channel.", pre_answer_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "answer", "Answer the call", "Answer the call for a channel.", answer_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "hangup", "Hangup the call", "Hangup the call for a channel.", hangup_function, "[<cause>]", SAF_SUPPORT_NOMEDIA);
|
||||
@ -3820,29 +3943,29 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
||||
SWITCH_ADD_APP(app_interface, "presence", "Send Presence", "Send Presence.", presence_function, "<rpid> <status> [<id>]",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "log", "Logs to the logger", LOG_LONG_DESC, log_function, "<log_level> <log_string>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "info", "Display Call Info", "Display Call Info", info_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "event", "Fire an event", "Fire an event", event_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "info", "Display Call Info", "Display Call Info", info_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "event", "Fire an event", "Fire an event", event_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "sound_test", "Analyze Audio", "Analyze Audio", sound_test_function, "", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, export_function, "<varname>=<value>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "bridge_export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, bridge_export_function, "<varname>=<value>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "<varname>=<value>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "push", "Set a channel variable", SET_LONG_DESC, push_function, "<varname>=<value>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "unshift", "Set a channel variable", SET_LONG_DESC, unshift_function, "<varname>=<value>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "set_global", "Set a global variable", SET_GLOBAL_LONG_DESC, set_global_function, "<varname>=<value>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "set_profile_var", "Set a caller profile variable", SET_PROFILE_VAR_LONG_DESC, set_profile_var_function,
|
||||
"<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
"<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "unset", "Unset a channel variable", UNSET_LONG_DESC, unset_function, "<varname>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "remove_bugs", "Remove media bugs", "Remove all media bugs from a channel.", remove_bugs_function, "", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
|
@ -1329,7 +1329,7 @@ static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_da
|
||||
if (digit_str[0]) {
|
||||
char *p = digit_str;
|
||||
while (p && *p) {
|
||||
switch_dtmf_t dtmf;
|
||||
switch_dtmf_t dtmf = {0};
|
||||
dtmf.digit = *p;
|
||||
dtmf.duration = switch_core_default_dtmf_duration(0);
|
||||
switch_channel_queue_dtmf(channel, &dtmf);
|
||||
|
@ -1264,8 +1264,9 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
|
||||
if (timeout < h->timeout) timeout = h->timeout;
|
||||
|
||||
if (use_ent) {
|
||||
stream.write_function(&stream, "{ignore_early_media=true,outbound_redirect_fatal=true,leg_timeout=%d,fifo_outbound_uuid=%s,fifo_name=%s}%s:_:",
|
||||
h->timeout, h->uuid, node->name, parsed ? parsed : h->originate_string);
|
||||
stream.write_function(&stream, "{ignore_early_media=true,outbound_redirect_fatal=true,leg_timeout=%d,fifo_outbound_uuid=%s,fifo_name=%s}%s%s",
|
||||
h->timeout, h->uuid, node->name,
|
||||
parsed ? parsed : h->originate_string, (i == cbh->rowcount - 1) ? "" : SWITCH_ENT_ORIGINATE_DELIM);
|
||||
} else {
|
||||
stream.write_function(&stream, "[leg_timeout=%d,fifo_outbound_uuid=%s,fifo_name=%s]%s,",
|
||||
h->timeout, h->uuid, node->name, parsed ? parsed : h->originate_string);
|
||||
@ -1278,10 +1279,6 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void
|
||||
|
||||
originate_string = (char *) stream.data;
|
||||
|
||||
if (originate_string) {
|
||||
end_of(originate_string) = '\0';
|
||||
}
|
||||
|
||||
uuid_list = (char *) stream2.data;
|
||||
|
||||
if (uuid_list) {
|
||||
@ -2537,7 +2534,10 @@ SWITCH_STANDARD_APP(fifo_function)
|
||||
if (orbit_ann) {
|
||||
switch_ivr_play_file(session, NULL, orbit_ann, NULL);
|
||||
}
|
||||
switch_ivr_session_transfer(session, cd.orbit_exten, cd.orbit_dialplan, cd.orbit_context);
|
||||
|
||||
if (strcmp(cd.orbit_exten, "_continue_")) {
|
||||
switch_ivr_session_transfer(session, cd.orbit_exten, cd.orbit_dialplan, cd.orbit_context);
|
||||
}
|
||||
}
|
||||
|
||||
check_ocancel(session);
|
||||
@ -2971,6 +2971,9 @@ SWITCH_STANDARD_APP(fifo_function)
|
||||
switch_safe_free(sql);
|
||||
|
||||
|
||||
switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(other_session));
|
||||
switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session));
|
||||
|
||||
switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session);
|
||||
|
||||
if (outbound_id) {
|
||||
@ -3677,7 +3680,6 @@ void node_dump(switch_stream_handle_t *stream)
|
||||
#define FIFO_API_SYNTAX "list|list_verbose|count|debug|status|importance [<fifo name>]|reparse [del_all]"
|
||||
SWITCH_STANDARD_API(fifo_api_function)
|
||||
{
|
||||
int len = 0;
|
||||
fifo_node_t *node;
|
||||
char *data = NULL;
|
||||
int argc = 0;
|
||||
@ -3772,9 +3774,8 @@ SWITCH_STANDARD_API(fifo_api_function)
|
||||
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
node = (fifo_node_t *) val;
|
||||
len = node_caller_count(node);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d:%d:%d\n", (char *) var, node->consumer_count, node_caller_count(node), len);
|
||||
stream->write_function(stream, "%s:%d:%d\n", (char *) var, node->consumer_count, node_caller_count(node));
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
x++;
|
||||
}
|
||||
@ -3783,9 +3784,8 @@ SWITCH_STANDARD_API(fifo_api_function)
|
||||
stream->write_function(stream, "none\n");
|
||||
}
|
||||
} else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
|
||||
len = node_caller_count(node);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node_caller_count(node), len);
|
||||
stream->write_function(stream, "%s:%d:%d\n", argv[1], node->consumer_count, node_caller_count(node));
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
} else {
|
||||
stream->write_function(stream, "none\n");
|
||||
@ -3795,7 +3795,6 @@ SWITCH_STANDARD_API(fifo_api_function)
|
||||
for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
node = (fifo_node_t *) val;
|
||||
len = node_caller_count(node);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d\n", (char *) var, node->has_outbound);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
@ -3806,7 +3805,6 @@ SWITCH_STANDARD_API(fifo_api_function)
|
||||
stream->write_function(stream, "none\n");
|
||||
}
|
||||
} else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) {
|
||||
len = node_caller_count(node);
|
||||
switch_mutex_lock(node->update_mutex);
|
||||
stream->write_function(stream, "%s:%d\n", argv[1], node->has_outbound);
|
||||
switch_mutex_unlock(node->update_mutex);
|
||||
|
@ -945,7 +945,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_hash_load)
|
||||
switch_scheduler_add_task(switch_epoch_time_now(NULL) + LIMIT_HASH_CLEANUP_INTERVAL, limit_hash_cleanup_callback, "limit_hash_cleanup", "mod_hash", 0, NULL,
|
||||
SSHF_NONE);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "hash", "Insert into the hashtable", HASH_DESC, hash_function, HASH_USAGE, SAF_SUPPORT_NOMEDIA)
|
||||
SWITCH_ADD_APP(app_interface, "hash", "Insert into the hashtable", HASH_DESC, hash_function, HASH_USAGE, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC)
|
||||
SWITCH_ADD_API(commands_api_interface, "hash", "hash get/set", hash_api_function, "[insert|delete|select]/<realm>/<key>/<value>");
|
||||
SWITCH_ADD_API(commands_api_interface, "hash_dump", "dump hash/limit_hash data (used for synchronization)", hash_dump_function, HASH_DUMP_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "hash_remote", "hash remote", hash_remote_function, HASH_REMOTE_SYNTAX);
|
||||
|
@ -605,6 +605,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
||||
char *key = NULL;
|
||||
int i = 0;
|
||||
int r = 0;
|
||||
switch_bool_t lcr_skipped = SWITCH_TRUE; /* assume we'll throw it away, paranoid about leak */
|
||||
|
||||
switch_memory_pool_t *pool = cbt->pool;
|
||||
|
||||
@ -669,6 +670,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error inserting into dedup hash\n");
|
||||
r = -1; goto end;
|
||||
}
|
||||
lcr_skipped = SWITCH_FALSE;
|
||||
r = 0; goto end;
|
||||
}
|
||||
|
||||
@ -698,6 +700,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error inserting into dedup hash\n");
|
||||
r = -1; goto end;
|
||||
}
|
||||
lcr_skipped = SWITCH_FALSE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -719,6 +722,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error inserting into dedup hash\n");
|
||||
r = -1; goto end;
|
||||
}
|
||||
lcr_skipped = SWITCH_FALSE;
|
||||
break;
|
||||
} else if (current->next == NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "adding %s to end of list after %s\n",
|
||||
@ -729,6 +733,7 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error inserting into dedup hash\n");
|
||||
r = -1; goto end;
|
||||
}
|
||||
lcr_skipped = SWITCH_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -736,8 +741,13 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa
|
||||
|
||||
end:
|
||||
|
||||
/* event is freed in lcr_destroy() switch_event_destroy(&additional->fields); */
|
||||
|
||||
/* lcr was not added to any lists, so destroy lcr object here */
|
||||
if (lcr_skipped == SWITCH_TRUE) {
|
||||
/* ensure we didn't accidentally add additional to the list */
|
||||
switch_assert(additional->prev == NULL && current->next != additional);
|
||||
lcr_destroy(additional);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ static struct {
|
||||
SWITCH_STANDARD_API(mongo_mapreduce_function)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
DBClientConnection *conn = NULL;
|
||||
DBClientBase *conn = NULL;
|
||||
char *ns = NULL, *json_query = NULL;
|
||||
|
||||
ns = strdup(cmd);
|
||||
@ -88,7 +88,7 @@ SWITCH_STANDARD_API(mongo_find_one_function)
|
||||
|
||||
if (!zstr(ns) && !zstr(json_query) && !zstr(json_fields)) {
|
||||
|
||||
DBClientConnection *conn = NULL;
|
||||
DBClientBase *conn = NULL;
|
||||
|
||||
try {
|
||||
BSONObj query = fromjson(json_query);
|
||||
@ -124,7 +124,7 @@ static switch_status_t config(void)
|
||||
const char *cf = "mongo.conf";
|
||||
switch_xml_t cfg, xml, settings, param;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
const char *host = "127.0.0.1";
|
||||
const char *conn_str = "127.0.0.1";
|
||||
switch_size_t min_connections = 1, max_connections = 1;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||
@ -139,7 +139,10 @@ static switch_status_t config(void)
|
||||
int tmp;
|
||||
|
||||
if (!strcmp(var, "host")) {
|
||||
host = val;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "'host' is deprecated. use 'connection-string'\n");
|
||||
conn_str = val;
|
||||
} else if (!strcmp(var, "connection-string")) {
|
||||
conn_str = val;
|
||||
} else if (!strcmp(var, "min-connections")) {
|
||||
if ((tmp = atoi(val)) > 0) {
|
||||
min_connections = tmp;
|
||||
@ -158,11 +161,11 @@ static switch_status_t config(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (mongo_connection_pool_create(&globals.conn_pool, min_connections, max_connections, host) != SWITCH_STATUS_SUCCESS) {
|
||||
if (mongo_connection_pool_create(&globals.conn_pool, min_connections, max_connections, conn_str) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Can't create connection pool\n");
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Mongo connection pool created [%s %d/%d]\n", host, (int)min_connections, (int)max_connections);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Mongo connection pool created [%s %d/%d]\n", conn_str, (int)min_connections, (int)max_connections);
|
||||
}
|
||||
|
||||
switch_xml_free(xml);
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef MOD_MONGO_H
|
||||
#define MOD_MONGO_H
|
||||
|
||||
|
||||
#include <client/dbclient.h>
|
||||
#include <client/connpool.h>
|
||||
#include <db/json.h>
|
||||
@ -10,7 +9,7 @@
|
||||
using namespace mongo;
|
||||
|
||||
typedef struct {
|
||||
char *host;
|
||||
char *conn_str;
|
||||
|
||||
switch_size_t min_connections;
|
||||
switch_size_t max_connections;
|
||||
@ -22,16 +21,16 @@ typedef struct {
|
||||
} mongo_connection_pool_t;
|
||||
|
||||
|
||||
switch_status_t mongo_connection_create(DBClientConnection **connection, const char *host);
|
||||
void mongo_connection_destroy(DBClientConnection **conn);
|
||||
switch_status_t mongo_connection_create(DBClientBase **connection, const char *conn_str);
|
||||
void mongo_connection_destroy(DBClientBase **conn);
|
||||
|
||||
switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections,
|
||||
const char *host);
|
||||
const char *conn_str);
|
||||
void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool);
|
||||
|
||||
|
||||
DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool);
|
||||
switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientConnection *conn);
|
||||
DBClientBase *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool);
|
||||
switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientBase *conn);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -10,24 +10,31 @@
|
||||
scoped_conn.done();
|
||||
*/
|
||||
|
||||
switch_status_t mongo_connection_create(DBClientConnection **connection, const char *host)
|
||||
switch_status_t mongo_connection_create(DBClientBase **connection, const char *conn_str)
|
||||
{
|
||||
DBClientConnection *conn = new DBClientConnection();
|
||||
DBClientBase *conn = NULL;
|
||||
string conn_string(conn_str), err_msg;
|
||||
ConnectionString cs = ConnectionString::parse(conn_string, err_msg);
|
||||
|
||||
if (!cs.isValid()) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't parse url: %s\n", err_msg.c_str());
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
try {
|
||||
conn->connect(host);
|
||||
conn = cs.connect(err_msg);
|
||||
} catch (DBException &e) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]\n", host);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]: %s\n", conn_str, err_msg.c_str());
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
*connection = conn;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", host);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", conn_str);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void mongo_connection_destroy(DBClientConnection **conn)
|
||||
void mongo_connection_destroy(DBClientBase **conn)
|
||||
{
|
||||
switch_assert(*conn != NULL);
|
||||
delete *conn;
|
||||
@ -36,12 +43,12 @@ void mongo_connection_destroy(DBClientConnection **conn)
|
||||
}
|
||||
|
||||
switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections,
|
||||
const char *host)
|
||||
const char *conn_str)
|
||||
{
|
||||
switch_memory_pool_t *pool = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
mongo_connection_pool_t *cpool = NULL;
|
||||
DBClientConnection *conn = NULL;
|
||||
DBClientBase *conn = NULL;
|
||||
|
||||
if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
@ -61,13 +68,13 @@ switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool
|
||||
|
||||
cpool->min_connections = min_connections;
|
||||
cpool->max_connections = max_connections;
|
||||
cpool->host = switch_core_strdup(pool, host);
|
||||
cpool->conn_str = switch_core_strdup(pool, conn_str);
|
||||
|
||||
cpool->pool = pool;
|
||||
|
||||
for (cpool->size = 0; cpool->size < min_connections; cpool->size++) {
|
||||
|
||||
if (mongo_connection_create(&conn, host) == SWITCH_STATUS_SUCCESS) {
|
||||
if (mongo_connection_create(&conn, conn_str) == SWITCH_STATUS_SUCCESS) {
|
||||
mongo_connection_pool_put(cpool, conn);
|
||||
} else {
|
||||
break;
|
||||
@ -94,7 +101,7 @@ void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool)
|
||||
switch_assert(cpool != NULL);
|
||||
|
||||
while (switch_queue_trypop(cpool->connections, &data) == SWITCH_STATUS_SUCCESS) {
|
||||
mongo_connection_destroy((DBClientConnection **)&data);
|
||||
mongo_connection_destroy((DBClientBase **)&data);
|
||||
}
|
||||
|
||||
switch_mutex_destroy(cpool->mutex);
|
||||
@ -104,9 +111,9 @@ void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool)
|
||||
}
|
||||
|
||||
|
||||
DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool)
|
||||
DBClientBase *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool)
|
||||
{
|
||||
DBClientConnection *conn = NULL;
|
||||
DBClientBase *conn = NULL;
|
||||
void *data = NULL;
|
||||
|
||||
switch_assert(conn_pool != NULL);
|
||||
@ -114,8 +121,8 @@ DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool
|
||||
switch_mutex_lock(conn_pool->mutex);
|
||||
|
||||
if (switch_queue_trypop(conn_pool->connections, &data) == SWITCH_STATUS_SUCCESS) {
|
||||
conn = (DBClientConnection *) data;
|
||||
} else if (mongo_connection_create(&conn, conn_pool->host) == SWITCH_STATUS_SUCCESS) {
|
||||
conn = (DBClientBase *) data;
|
||||
} else if (mongo_connection_create(&conn, conn_pool->conn_str) == SWITCH_STATUS_SUCCESS) {
|
||||
if (++conn_pool->size > conn_pool->max_connections) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Connection pool is empty. You may want to increase 'max-connections'\n");
|
||||
}
|
||||
@ -130,7 +137,7 @@ DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool
|
||||
return conn;
|
||||
}
|
||||
|
||||
switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientConnection *conn)
|
||||
switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientBase *conn)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
|
287
src/mod/applications/mod_sms/mod_sms.2008.vcproj
Normal file
287
src/mod/applications/mod_sms/mod_sms.2008.vcproj
Normal file
@ -0,0 +1,287 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="mod_sms"
|
||||
ProjectGUID="{11C9BC3D-45E9-46E3-BE84-B8CEE4685E39}"
|
||||
RootNamespace="mod_sms"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\mod_sms.c"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
135
src/mod/applications/mod_sms/mod_sms.2010.vcxproj
Normal file
135
src/mod/applications/mod_sms/mod_sms.2010.vcxproj
Normal file
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>mod_sms</ProjectName>
|
||||
<ProjectGuid>{11C9BC3D-45E9-46E3-BE84-B8CEE4685E39}</ProjectGuid>
|
||||
<RootNamespace>mod_sms</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_sms.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2010.vcxproj">
|
||||
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
508
src/mod/applications/mod_sms/mod_sms.c
Normal file
508
src/mod/applications/mod_sms/mod_sms.c
Normal file
@ -0,0 +1,508 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* mod_sms.c -- Abstract SMS
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
#define SMS_CHAT_PROTO "GLOBAL_SMS"
|
||||
#define MY_EVENT_SEND_MESSAGE "SMS::SEND_MESSAGE"
|
||||
|
||||
/* Prototypes */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sms_shutdown);
|
||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_sms_runtime);
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_sms_load);
|
||||
SWITCH_MODULE_DEFINITION(mod_sms, mod_sms_load, mod_sms_shutdown, NULL);
|
||||
|
||||
|
||||
static void event_handler(switch_event_t *event)
|
||||
{
|
||||
const char *dest_proto = switch_event_get_header(event, "dest_proto");
|
||||
switch_core_chat_send(dest_proto, event);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
BREAK_ON_TRUE,
|
||||
BREAK_ON_FALSE,
|
||||
BREAK_ALWAYS,
|
||||
BREAK_NEVER
|
||||
} break_t;
|
||||
|
||||
|
||||
|
||||
static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_t **extension)
|
||||
{
|
||||
switch_xml_t xcond, xaction, xexpression;
|
||||
char *exten_name = (char *) switch_xml_attr(xexten, "name");
|
||||
int proceed = 0;
|
||||
char *expression_expanded = NULL, *field_expanded = NULL;
|
||||
switch_regex_t *re = NULL;
|
||||
const char *to = switch_event_get_header(event, "to");
|
||||
|
||||
if (!to) {
|
||||
to = "nobody";
|
||||
}
|
||||
|
||||
if (!exten_name) {
|
||||
exten_name = "_anon_";
|
||||
}
|
||||
|
||||
for (xcond = switch_xml_child(xexten, "condition"); xcond; xcond = xcond->next) {
|
||||
char *field = NULL;
|
||||
char *do_break_a = NULL;
|
||||
char *expression = NULL;
|
||||
const char *field_data = NULL;
|
||||
int ovector[30];
|
||||
switch_bool_t anti_action = SWITCH_TRUE;
|
||||
break_t do_break_i = BREAK_ON_FALSE;
|
||||
|
||||
int time_match = switch_xml_std_datetime_check(xcond);
|
||||
|
||||
switch_safe_free(field_expanded);
|
||||
switch_safe_free(expression_expanded);
|
||||
|
||||
if (switch_xml_child(xcond, "condition")) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Nested conditions are not allowed!\n");
|
||||
proceed = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
field = (char *) switch_xml_attr(xcond, "field");
|
||||
|
||||
if ((xexpression = switch_xml_child(xcond, "expression"))) {
|
||||
expression = switch_str_nil(xexpression->txt);
|
||||
} else {
|
||||
expression = (char *) switch_xml_attr_soft(xcond, "expression");
|
||||
}
|
||||
|
||||
if ((expression_expanded = switch_event_expand_headers(event, expression)) == expression) {
|
||||
expression_expanded = NULL;
|
||||
} else {
|
||||
expression = expression_expanded;
|
||||
}
|
||||
|
||||
if ((do_break_a = (char *) switch_xml_attr(xcond, "break"))) {
|
||||
if (!strcasecmp(do_break_a, "on-true")) {
|
||||
do_break_i = BREAK_ON_TRUE;
|
||||
} else if (!strcasecmp(do_break_a, "on-false")) {
|
||||
do_break_i = BREAK_ON_FALSE;
|
||||
} else if (!strcasecmp(do_break_a, "always")) {
|
||||
do_break_i = BREAK_ALWAYS;
|
||||
} else if (!strcasecmp(do_break_a, "never")) {
|
||||
do_break_i = BREAK_NEVER;
|
||||
} else {
|
||||
do_break_a = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (time_match == 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s Date/Time Match (PASS) [%s] break=%s\n",
|
||||
to, exten_name, do_break_a ? do_break_a : "on-false");
|
||||
anti_action = SWITCH_FALSE;
|
||||
} else if (time_match == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s Date/Time Match (FAIL) [%s] break=%s\n",
|
||||
to, exten_name, do_break_a ? do_break_a : "on-false");
|
||||
}
|
||||
|
||||
if (field) {
|
||||
if (strchr(field, '$')) {
|
||||
if ((field_expanded = switch_event_expand_headers(event, field)) == field) {
|
||||
field_expanded = NULL;
|
||||
field_data = field;
|
||||
} else {
|
||||
field_data = field_expanded;
|
||||
}
|
||||
} else {
|
||||
field_data = switch_event_get_header(event, field);
|
||||
}
|
||||
if (!field_data) {
|
||||
field_data = "";
|
||||
}
|
||||
|
||||
if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
|
||||
to, exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
|
||||
anti_action = SWITCH_FALSE;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s Regex (FAIL) [%s] %s(%s) =~ /%s/ break=%s\n",
|
||||
to, exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
|
||||
}
|
||||
} else if (time_match == -1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s Absolute Condition [%s]\n", to, exten_name);
|
||||
anti_action = SWITCH_FALSE;
|
||||
}
|
||||
|
||||
if (anti_action) {
|
||||
for (xaction = switch_xml_child(xcond, "anti-action"); xaction; xaction = xaction->next) {
|
||||
const char *application = switch_xml_attr_soft(xaction, "application");
|
||||
const char *loop = switch_xml_attr(xaction, "loop");
|
||||
const char *data;
|
||||
const char *inline_ = switch_xml_attr_soft(xaction, "inline");
|
||||
int xinline = switch_true(inline_);
|
||||
int loop_count = 1;
|
||||
|
||||
if (!zstr(xaction->txt)) {
|
||||
data = xaction->txt;
|
||||
} else {
|
||||
data = (char *) switch_xml_attr_soft(xaction, "data");
|
||||
}
|
||||
|
||||
if (!*extension) {
|
||||
if ((switch_event_create(extension, SWITCH_EVENT_CLONE)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (loop) {
|
||||
loop_count = atoi(loop);
|
||||
}
|
||||
|
||||
for (;loop_count > 0; loop_count--) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s ANTI-Action %s(%s) %s\n", to, application, data, xinline ? "INLINE" : "");
|
||||
|
||||
if (xinline) {
|
||||
switch_core_execute_chat_app(event, application, data);
|
||||
} else {
|
||||
switch_event_add_header_string(*extension, SWITCH_STACK_BOTTOM, application, zstr(data) ? "__undef" : data);
|
||||
}
|
||||
}
|
||||
proceed = 1;
|
||||
}
|
||||
} else {
|
||||
if (field && strchr(expression, '(')) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DP_MATCH", NULL);
|
||||
switch_capture_regex(re, proceed, field_data, ovector, "DP_MATCH", switch_regex_set_event_header_callback, event);
|
||||
}
|
||||
|
||||
for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) {
|
||||
char *application = (char *) switch_xml_attr_soft(xaction, "application");
|
||||
const char *loop = switch_xml_attr(xaction, "loop");
|
||||
char *data = NULL;
|
||||
char *substituted = NULL;
|
||||
uint32_t len = 0;
|
||||
char *app_data = NULL;
|
||||
const char *inline_ = switch_xml_attr_soft(xaction, "inline");
|
||||
int xinline = switch_true(inline_);
|
||||
int loop_count = 1;
|
||||
|
||||
if (!zstr(xaction->txt)) {
|
||||
data = xaction->txt;
|
||||
} else {
|
||||
data = (char *) switch_xml_attr_soft(xaction, "data");
|
||||
}
|
||||
|
||||
if (field && strchr(expression, '(')) {
|
||||
len = (uint32_t) (strlen(data) + strlen(field_data) + 10) * proceed;
|
||||
if (!(substituted = malloc(len))) {
|
||||
abort();
|
||||
}
|
||||
memset(substituted, 0, len);
|
||||
switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);
|
||||
app_data = substituted;
|
||||
} else {
|
||||
app_data = data;
|
||||
}
|
||||
|
||||
if (!*extension) {
|
||||
if ((switch_event_create(extension, SWITCH_EVENT_CLONE)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (loop) {
|
||||
loop_count = atoi(loop);
|
||||
}
|
||||
for (;loop_count > 0; loop_count--) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s Action %s(%s) %s\n", to, application, app_data, xinline ? "INLINE" : "");
|
||||
|
||||
if (xinline) {
|
||||
switch_core_execute_chat_app(event, application, app_data);
|
||||
} else {
|
||||
switch_event_add_header_string(*extension, SWITCH_STACK_BOTTOM, application, zstr(data) ? "__undef" : data);
|
||||
}
|
||||
}
|
||||
switch_safe_free(substituted);
|
||||
}
|
||||
}
|
||||
switch_regex_safe_free(re);
|
||||
|
||||
if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
|
||||
(anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
switch_regex_safe_free(re);
|
||||
switch_safe_free(field_expanded);
|
||||
switch_safe_free(expression_expanded);
|
||||
return proceed;
|
||||
}
|
||||
|
||||
|
||||
static switch_event_t *chatplan_hunt(switch_event_t *event)
|
||||
{
|
||||
switch_event_t *extension = NULL;
|
||||
switch_xml_t alt_root = NULL, cfg, xml = NULL, xcontext, xexten = NULL;
|
||||
const char *alt_path;
|
||||
const char *context;
|
||||
const char *from;
|
||||
const char *to;
|
||||
|
||||
if (!(context = switch_event_get_header(event, "context"))) {
|
||||
context = "default";
|
||||
}
|
||||
|
||||
if (!(from = switch_event_get_header(event, "from_user"))) {
|
||||
from = switch_event_get_header(event, "from");
|
||||
}
|
||||
|
||||
if (!(to = switch_event_get_header(event, "to_user"))) {
|
||||
to = switch_event_get_header(event, "to");
|
||||
}
|
||||
|
||||
alt_path = switch_event_get_header(event, "alt_path");
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Processing text message %s->%s in context %s\n", from, to, context);
|
||||
|
||||
/* get our handle to the "chatplan" section of the config */
|
||||
|
||||
if (!zstr(alt_path)) {
|
||||
switch_xml_t conf = NULL, tag = NULL;
|
||||
if (!(alt_root = switch_xml_parse_file_simple(alt_path))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of [%s] failed\n", alt_path);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((conf = switch_xml_find_child(alt_root, "section", "name", "chatplan")) && (tag = switch_xml_find_child(conf, "chatplan", NULL, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Getting chatplan from alternate path: %s\n", alt_path);
|
||||
xml = alt_root;
|
||||
cfg = tag;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of chatplan failed\n");
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
if (switch_xml_locate("chatplan", NULL, NULL, NULL, &xml, &cfg, event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of chatplan failed\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* get a handle to the context tag */
|
||||
if (!(xcontext = switch_xml_find_child(cfg, "context", "name", context))) {
|
||||
if (!(xcontext = switch_xml_find_child(cfg, "context", "name", "global"))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Context %s not found\n", context);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
xexten = switch_xml_child(xcontext, "extension");
|
||||
|
||||
while (xexten) {
|
||||
int proceed = 0;
|
||||
const char *cont = switch_xml_attr(xexten, "continue");
|
||||
const char *exten_name = switch_xml_attr(xexten, "name");
|
||||
|
||||
if (!exten_name) {
|
||||
exten_name = "UNKNOWN";
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
|
||||
"Chatplan: %s parsing [%s->%s] continue=%s\n",
|
||||
to, context, exten_name, cont ? cont : "false");
|
||||
|
||||
proceed = parse_exten(event, xexten, &extension);
|
||||
|
||||
if (proceed && !switch_true(cont)) {
|
||||
break;
|
||||
}
|
||||
|
||||
xexten = xexten->next;
|
||||
}
|
||||
|
||||
switch_xml_free(xml);
|
||||
xml = NULL;
|
||||
|
||||
done:
|
||||
switch_xml_free(xml);
|
||||
return extension;
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t chat_send(switch_event_t *message_event)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_event_t *exten;
|
||||
|
||||
if ((exten = chatplan_hunt(message_event))) {
|
||||
switch_event_header_t *hp;
|
||||
|
||||
for (hp = exten->headers; hp; hp = hp->next) {
|
||||
status = switch_core_execute_chat_app(message_event, hp->name, hp->value);
|
||||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch_event_destroy(&exten);
|
||||
status = SWITCH_STATUS_BREAK;
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_CHAT_APP(stop_function)
|
||||
{
|
||||
switch_set_flag(message, EF_NO_CHAT_EXEC);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_CHAT_APP(send_function)
|
||||
{
|
||||
const char *dest_proto = data;
|
||||
|
||||
if (zstr(dest_proto)) {
|
||||
dest_proto = switch_event_get_header(message, "dest_proto");
|
||||
}
|
||||
|
||||
switch_core_chat_send(dest_proto, message);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_CHAT_APP(set_function)
|
||||
{
|
||||
char *var, *val;
|
||||
|
||||
if (data) {
|
||||
var = strdup(data);
|
||||
if ((val = strchr(var, '='))) {
|
||||
*val++ = '\0';
|
||||
}
|
||||
|
||||
if (zstr(val)) {
|
||||
switch_event_del_header(message, var);
|
||||
} else {
|
||||
switch_event_add_header_string(message, SWITCH_STACK_BOTTOM, var, val);
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_CHAT_APP(fire_function)
|
||||
{
|
||||
switch_event_t *fireme;
|
||||
|
||||
switch_event_dup(&fireme, message);
|
||||
switch_event_fire(&fireme);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_CHAT_APP(reply_function)
|
||||
{
|
||||
switch_event_t *reply;
|
||||
const char *proto = switch_event_get_header(message, "proto");
|
||||
|
||||
if (proto) {
|
||||
switch_ivr_create_message_reply(&reply, message, SMS_CHAT_PROTO);
|
||||
|
||||
if (!zstr(data)) {
|
||||
switch_event_set_body(reply, data);
|
||||
}
|
||||
|
||||
switch_core_chat_deliver(proto, &reply);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Macro expands to: switch_status_t mod_sms_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_sms_load)
|
||||
{
|
||||
switch_chat_interface_t *chat_interface;
|
||||
switch_chat_application_interface_t *chat_app_interface;
|
||||
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_CUSTOM, MY_EVENT_SEND_MESSAGE, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
SWITCH_ADD_CHAT(chat_interface, SMS_CHAT_PROTO, chat_send);
|
||||
|
||||
SWITCH_ADD_CHAT_APP(chat_app_interface, "reply", "reply to a message", "reply to a message", reply_function, "", SCAF_NONE);
|
||||
SWITCH_ADD_CHAT_APP(chat_app_interface, "stop", "stop execution", "stop execution", stop_function, "", SCAF_NONE);
|
||||
SWITCH_ADD_CHAT_APP(chat_app_interface, "set", "set a variable", "set a variable", set_function, "", SCAF_NONE);
|
||||
SWITCH_ADD_CHAT_APP(chat_app_interface, "send", "send the message as-is", "send the message as-is", send_function, "", SCAF_NONE);
|
||||
SWITCH_ADD_CHAT_APP(chat_app_interface, "fire", "fire the message", "fire the message", fire_function, "", SCAF_NONE);
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the system shuts down
|
||||
Macro expands to: switch_status_t mod_sms_shutdown() */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sms_shutdown)
|
||||
{
|
||||
switch_event_unbind_callback(event_handler);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4
|
||||
*/
|
@ -12,8 +12,8 @@ SPANDSP_LA=$(SPANDSP_BUILDDIR)/src/libspandsp.la
|
||||
mod_LTLIBRARIES = mod_spandsp.la
|
||||
mod_spandsp_la_SOURCES = mod_spandsp.c udptl.c mod_spandsp_fax.c mod_spandsp_dsp.c mod_spandsp_codecs.c
|
||||
mod_spandsp_la_CFLAGS = $(AM_CFLAGS) -I$(SPANDSP_DIR)/src -I$(TIFF_DIR)/libtiff -I$(SPANDSP_BUILDDIR)/src -I$(TIFF_BUILDDIR)/libtiff -I.
|
||||
mod_spandsp_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LA) $(TIFF_LA)
|
||||
mod_spandsp_la_LDFLAGS = -avoid-version -module -no-undefined -shared -ljpeg
|
||||
mod_spandsp_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LA) $(TIFF_LA) -ljpeg -lz
|
||||
mod_spandsp_la_LDFLAGS = -avoid-version -module -no-undefined -shared
|
||||
|
||||
$(SPANDSP_LA): $(TIFF_LA) $(SPANDSP_DIR) $(SPANDSP_DIR)/.update
|
||||
cd $(SPANDSP_BUILDDIR) && $(MAKE) -j1
|
||||
|
@ -52,7 +52,7 @@ static void spandsp_dtmf_rx_realtime_callback(void *user_data, int code, int lev
|
||||
if (digit) {
|
||||
/* prevent duplicate DTMF */
|
||||
if (digit != pvt->last_digit || (pvt->samples - pvt->last_digit_end) > pvt->min_dup_digit_spacing) {
|
||||
switch_dtmf_t dtmf;
|
||||
switch_dtmf_t dtmf = {0};
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "DTMF BEGIN DETECTED: [%c]\n", digit);
|
||||
pvt->last_digit = digit;
|
||||
dtmf.digit = digit;
|
||||
|
@ -806,7 +806,9 @@ static t38_mode_t negotiate_t38(pvt_t *pvt)
|
||||
switch_channel_set_private(channel, "t38_options", NULL);
|
||||
} else {
|
||||
pvt->t38_mode = T38_MODE_NEGOTIATED;
|
||||
|
||||
switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_NEGOTIATED);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38 SDP Origin = %s\n", t38_options->sdp_o_line);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxVersion = %d\n", t38_options->T38FaxVersion);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38MaxBitRate = %d\n", t38_options->T38MaxBitRate);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "T38FaxFillBitRemoval = %d\n", t38_options->T38FaxFillBitRemoval);
|
||||
@ -827,7 +829,12 @@ static t38_mode_t negotiate_t38(pvt_t *pvt)
|
||||
t38_options->T38FaxVersion = 3;
|
||||
}
|
||||
t38_options->T38MaxBitRate = (pvt->disable_v17) ? 9600 : 14400;
|
||||
t38_options->T38FaxFillBitRemoval = 1;
|
||||
|
||||
/* cisco gets mad when we set this to one in a response where they set it to 0, are we allowed to hardcode this to 1 on responses? */
|
||||
if (!zstr(t38_options->sdp_o_line) && !switch_stristr("cisco", t38_options->sdp_o_line)) {
|
||||
t38_options->T38FaxFillBitRemoval = 1;
|
||||
}
|
||||
|
||||
t38_options->T38FaxTranscodingMMR = 0;
|
||||
t38_options->T38FaxTranscodingJBIG = 0;
|
||||
t38_options->T38FaxRateManagement = "transferredTCF";
|
||||
@ -1204,6 +1211,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
|
||||
} else if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
pvt->t38_mode = T38_MODE_NEGOTIATED;
|
||||
switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_NEGOTIATED);
|
||||
spanfax_init(pvt, T38_MODE);
|
||||
configure_t38(pvt);
|
||||
|
||||
@ -1486,13 +1494,14 @@ static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *sessio
|
||||
spanfax_init(pvt, T38_GATEWAY_MODE);
|
||||
configure_t38(pvt);
|
||||
pvt->t38_mode = T38_MODE_NEGOTIATED;
|
||||
switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_NEGOTIATED);
|
||||
} else {
|
||||
if (negotiate_t38(pvt) != T38_MODE_NEGOTIATED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Could not negotiate T38\n", switch_channel_get_name(channel));
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
goto end_unlock;
|
||||
}
|
||||
|
||||
switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_NEGOTIATED);
|
||||
spanfax_init(pvt, T38_GATEWAY_MODE);
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_valet_parking_load);
|
||||
SWITCH_MODULE_DEFINITION(mod_valet_parking, mod_valet_parking_load, NULL, NULL);
|
||||
|
||||
typedef struct {
|
||||
char ext[256];
|
||||
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||
time_t timeout;
|
||||
} valet_token_t;
|
||||
@ -47,6 +48,7 @@ typedef struct {
|
||||
switch_hash_t *hash;
|
||||
switch_mutex_t *mutex;
|
||||
switch_memory_pool_t *pool;
|
||||
time_t last_timeout_check;
|
||||
} valet_lot_t;
|
||||
|
||||
static valet_lot_t globals = { 0 };
|
||||
@ -92,46 +94,61 @@ static void check_timeouts(void)
|
||||
void *val;
|
||||
time_t now;
|
||||
valet_lot_t *lot;
|
||||
switch_console_callback_match_t *matches = NULL;
|
||||
switch_console_callback_match_node_t *m;
|
||||
switch_hash_index_t *i_hi;
|
||||
const void *i_var;
|
||||
void *i_val;
|
||||
char *i_ext;
|
||||
valet_token_t *token;
|
||||
|
||||
now = switch_epoch_time_now(NULL);
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
if (now - globals.last_timeout_check < 30) {
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
globals.last_timeout_check = now;
|
||||
for (hi = switch_hash_first(NULL, globals.hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_index_t *i_hi;
|
||||
const void *i_var;
|
||||
void *i_val;
|
||||
char *i_ext;
|
||||
valet_token_t *token;
|
||||
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
lot = (valet_lot_t *) val;
|
||||
|
||||
switch_mutex_lock(lot->mutex);
|
||||
|
||||
top:
|
||||
|
||||
for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) {
|
||||
switch_hash_this(i_hi, &i_var, NULL, &i_val);
|
||||
i_ext = (char *) i_var;
|
||||
token = (valet_token_t *) i_val;
|
||||
if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) {
|
||||
switch_core_hash_delete(lot->hash, i_ext);
|
||||
switch_safe_free(token);
|
||||
goto top;
|
||||
}
|
||||
}
|
||||
|
||||
switch_mutex_unlock(lot->mutex);
|
||||
switch_console_push_match(&matches, (const char *) var);
|
||||
}
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
|
||||
if (matches) {
|
||||
for (m = matches->head; m; m = m->next) {
|
||||
|
||||
lot = valet_find_lot(m->val);
|
||||
switch_mutex_lock(lot->mutex);
|
||||
|
||||
top:
|
||||
|
||||
for (i_hi = switch_hash_first(NULL, lot->hash); i_hi; i_hi = switch_hash_next(i_hi)) {
|
||||
switch_hash_this(i_hi, &i_var, NULL, &i_val);
|
||||
i_ext = (char *) i_var;
|
||||
token = (valet_token_t *) i_val;
|
||||
if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) {
|
||||
switch_core_hash_delete(lot->hash, i_ext);
|
||||
switch_safe_free(token);
|
||||
goto top;
|
||||
}
|
||||
}
|
||||
|
||||
switch_mutex_unlock(lot->mutex);
|
||||
}
|
||||
|
||||
switch_console_free_matches(&matches);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int next_id(valet_lot_t *lot, int min, int max, int in)
|
||||
static valet_token_t *next_id(switch_core_session_t *session, valet_lot_t *lot, int min, int max, int in)
|
||||
{
|
||||
int i, r = 0;
|
||||
char buf[128] = "";
|
||||
char buf[256] = "";
|
||||
valet_token_t *token;
|
||||
|
||||
if (!min) {
|
||||
@ -148,9 +165,20 @@ static int next_id(valet_lot_t *lot, int min, int max, int in)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
token = NULL;
|
||||
|
||||
if (r) {
|
||||
switch_snprintf(buf, sizeof(buf), "%d", r);
|
||||
switch_zmalloc(token, sizeof(*token));
|
||||
switch_set_string(token->uuid, switch_core_session_get_uuid(session));
|
||||
switch_set_string(token->ext, buf);
|
||||
switch_core_hash_insert(lot->hash, buf, token);
|
||||
}
|
||||
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
return r;
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
@ -166,12 +194,13 @@ SWITCH_STANDARD_APP(valet_parking_function)
|
||||
const char *var;
|
||||
valet_token_t *token = NULL;
|
||||
|
||||
|
||||
check_timeouts();
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, "valet_announce_slot"))) {
|
||||
play_announce = switch_true(var);
|
||||
}
|
||||
|
||||
check_timeouts();
|
||||
|
||||
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
|
||||
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
|
||||
char *lot_name = argv[0];
|
||||
@ -192,7 +221,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
|
||||
const char *io = argv[2];
|
||||
const char *min = argv[3];
|
||||
const char *max = argv[4];
|
||||
int min_i, max_i, id, in = -1;
|
||||
int min_i, max_i, in = -1;
|
||||
|
||||
if (argc < 5) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Usage: %s\n", VALET_APP_SYNTAX);
|
||||
@ -217,13 +246,13 @@ SWITCH_STANDARD_APP(valet_parking_function)
|
||||
min_i = atoi(min);
|
||||
max_i = atoi(max);
|
||||
|
||||
if (!(id = next_id(lot, min_i, max_i, in))) {
|
||||
if (!(token = next_id(session, lot, min_i, max_i, in))) {
|
||||
switch_ivr_phrase_macro(session, in ? "valet_lot_full" : "valet_lot_empty", "", NULL, NULL);
|
||||
switch_mutex_unlock(lot->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
switch_snprintf(dtmf_buf, sizeof(dtmf_buf), "%d", id);
|
||||
switch_snprintf(dtmf_buf, sizeof(dtmf_buf), "%s", token->ext);
|
||||
ext = dtmf_buf;
|
||||
} else if (!strcasecmp(ext, "ask")) {
|
||||
const char *prompt = "ivr/ivr-enter_ext_pound.wav";
|
||||
@ -269,60 +298,63 @@ SWITCH_STANDARD_APP(valet_parking_function)
|
||||
}
|
||||
}
|
||||
|
||||
switch_mutex_lock(lot->mutex);
|
||||
if ((token = (valet_token_t *) switch_core_hash_find(lot->hash, ext))) {
|
||||
switch_core_session_t *b_session;
|
||||
if (!token) {
|
||||
switch_mutex_lock(lot->mutex);
|
||||
if ((token = (valet_token_t *) switch_core_hash_find(lot->hash, ext))) {
|
||||
switch_core_session_t *b_session;
|
||||
|
||||
if (token->timeout) {
|
||||
const char *var = switch_channel_get_variable(channel, "valet_ticket");
|
||||
if (token->timeout) {
|
||||
const char *var = switch_channel_get_variable(channel, "valet_ticket");
|
||||
|
||||
if (!zstr(var)) {
|
||||
if (!strcmp(var, token->uuid)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Valet ticket %s accepted.\n", var);
|
||||
if (!zstr(var)) {
|
||||
if (!strcmp(var, token->uuid)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Valet ticket %s accepted.\n", var);
|
||||
token->timeout = 0;
|
||||
switch_channel_set_variable(channel, "valet_ticket", NULL);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid token %s\n", token->uuid);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!zstr(token->uuid) && (b_session = switch_core_session_locate(token->uuid))) {
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VALET_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Lot-Name", lot_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Extension", ext);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "bridge");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-To-UUID", switch_core_session_get_uuid(session));
|
||||
switch_channel_event_set_data(switch_core_session_get_channel(b_session), event);
|
||||
switch_event_fire(&event);
|
||||
switch_core_session_rwunlock(b_session);
|
||||
token->timeout = 0;
|
||||
switch_channel_set_variable(channel, "valet_ticket", NULL);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid token %s\n", token->uuid);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), token->uuid);
|
||||
switch_mutex_unlock(lot->mutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!zstr(token->uuid) && (b_session = switch_core_session_locate(token->uuid))) {
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, VALET_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Lot-Name", lot_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Valet-Extension", ext);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "bridge");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridge-To-UUID", switch_core_session_get_uuid(session));
|
||||
switch_channel_event_set_data(switch_core_session_get_channel(b_session), event);
|
||||
switch_event_fire(&event);
|
||||
switch_core_session_rwunlock(b_session);
|
||||
token->timeout = 0;
|
||||
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), token->uuid);
|
||||
switch_mutex_unlock(lot->mutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
token = NULL;
|
||||
|
||||
switch_zmalloc(token, sizeof(*token));
|
||||
switch_set_string(token->uuid, switch_core_session_get_uuid(session));
|
||||
switch_core_hash_insert(lot->hash, ext, token);
|
||||
}
|
||||
|
||||
|
||||
token = NULL;
|
||||
|
||||
if (!(tmp = switch_channel_get_variable(channel, "valet_hold_music"))) {
|
||||
tmp = switch_channel_get_hold_music(channel);
|
||||
}
|
||||
if (tmp)
|
||||
|
||||
if (tmp) {
|
||||
music = tmp;
|
||||
}
|
||||
|
||||
if (!strcasecmp(music, "silence")) {
|
||||
music = "silence_stream://-1";
|
||||
}
|
||||
|
||||
switch_zmalloc(token, sizeof(*token));
|
||||
switch_set_string(token->uuid, switch_core_session_get_uuid(session));
|
||||
switch_core_hash_insert(lot->hash, ext, token);
|
||||
|
||||
|
||||
dest = switch_core_session_sprintf(session, "set:valet_ticket=%s,set:valet_hold_music=%s,sleep:1000,valet_park:%s %s",
|
||||
token->uuid, music, lot_name, ext);
|
||||
switch_channel_set_variable(channel, "inline_destination", dest);
|
||||
@ -337,6 +369,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
|
||||
if ((b_session = switch_core_session_locate(uuid))) {
|
||||
token->timeout = switch_epoch_time_now(NULL) + 10;
|
||||
if (play_announce) {
|
||||
switch_ivr_sleep(session, 1500, SWITCH_TRUE, NULL);
|
||||
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
|
||||
}
|
||||
switch_ivr_session_transfer(b_session, dest, "inline", NULL);
|
||||
@ -348,6 +381,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
|
||||
}
|
||||
|
||||
if (play_announce) {
|
||||
switch_ivr_sleep(session, 1500, SWITCH_TRUE, NULL);
|
||||
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
|
||||
}
|
||||
}
|
||||
@ -452,6 +486,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_valet_parking_load)
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
|
||||
globals.pool = pool;
|
||||
switch_core_hash_init(&globals.hash, NULL);
|
||||
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
|
||||
|
@ -853,6 +853,7 @@ struct call_control {
|
||||
switch_file_handle_t *fh;
|
||||
char buf[4];
|
||||
int noexit;
|
||||
int playback_controls_active;
|
||||
};
|
||||
typedef struct call_control cc_t;
|
||||
|
||||
@ -871,7 +872,13 @@ static switch_status_t control_playback(switch_core_session_t *session, void *in
|
||||
|| dtmf->digit == *cc->profile->prev_msg_key || dtmf->digit == *cc->profile->next_msg_key
|
||||
|| dtmf->digit == *cc->profile->repeat_msg_key
|
||||
|| dtmf->digit == *cc->profile->terminator_key || dtmf->digit == *cc->profile->skip_info_key
|
||||
|| dtmf->digit == *cc->profile->email_key || dtmf->digit == *cc->profile->forward_key)) {
|
||||
|| dtmf->digit == *cc->profile->forward_key)) {
|
||||
*cc->buf = dtmf->digit;
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
|
||||
if (!cc->playback_controls_active
|
||||
&& (dtmf->digit == *cc->profile->email_key)) {
|
||||
*cc->buf = dtmf->digit;
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
@ -907,10 +914,6 @@ static switch_status_t control_playback(switch_core_session_t *session, void *in
|
||||
switch_core_file_seek(fh, &pos, samps, SEEK_CUR);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
if (!cc->noexit && dtmf->digit == *cc->profile->terminator_key) {
|
||||
*cc->buf = dtmf->digit;
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1535,6 +1538,9 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
msg.from = __FILE__;
|
||||
msg.string_arg = cid_buf;
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending display update [%s] to %s\n",
|
||||
cid_buf, switch_channel_get_name(channel));
|
||||
switch_core_session_receive_message(session, &msg);
|
||||
|
||||
if (!zstr(cbt->cid_number) && (vm_announce_cid = switch_channel_get_variable(channel, "vm_announce_cid"))) {
|
||||
@ -1568,11 +1574,11 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t
|
||||
*cc.buf = '\0';
|
||||
memset(&fh, 0, sizeof(fh));
|
||||
cc.fh = &fh;
|
||||
cc.noexit = 1;
|
||||
cc.playback_controls_active = 1;
|
||||
if (switch_file_exists(cbt->file_path, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
|
||||
TRY_CODE(switch_ivr_play_file(session, &fh, cbt->file_path, &args));
|
||||
}
|
||||
cc.noexit = 0;
|
||||
cc.playback_controls_active = 0;
|
||||
}
|
||||
|
||||
if (!*cc.buf && (profile->play_date_announcement == VM_DATE_LAST)) {
|
||||
@ -2010,10 +2016,10 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
|
||||
"username='%s' and domain='%s' and flags='save'",
|
||||
(long) switch_epoch_time_now(NULL), myid, domain_name);
|
||||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
switch_snprintf(sql, sizeof(sql), "select file_path from voicemail_msgs where username='%s' and domain='%s' and flags='delete'", myid,
|
||||
switch_snprintfv(sql, sizeof(sql), "select file_path from voicemail_msgs where username='%q' and domain='%q' and flags='delete'", myid,
|
||||
domain_name);
|
||||
vm_execute_sql_callback(profile, profile->mutex, sql, unlink_callback, NULL);
|
||||
switch_snprintf(sql, sizeof(sql), "delete from voicemail_msgs where username='%s' and domain='%s' and flags='delete'", myid, domain_name);
|
||||
switch_snprintfv(sql, sizeof(sql), "delete from voicemail_msgs where username='%q' and domain='%q' and flags='delete'", myid, domain_name);
|
||||
vm_execute_sql(profile, sql, profile->mutex);
|
||||
vm_check_state = VM_CHECK_FOLDER_SUMMARY;
|
||||
|
||||
@ -2299,7 +2305,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p
|
||||
}
|
||||
|
||||
thepass = thehash = NULL;
|
||||
switch_snprintf(sql, sizeof(sql), "select * from voicemail_prefs where username='%s' and domain='%s'", myid, domain_name);
|
||||
switch_snprintfv(sql, sizeof(sql), "select * from voicemail_prefs where username='%q' and domain='%q'", myid, domain_name);
|
||||
vm_execute_sql_callback(profile, profile->mutex, sql, prefs_callback, &cbt);
|
||||
|
||||
x_params = switch_xml_child(x_user, "variables");
|
||||
@ -2773,6 +2779,10 @@ static switch_status_t deliver_vm(vm_profile_t *profile,
|
||||
|
||||
|
||||
if (send_notify) {
|
||||
if (zstr(vm_notify_email)) {
|
||||
vm_notify_email = vm_email;
|
||||
}
|
||||
|
||||
if (zstr(profile->notify_email_headers)) {
|
||||
headers = switch_mprintf("From: FreeSWITCH mod_voicemail <%s@%s>\n"
|
||||
"Subject: Voicemail from %s %s\nX-Priority: %d", myid, domain_name, caller_id_name, caller_id_number, priority);
|
||||
@ -2841,7 +2851,7 @@ static switch_status_t deliver_vm(vm_profile_t *profile,
|
||||
|
||||
failed:
|
||||
|
||||
if (del_file && file_path) {
|
||||
if (del_file && file_path && switch_file_exists(file_path, pool)) {
|
||||
if (unlink(file_path) != 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to delete file [%s]\n", file_path);
|
||||
}
|
||||
@ -3215,7 +3225,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch_snprintf(sql, sizeof(sql), "select * from voicemail_prefs where username='%s' and domain='%s'", id, domain_name);
|
||||
switch_snprintfv(sql, sizeof(sql), "select * from voicemail_prefs where username='%q' and domain='%q'", id, domain_name);
|
||||
vm_execute_sql_callback(profile, profile->mutex, sql, prefs_callback, &cbt);
|
||||
|
||||
if (!vm_ext) {
|
||||
@ -3317,7 +3327,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p
|
||||
callback.buf = disk_usage;
|
||||
callback.len = sizeof(disk_usage);
|
||||
|
||||
switch_snprintf(sqlstmt, sizeof(sqlstmt), "select sum(message_len) from voicemail_msgs where username='%s' and domain='%s'", id, domain_name);
|
||||
switch_snprintfv(sqlstmt, sizeof(sqlstmt), "select sum(message_len) from voicemail_msgs where username='%q' and domain='%q'", id, domain_name);
|
||||
vm_execute_sql_callback(profile, profile->mutex, sqlstmt, sql2str_callback, &callback);
|
||||
|
||||
if (atoi(disk_usage) >= disk_quota) {
|
||||
@ -3623,7 +3633,7 @@ SWITCH_STANDARD_API(prefs_api_function)
|
||||
|
||||
}
|
||||
|
||||
switch_snprintf(sql, sizeof(sql), "select * from voicemail_prefs where username='%s' and domain='%s'", id, domain);
|
||||
switch_snprintfv(sql, sizeof(sql), "select * from voicemail_prefs where username='%q' and domain='%q'", id, domain);
|
||||
vm_execute_sql_callback(profile, profile->mutex, sql, prefs_callback, &cbt);
|
||||
|
||||
if (!strcasecmp(how, "greeting_path")) {
|
||||
|
@ -489,11 +489,21 @@ static void pres_event_handler(switch_event_t *event)
|
||||
switch_safe_free(sql);
|
||||
}
|
||||
|
||||
static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject,
|
||||
const char *body, const char *type, const char *hint)
|
||||
static switch_status_t chat_send(switch_event_t *message_event)
|
||||
{
|
||||
char *user, *host, *f_user = NULL, *ffrom = NULL, *f_host = NULL, *f_resource = NULL;
|
||||
mdl_profile_t *profile = NULL;
|
||||
const char *proto;
|
||||
const char *from;
|
||||
const char *to;
|
||||
const char *body;
|
||||
const char *hint;
|
||||
|
||||
proto = switch_event_get_header(message_event, "proto");
|
||||
from = switch_event_get_header(message_event, "from");
|
||||
to = switch_event_get_header(message_event, "to");
|
||||
body = switch_event_get_body(message_event);
|
||||
hint = switch_event_get_header(message_event, "hint");
|
||||
|
||||
switch_assert(proto != NULL);
|
||||
|
||||
@ -2876,6 +2886,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
|
||||
char *proto = MDL_CHAT_PROTO;
|
||||
char *pproto = NULL, *ffrom = NULL;
|
||||
char *hint;
|
||||
switch_event_t *event;
|
||||
char *from_user, *from_host;
|
||||
#ifdef AUTO_REPLY
|
||||
if (profile->auto_reply) {
|
||||
ldl_handle_send_msg(handle,
|
||||
@ -2902,10 +2914,41 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
|
||||
from = ffrom;
|
||||
}
|
||||
|
||||
if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */
|
||||
switch_core_chat_send(proto, MDL_CHAT_PROTO, from, to, subject, switch_str_nil(msg), NULL, hint);
|
||||
from_user = strdup(from);
|
||||
if ((from_host = strchr(from_user, '@'))) {
|
||||
*from_host++ = '\0';
|
||||
}
|
||||
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", from);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_user", from_user);
|
||||
if (from_host) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_host", from_host);
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", to);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", subject);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "text/plain");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", hint);
|
||||
|
||||
if (msg) {
|
||||
switch_event_add_body(event, "%s", msg);
|
||||
}
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
|
||||
switch_safe_free(from_user);
|
||||
|
||||
if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */
|
||||
switch_core_chat_send(proto, event);
|
||||
}
|
||||
|
||||
switch_core_chat_send("GLOBAL", event);
|
||||
|
||||
switch_event_destroy(&event);
|
||||
|
||||
switch_safe_free(pproto);
|
||||
switch_safe_free(ffrom);
|
||||
}
|
||||
|
@ -928,7 +928,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
while (p && *p) {
|
||||
switch_dtmf_t dtmf;
|
||||
switch_dtmf_t dtmf = {0};
|
||||
dtmf.digit = *p;
|
||||
dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION;
|
||||
switch_channel_queue_dtmf(channel, &dtmf);
|
||||
|
@ -1,3 +1,6 @@
|
||||
moves the switch_rtp_request_port() call from the contructor to FSH323Connection::CreateRealTimeLogicalChannel() - fix
|
||||
rtp port leak. tnx to Peter Olsson.
|
||||
fix log printing
|
||||
fix small interoperability issues if remote endpoint send progress twice
|
||||
make sure dtmfinband gets initialized
|
||||
make gk-identifier and gk-interface settings optional (documentation sayed that about gk-identifier already)
|
||||
|
@ -413,7 +413,7 @@ bool FSH323EndPoint::Initialise(switch_loadable_module_interface_t *iface)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_fax_old_asn) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "--->fax_old_asn\n");
|
||||
SetT38_IFP_PRE();
|
||||
@ -714,6 +714,7 @@ FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* tran
|
||||
, m_rtp_resetting(0)
|
||||
, m_isRequst_fax(false)
|
||||
, m_channel_hangup(false)
|
||||
, m_RTPlocalPort(0)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"======>FSH323Connection::FSH323Connection [%p]\n",this);
|
||||
|
||||
@ -739,8 +740,6 @@ FSH323Connection::FSH323Connection(FSH323EndPoint& endpoint, H323Transport* tran
|
||||
|
||||
switch_channel_set_state(m_fsChannel, CS_INIT);
|
||||
}
|
||||
|
||||
m_RTPlocalPort = switch_rtp_request_port((const char *)m_RTPlocalIP.AsString());
|
||||
}
|
||||
|
||||
FSH323Connection::~FSH323Connection()
|
||||
@ -974,6 +973,9 @@ H323Channel* FSH323Connection::CreateRealTimeLogicalChannel(const H323Capability
|
||||
|
||||
H323TransportAddress m_h323transportadd = GetSignallingChannel()->GetLocalAddress();
|
||||
m_h323transportadd.GetIpAddress(m_RTPlocalIP);
|
||||
if (!m_RTPlocalPort) {
|
||||
m_RTPlocalPort = switch_rtp_request_port((const char *)m_RTPlocalIP.AsString());
|
||||
}
|
||||
|
||||
return new FSH323_ExternalRTPChannel(*this, capability, dir, sessionID,m_RTPlocalIP,m_RTPlocalPort);
|
||||
}
|
||||
@ -2044,7 +2046,7 @@ PBoolean FSH323_ExternalRTPChannel::Start()
|
||||
, GetMainTypes[m_capability->GetMainType()],(const char*)(m_capability->GetFormatName()),this);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"%s initialise %s codec %s for connection [%p]\n",switch_channel_get_name(m_fsChannel),((GetDirection() == IsReceiver)? " read" : " write")
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"%s Unsupported ptime of %u on %s %s codec %s for connection [%p]\n",switch_channel_get_name(m_fsChannel),((GetDirection() == IsReceiver)? " read" : " write")
|
||||
, GetMainTypes[m_capability->GetMainType()],(const char*)(m_capability->GetFormatName()),this);
|
||||
|
||||
if (GetDirection() == IsReceiver) {
|
||||
|
@ -188,9 +188,14 @@ switch_status_t rtmp_check_auth(rtmp_session_t *rsession, const char *user, cons
|
||||
switch_xml_t xml = NULL, x_param, x_params;
|
||||
switch_bool_t allow_empty_password = SWITCH_FALSE;
|
||||
const char *passwd = NULL;
|
||||
switch_event_t *locate_params;
|
||||
|
||||
switch_event_create(&locate_params, SWITCH_EVENT_GENERAL);
|
||||
switch_assert(locate_params);
|
||||
switch_event_add_header_string(locate_params, SWITCH_STACK_BOTTOM, "source", "mod_rtmp");
|
||||
|
||||
/* Locate user */
|
||||
if (switch_xml_locate_user_merged("id", user, domain, NULL, &xml, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
if (switch_xml_locate_user_merged("id", user, domain, NULL, &xml, locate_params) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_WARNING, "Authentication failed. No such user %s@%s\n", user, domain);
|
||||
goto done;
|
||||
}
|
||||
@ -231,6 +236,9 @@ done:
|
||||
if (xml) {
|
||||
switch_xml_free(xml);
|
||||
}
|
||||
|
||||
switch_event_destroy(&locate_params);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "skypopen.h"
|
||||
#define MDL_CHAT_PROTO "skype"
|
||||
#define SKYPE_CHAT_PROTO "skype"
|
||||
|
||||
#ifdef WIN32
|
||||
/***************/
|
||||
@ -943,7 +943,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||
if(channel){
|
||||
|
||||
while (p && *p) {
|
||||
switch_dtmf_t dtmf;
|
||||
switch_dtmf_t dtmf = {0};
|
||||
dtmf.digit = *p;
|
||||
dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION;
|
||||
switch_channel_queue_dtmf(channel, &dtmf);
|
||||
@ -1858,17 +1858,35 @@ static switch_status_t load_config(int reload_type)
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type,
|
||||
const char *hint)
|
||||
static switch_status_t chat_send(switch_event_t *message_event)
|
||||
|
||||
{
|
||||
char *user = NULL, *host, *f_user = NULL, *f_host = NULL, *f_resource = NULL;
|
||||
private_t *tech_pvt = NULL;
|
||||
int i = 0, found = 0, tried = 0;
|
||||
char skype_msg[1024];
|
||||
|
||||
const char *proto;
|
||||
const char *from;
|
||||
const char *to;
|
||||
const char *subject;
|
||||
const char *body;
|
||||
//const char *type;
|
||||
const char *hint;
|
||||
|
||||
proto = switch_event_get_header(message_event, "proto");
|
||||
from = switch_event_get_header(message_event, "from");
|
||||
to = switch_event_get_header(message_event, "to");
|
||||
subject = switch_event_get_header(message_event, "subject");
|
||||
body = switch_event_get_body(message_event);
|
||||
//type = switch_event_get_header(message_event, "type");
|
||||
hint = switch_event_get_header(message_event, "hint");
|
||||
|
||||
switch_assert(proto != NULL);
|
||||
|
||||
DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, type,
|
||||
//DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, type,
|
||||
// hint ? hint : "NULL");
|
||||
DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body,
|
||||
hint ? hint : "NULL");
|
||||
|
||||
if (!to || !strlen(to)) {
|
||||
@ -1895,7 +1913,9 @@ static switch_status_t chat_send(const char *proto, const char *from, const char
|
||||
*host++ = '\0';
|
||||
}
|
||||
|
||||
DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, type,
|
||||
//DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body, type,
|
||||
// hint ? hint : "NULL");
|
||||
DEBUGA_SKYPE("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", SKYPOPEN_P_LOG, proto, from, to, subject, body,
|
||||
hint ? hint : "NULL");
|
||||
if (hint && strlen(hint)) {
|
||||
//in hint we receive the interface name to use
|
||||
@ -1998,7 +2018,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skypopen_load)
|
||||
SWITCH_ADD_API(commands_api_interface, "skypopen", "Skypopen interface commands", skypopen_function, SKYPOPEN_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "skypopen_chat", "Skypopen_chat interface remote_skypename TEXT", skypopen_chat_function,
|
||||
SKYPOPEN_CHAT_SYNTAX);
|
||||
SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send);
|
||||
SWITCH_ADD_CHAT(chat_interface, SKYPE_CHAT_PROTO, chat_send);
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_INCOMING_CHATMESSAGE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
|
||||
@ -2944,7 +2964,7 @@ int incoming_chatmessage(private_t *tech_pvt, int which)
|
||||
session = switch_core_session_locate(tech_pvt->session_uuid_str);
|
||||
}
|
||||
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SKYPE_CHAT_PROTO);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->chatmessages[which].from_handle);
|
||||
@ -2971,7 +2991,7 @@ int incoming_chatmessage(private_t *tech_pvt, int which)
|
||||
if (!event_sent_to_esl) {
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SKYPE_CHAT_PROTO);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->chatmessages[which].from_handle);
|
||||
@ -2997,6 +3017,33 @@ int incoming_chatmessage(private_t *tech_pvt, int which)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static switch_status_t compat_chat_send(const char *proto, const char *from, const char *to,
|
||||
const char *subject, const char *body, const char *type, const char *hint)
|
||||
{
|
||||
switch_event_t *message_event;
|
||||
switch_status_t status;
|
||||
|
||||
if (switch_event_create(&message_event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
|
||||
switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from);
|
||||
switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to);
|
||||
switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject);
|
||||
switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type);
|
||||
switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint);
|
||||
|
||||
if (body) {
|
||||
switch_event_add_body(message_event, "%s", body);
|
||||
}
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
|
||||
status = chat_send(message_event);
|
||||
switch_event_destroy(&message_event);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(skypopen_chat_function)
|
||||
{
|
||||
@ -3037,11 +3084,11 @@ SWITCH_STANDARD_API(skypopen_chat_function)
|
||||
goto end;
|
||||
} else {
|
||||
|
||||
NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", SKYPOPEN_P_LOG, MDL_CHAT_PROTO, tech_pvt->skype_user,
|
||||
NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", SKYPOPEN_P_LOG, SKYPE_CHAT_PROTO, tech_pvt->skype_user,
|
||||
argv[1], "SIMPLE MESSAGE", switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), tech_pvt->name);
|
||||
|
||||
chat_send(MDL_CHAT_PROTO, tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE",
|
||||
switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, tech_pvt->name);
|
||||
compat_chat_send(SKYPE_CHAT_PROTO, tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE",
|
||||
switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, tech_pvt->name);
|
||||
|
||||
}
|
||||
} else {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user