diff --git a/build/modules.conf.in b/build/modules.conf.in index 13e655672c..bd5d49a7ad 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -100,6 +100,7 @@ say/mod_say_en #say/mod_say_fr #say/mod_say_it #say/mod_say_nl +#say/mod_say_pt say/mod_say_ru #say/mod_say_zh #say/mod_say_hu diff --git a/configure.in b/configure.in index 77df2a614c..d91cf11419 100644 --- a/configure.in +++ b/configure.in @@ -205,10 +205,14 @@ if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then APR_ADDTO(SWITCH_AM_CFLAGS, -DPIC) APR_ADDTO(SWITCH_AM_CFLAGS, -erroff=E_END_OF_LOOP_CODE_NOT_REACHED) APR_ADDTO(SWITCH_AM_CFLAGS, -errtags=yes) + APR_ADDTO(SWITCH_AM_CFLAGS, -D__FUNCTION__=__func__ ) + APR_ADDTO(SWITCH_AM_CFLAGS, -mt) APR_ADDTO(SWITCH_AM_CXXFLAGS, -errtags=yes) APR_ADDTO(SWITCH_AM_CXXFLAGS, -KPIC) APR_ADDTO(SWITCH_AM_CXXFLAGS, -DPIC) APR_ADDTO(SWITCH_AM_CXXFLAGS, "-features=extensions") + APR_ADDTO(SWITCH_AM_CXXFLAGS, -D__FUNCTION__=__func__) + APR_ADDTO(SWITCH_AM_CXXFLAGS, -mt) APR_ADDTO(SWITCH_AM_LDFLAGS, -R${prefix}/lib) if test "${enable_64}" = "yes"; then diff --git a/docs/ChangeLog b/docs/ChangeLog index 96066b6e8c..0ca48c0e81 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -20,6 +20,7 @@ freeswitch (1.0.7) build: Remove mod_spidermonkey from windows 2008 x64 builds - does not work (r:280e894d) build: fix warnings on windows x64 builds src and mods projects - only libsofia included on the libs side (r:45ecbc2f) build: Patch debian init.d script to set ulimit values (r:0eb33e57/FS-2844) + build: add plc to core (r:b7c80a84) 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 @@ -33,6 +34,7 @@ freeswitch (1.0.7) config: Fix phrase files, still missing a sound file (r:6741f350/FS-2742) config: Disallow global-intercept and group-intercept can intercept an outbound call in default dialplan (r:890871ba/FS-2777) config: fix single domain assumption in default config to be more portable *cough* bkw *cough* (r:f987903e) + config: Bump Doxygen.conf version to 1.0.6... belatedly (r:cfeae1ba) core: Add RTCP support (FSRTP-14) core: handle some errors on missing db handle conditions core: add ... and shutdown as a fail-safe when no modules are loaded @@ -145,6 +147,15 @@ freeswitch (1.0.7) core: Application intercept causes FS to stop processing calls (r:12fc65f7/FS-2872) core: fix edge cases for endless loop in sql thread (r:5d7c09ed) core: prevent race while changing codecs mid call (r:7aa72b67) + core: Fix crash in ODBC when SQL Server kills TCP connection (r:5aba96e3/FS-2910) + core: Fix fallback to CORE_DB when MSSQL fails init (r:3406d05b) + core: add new function to init an empty switch_sockaddr_t to avoid an unnecessary dns lookup on 0.0.0.0 (r:009c41d4) + core: fix endless RTP loop in Windows (r:cb2d0736/FS-2924) + core: play_and_get_digits should actually timeout, not last forever... (r:28cab5ed/FS-2923) + core: Fix crash w/o core dump (r:00046ee0/FS-2933) + core: normalize tests for outbound channels to use switch_channel_direction instead of testing for CF_OUTBOUND (r:93cc3dc5) + core: add CF_DIALPLAN (r:3ff07445) + core: tweak on calle[re] id (r:9db4a826) lang: Improve French phrase files (FSCONFIG-23) libapr: Fix issue where after a bridge with a member, uuid of Agent is set to single quote character ' (r:3fee704d/FS-2738) libdingaling: fix race on shutdown causing crash (FSMOD-47) @@ -163,6 +174,8 @@ freeswitch (1.0.7) libesl: fix leak-on-error in esl_connect_timeout() (r:4263d60e) libesl: Call close on connection handle if the connection fails (r:413dcc4c/ESL-50) libesl: allow fs_cli -x to have args up to 1024 chars (was 256) (r:7039ba47) + libesl: Make last_event pointer last longer (r:a15f51d5/ESL-37) + libesl: use a packet buffer for ESL (r:2081bf97) 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) @@ -220,6 +233,8 @@ freeswitch (1.0.7) mod_commands: add escaping empty strings to sql_escape (r:7bd0a5a6/FS-2833) mod_commands: add uuid_fileman : <-- same vals as the callbacks in js and lua to control the currently playing file of a channel from the cli or ESL (for the people who were ignoring me on the conference call so I decided to implement it instead of try to explain it ) (r:c4369fc8) mod_commands: FS-2210 Add support for auto completion for uuid_simplify (r:72bcc01b/FS-2210) + mod_commands: allow epoch in strftime_tz (r:bbf1cd1f) + mod_commands: Dramatic jitterbuffer changes (r:d5470961) 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 @@ -229,6 +244,7 @@ freeswitch (1.0.7) mod_conference: Fix floor change events not always firing (r:8f1767d3/MODAPP-424) mod_conference: refactor conference to use switch_ivr_dmachine for the digit parsing controls are now bound to each member separately based on conference_controls channel var, then the caller-controls param in the profile or a default to "default" (r:ac19f73c) mod_conference: Fix crash on dtmf action (r:4d5389bd/FS-2781) + mod_conference: revert to the last transfered conference on recover (r:d11c83b1) 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) @@ -500,6 +516,11 @@ freeswitch (1.0.7) mod_sofia: Fix wrong IP in VIA and contact HEADER for MESSAGE method while fs run in private network (r:59ea4a1b/FS-2886) mod_sofia: SIP-header History-Info might exist multiple times, but only last header is exposed as a channel variable (r:8cf15012/FS-2881) mod_sofia: Add support to reboot Yealink phone remotely (r:fdc31908/FS-2897) + mod_sofia: Add reuse-connections sofia profile param to allow users to turn off TPTAG_REUSE, thus not re-using TCP connections (r:98ed05cc) + mod_sofia: Make sofia recover also work on custom uuid (r:3a645dee/FS-2913) + mod_sofia: remove check for va_list completely in sofia since i don't even think it happens ever (r:dfecc914) + mod_sofia: have mod_sofia always elect to be the session refresher so we know it will work, also make the session-expires set to 0 imply 100% disabled session timers (r:321013ef) + mod_sofia: Do not set nat mode when the device's network_ip is within the acl also so if your FS is behind nat and your phone is too then it will still make the right decisions (r:6c6eab8c) 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) @@ -515,6 +536,7 @@ freeswitch (1.0.7) mod_spidermonkey: fix seg in js hangup (r:7d554c11) mod_spidermonkey: Fix mod_spidermonkey build on FreeBSD, (Undefined symbol PR_LocalTimeParameters). (r:3edb8419) mod_spy: add support for loopback endpoint (MODAPP-416) + mod_spy: fix crash when session can't be located (r:c4154633/FS-2929) mod_tts_commandline: fix core dump, temp file problem. flush can be called several times (FSMOD-35) mod_unimrcp: fix fortify findings for mod_unimrcp (r:336f0b4e/FSMOD-67) mod_valet_parking: add event data to valet parking hold event diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml index a028a2aae0..41bc69cde1 100644 --- a/docs/phrase/phrase_en.xml +++ b/docs/phrase/phrase_en.xml @@ -221,6 +221,7 @@ + @@ -241,6 +242,8 @@ + + @@ -259,6 +262,12 @@ + + + + + + @@ -362,8 +371,6 @@ - - @@ -390,15 +397,10 @@ - - - - - @@ -409,10 +411,7 @@ - - - @@ -425,20 +424,10 @@ - - - - - - - - - - - - - + + + diff --git a/docs/phrase/phrase_es_ES.xml b/docs/phrase/phrase_es_ES.xml new file mode 100644 index 0000000000..ad99c1bf73 --- /dev/null +++ b/docs/phrase/phrase_es_ES.xml @@ -0,0 +1,994 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/phrase/phrase_es_MX.xml b/docs/phrase/phrase_es_MX.xml new file mode 100644 index 0000000000..527f8c3c89 --- /dev/null +++ b/docs/phrase/phrase_es_MX.xml @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/phrase/phrase_pt_BR.xml b/docs/phrase/phrase_pt_BR.xml new file mode 100644 index 0000000000..9cc400c76b --- /dev/null +++ b/docs/phrase/phrase_pt_BR.xml @@ -0,0 +1,987 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/phrase/phrase_pt_PT.xml b/docs/phrase/phrase_pt_PT.xml new file mode 100644 index 0000000000..a0e59deb85 --- /dev/null +++ b/docs/phrase/phrase_pt_PT.xml @@ -0,0 +1,987 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index af26f7f2af..5e804b7505 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -49,6 +49,7 @@ if HAVE_SNG_ISDN INCS += -I/usr/include/sng_isdn endif +# we needed to separate CFLAGS in FTDM_COMPAT_CFLAGS and FTDM_CFLAGS due to -c99 which causes problems with wanpipe headers FTDM_COMPAT_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_COMPAT_CFLAGS@ @DEFS@ FTDM_CFLAGS = $(INCS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_CFLAGS@ @DEFS@ COMPILE = $(CC) $(FTDM_CFLAGS) @@ -183,8 +184,8 @@ ftmod_analog_em_la_LIBADD = libfreetdm.la if HAVE_LIBSANGOMA mod_LTLIBRARIES += ftmod_wanpipe.la ftmod_wanpipe_la_SOURCES = $(SRC)/ftmod/ftmod_wanpipe/ftmod_wanpipe.c -#some structures within Wanpipe drivers are not c99 compatible, so we need to compile ftmod_wanpipe -#without c99 flags +# some structures within Wanpipe drivers are not c99 compatible, so we need to compile ftmod_wanpipe +# without c99 flags, use FTDM_COMPAT_CFLAGS instead ftmod_wanpipe_la_CFLAGS = $(AM_CFLAGS) $(FTDM_COMPAT_CFLAGS) -D__LINUX__ -I/usr/include/wanpipe ftmod_wanpipe_la_LDFLAGS = -shared -module -avoid-version -lsangoma ftmod_wanpipe_la_LIBADD = libfreetdm.la diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index 592dfd82a3..e26f10b0b2 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -82,7 +82,7 @@ sun) fi ;; *) - COMP_VENDOR_COMPAT_CFLAGS="-Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" + COMP_VENDOR_COMPAT_CFLAGS="-Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" COMP_VENDOR_CFLAGS="-std=c99 $COMP_VENDOR_COMPAT_CFLAGS" ;; esac diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index c459a57c11..7637932b79 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -1136,6 +1136,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi direction = FTDM_BOTTOM_UP; } else if (*argv[1] == 'a') { direction = FTDM_TOP_DOWN; + } else if (*argv[1] == 'r') { + direction = FTDM_RR_DOWN; + } else if (*argv[1] == 'R') { + direction = FTDM_RR_UP; } else { chan_id = atoi(argv[1]); } @@ -1278,6 +1282,10 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi caller_data.dnis.type = outbound_profile->destination_number_ton; } + if ((var = channel_get_variable(session, var_event, "freetdm_calling_party_category"))) { + ftdm_set_calling_party_category(var, (uint8_t *)&caller_data.cpc); + } + if ((var = channel_get_variable(session, var_event, "freetdm_custom_call_data"))) { ftdm_set_string(caller_data.raw_data, var); caller_data.raw_data_len = (uint32_t)strlen(var); diff --git a/libs/freetdm/src/ftdm_call_utils.c b/libs/freetdm/src/ftdm_call_utils.c index 69f2fb4fff..2b72f05b77 100644 --- a/libs/freetdm/src/ftdm_call_utils.c +++ b/libs/freetdm/src/ftdm_call_utils.c @@ -30,6 +30,12 @@ * 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. + * + * Contributors: + * + * Moises Silva + * Ricardo Barroetaveña + * */ #include "private/ftdm_core.h" @@ -144,3 +150,20 @@ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number) return FTDM_SUCCESS; } + +FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target) +{ + uint8_t val; + ftdm_status_t status = FTDM_SUCCESS; + + val = ftdm_str2ftdm_calling_party_category(string); + if (val == FTDM_CPC_INVALID) { + ftdm_log(FTDM_LOG_WARNING, "Invalid category string (%s)\n", string); + val = FTDM_CPC_ORDINARY; + status = FTDM_FAIL; + } + + *target = val; + return status; +} + diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 7fb5afdb59..f0c3c1c278 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -301,6 +301,9 @@ FTDM_STR2ENUM(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t, FTDM_ENUM_NAMES(USER_LAYER1_PROT_NAMES, USER_LAYER1_PROT_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t, USER_LAYER1_PROT_NAMES, FTDM_USER_LAYER1_PROT_INVALID) +FTDM_ENUM_NAMES(CALLING_PARTY_CATEGORY_NAMES, CALLING_PARTY_CATEGORY_STRINGS) +FTDM_STR2ENUM(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t, CALLING_PARTY_CATEGORY_NAMES, FTDM_CPC_INVALID) + static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name); static const char *cut_path(const char *in) @@ -1703,6 +1706,21 @@ static ftdm_status_t __inline__ get_best_rated(ftdm_channel_t **fchan, ftdm_chan return FTDM_SUCCESS; } +static uint32_t __inline__ rr_next(uint32_t last, uint32_t min, uint32_t max, ftdm_direction_t direction) +{ + uint32_t next = min; + + ftdm_log(FTDM_LOG_DEBUG, "last = %d, min = %d, max = %d\n", last, min, max); + + if (direction == FTDM_RR_DOWN) { + next = (last >= max) ? min : ++last; + } else { + next = (last <= min) ? max : --last; + } + return next; +} + + FT_DECLARE(int) ftdm_channel_get_availability(ftdm_channel_t *ftdmchan) { int availability = -1; @@ -1745,6 +1763,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir if (direction == FTDM_TOP_DOWN) { i = 0; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + i = rr_next(group->last_used_index, 0, group->chan_count - 1, direction); } else { i = group->chan_count-1; } @@ -1759,16 +1779,24 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir if (request_voice_channel(check, ftdmchan, caller_data, direction)) { status = FTDM_SUCCESS; + if (direction == FTDM_RR_UP || direction == FTDM_RR_DOWN) { + group->last_used_index = i; + } break; } calculate_best_rate(check, &best_rated, &best_rate); if (direction == FTDM_TOP_DOWN) { - if (i >= group->chan_count) { + if (i >= (group->chan_count - 1)) { break; } i++; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + if (check == best_rated) { + group->last_used_index = i; + } + i = rr_next(i, 0, group->chan_count - 1, direction); } else { if (i == 0) { break; @@ -1847,6 +1875,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (direction == FTDM_TOP_DOWN) { i = 1; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + i = rr_next(span->last_used_index, 1, span->chan_count, direction); } else { i = span->chan_count; } @@ -1857,6 +1887,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (i > span->chan_count) { break; } + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + if (i == span->last_used_index) { + break; + } } else { if (i == 0) { break; @@ -1870,6 +1904,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (request_voice_channel(check, ftdmchan, caller_data, direction)) { status = FTDM_SUCCESS; + if (direction == FTDM_RR_UP || direction == FTDM_RR_DOWN) { + span->last_used_index = i; + } break; } @@ -1877,6 +1914,11 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc if (direction == FTDM_TOP_DOWN) { i++; + } else if (direction == FTDM_RR_DOWN || direction == FTDM_RR_UP) { + if (check == best_rated) { + span->last_used_index = i; + } + i = rr_next(i, 1, span->chan_count, direction); } else { i--; } diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 68f0e9e5a4..8cbc0f4f45 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -515,23 +515,17 @@ static __inline__ void state_advance(ftdm_channel_t *chan) switch (ftdm_channel_get_state(chan)) { case FTDM_CHANNEL_STATE_DOWN: { + ftdm_channel_t *chtmp = chan; chan->call_data = NULL; - ftdm_channel_done(chan); - /* - * Close channel completely, BRI PTMP will thank us - */ - if (ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) { - ftdm_channel_t *chtmp = chan; - if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - } else { - ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n", - ftdm_channel_get_span_id(chan), - ftdm_channel_get_id(chan)); - } + if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n", + ftdm_channel_get_span_id(chan), + ftdm_channel_get_id(chan)); + } else { + ftdm_log(FTDM_LOG_DEBUG, "-- Closed channel %d:%d\n", + ftdm_channel_get_span_id(chan), + ftdm_channel_get_id(chan)); } } break; diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c index ccf7fdf89a..d178de53cd 100644 --- a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c @@ -33,6 +33,7 @@ * Contributors: * * Arnaldo Pereira + * Ricardo Barroetaveña * */ @@ -380,11 +381,72 @@ static void ft_r2_answer_call(ftdm_channel_t *ftdmchan) R2CALL(ftdmchan)->answer_pending = 0; } +static __inline__ ftdm_calling_party_category_t ftdm_openr2_cpc_to_r2_ftdm_cpc(openr2_calling_party_category_t cpc) +{ + switch (cpc) { + case OR2_CALLING_PARTY_CATEGORY_UNKNOWN: + return FTDM_CPC_UNKNOWN; + + case OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER: + return FTDM_CPC_ORDINARY; + + case OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER: + return FTDM_CPC_PRIORITY; + + case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_SUBSCRIBER: + return FTDM_CPC_UNKNOWN; + + case OR2_CALLING_PARTY_CATEGORY_INTERNATIONAL_PRIORITY_SUBSCRIBER: + return FTDM_CPC_UNKNOWN; + + case OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT: + return FTDM_CPC_TEST; + + case OR2_CALLING_PARTY_CATEGORY_PAY_PHONE: + return FTDM_CPC_PAYPHONE; + + case OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL: + return FTDM_CPC_OPERATOR; + } + return FTDM_CPC_INVALID; +} + +static __inline openr2_calling_party_category_t ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdm_calling_party_category_t cpc) +{ + switch (cpc) { + case FTDM_CPC_UNKNOWN: + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; + + case FTDM_CPC_OPERATOR: + return OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL; + + case FTDM_CPC_ORDINARY: + return OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; + + case FTDM_CPC_PRIORITY: + return OR2_CALLING_PARTY_CATEGORY_NATIONAL_PRIORITY_SUBSCRIBER; + + case FTDM_CPC_DATA: + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; + + case FTDM_CPC_TEST: + return OR2_CALLING_PARTY_CATEGORY_TEST_EQUIPMENT; + + case FTDM_CPC_PAYPHONE: + return OR2_CALLING_PARTY_CATEGORY_PAY_PHONE; + + case FTDM_CPC_INVALID: + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; + } + return OR2_CALLING_PARTY_CATEGORY_UNKNOWN; +} + /* this function must be called with the chan mutex held! */ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) { openr2_call_status_t callstatus; ftdm_r2_data_t *r2data; + openr2_calling_party_category_t category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER; r2data = ftdmchan->span->signal_data; @@ -397,6 +459,12 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) ft_r2_clean_call(ftdmchan->call_data); + if (ftdmchan->caller_data.cpc == FTDM_CPC_INVALID || ftdmchan->caller_data.cpc == FTDM_CPC_UNKNOWN) { + category = r2data->category; + } else { + category = ftdm_r2_ftdm_cpc_to_openr2_cpc(ftdmchan->caller_data.cpc); + } + /* start io dump */ if (r2data->mf_dump_size) { ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_INPUT_DUMP, &r2data->mf_dump_size); @@ -404,9 +472,9 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call) } callstatus = openr2_chan_make_call(R2CALL(ftdmchan)->r2chan, - ftdmchan->caller_data.cid_num.digits, + ftdmchan->caller_data.pres == FTDM_PRES_ALLOWED ? ftdmchan->caller_data.cid_num.digits : NULL, ftdmchan->caller_data.dnis.digits, - r2data->category); + category); if (callstatus) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to make call in R2 channel, openr2_chan_make_call failed\n"); @@ -622,6 +690,7 @@ static void ftdm_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, cons } else { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING); } + ftdmchan->caller_data.cpc = ftdm_openr2_cpc_to_r2_ftdm_cpc(category); } /* diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index f40196499c..09208f8d2c 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -31,7 +31,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "private/ftdm_core.h" #include "ftmod_zt.h" diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index 56a9dc0577..69b90f1acd 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -144,7 +144,9 @@ typedef enum { /*! \brief Hunting direction (when hunting for free channels) */ typedef enum { FTDM_TOP_DOWN, - FTDM_BOTTOM_UP + FTDM_BOTTOM_UP, + FTDM_RR_DOWN, + FTDM_RR_UP, } ftdm_direction_t; /*! \brief I/O channel type */ @@ -265,6 +267,21 @@ typedef enum { #define USER_LAYER1_PROT_STRINGS "V.110", "u-law", "a-law", "Invalid" FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_user_layer1_prot_t) +/*! Calling Party Category */ +typedef enum { + FTDM_CPC_UNKNOWN, + FTDM_CPC_OPERATOR, + FTDM_CPC_ORDINARY, + FTDM_CPC_PRIORITY, + FTDM_CPC_DATA, + FTDM_CPC_TEST, + FTDM_CPC_PAYPHONE, + FTDM_CPC_INVALID +} ftdm_calling_party_category_t; +#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid" +FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t) + + /*! \brief Number abstraction */ typedef struct { char digits[25]; @@ -294,7 +311,8 @@ typedef struct ftdm_caller_data { ftdm_bearer_cap_t bearer_capability; /* user information layer 1 protocol */ ftdm_user_layer1_prot_t bearer_layer1; - ftdm_variable_container_t variables; /*! + * Ricardo Barroetaveña + * */ #ifndef __FTDM_CALL_UTILS_H__ @@ -114,5 +120,16 @@ FT_DECLARE(ftdm_status_t) ftdm_set_presentation_ind(const char *string, uint8_t */ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number); +/*! + * \brief Set the Calling Party Category from an enum + * + * \param cpc_string string value + * \param target the target to set value to + * + * \retval FTDM_SUCCESS success + * \retval FTDM_FAIL failure + */ +FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target); + #endif /* __FTDM_CALL_UTILS_H__ */ diff --git a/libs/freetdm/src/include/ftdm_os.h b/libs/freetdm/src/include/ftdm_os.h index 5026bb7236..f3ebee9ea2 100644 --- a/libs/freetdm/src/include/ftdm_os.h +++ b/libs/freetdm/src/include/ftdm_os.h @@ -39,9 +39,12 @@ extern "C" { #endif +#if defined(__linux__) && !defined(__USE_BSD) +#define __USE_BSD +#endif + #include "ftdm_declare.h" #include "ftdm_threadmutex.h" - #include #ifndef __WINDOWS__ diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index 9222da3a42..e8ee7156f8 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -493,6 +493,7 @@ struct ftdm_span { ftdm_trunk_type_t trunk_type; ftdm_analog_start_type_t start_type; ftdm_signal_type_t signal_type; + uint32_t last_used_index; /* Private signaling data. Do not touch unless you are a signaling module */ void *signal_data; fio_signal_cb_t signal_cb; diff --git a/libs/freetdm/src/testsangomaboost.c b/libs/freetdm/src/testsangomaboost.c index b254a08bb8..b007fc186b 100644 --- a/libs/freetdm/src/testsangomaboost.c +++ b/libs/freetdm/src/testsangomaboost.c @@ -48,12 +48,7 @@ #include #include #include -#if defined(__linux__) && !defined(__USE_BSD) -#define __USE_BSD -#endif -#ifndef WIN32 -#include -#endif + #include "freetdm.h" diff --git a/libs/stfu/stfu.c b/libs/stfu/stfu.c index 2ffb86fdb6..b7df8ea870 100644 --- a/libs/stfu/stfu.c +++ b/libs/stfu/stfu.c @@ -413,7 +413,9 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void if (i->last_wr_ts) { if ((ts <= i->last_wr_ts && (i->last_wr_ts != UINT_MAX || ts == i->last_wr_ts))) { - stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); + } if (i->in_queue->array_len < i->in_queue->array_size) { i->in_queue->array_len++; } diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index d6bce5e8bf..e726554d81 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -312,6 +312,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switc */ SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension); +SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel, switch_bool_t in); + /*! \brief Retrieve caller extension from a given channel \param channel channel to retrieve extension from diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 3943ac6ea6..9d9896956e 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -291,6 +291,7 @@ static switch_status_t fifo_queue_popfly(fifo_queue_t *queue, const char *uuid) struct fifo_node { char *name; switch_mutex_t *mutex; + switch_mutex_t *update_mutex; fifo_queue_t *fifo_list[MAX_PRI]; switch_hash_t *consumer_hash; int outbound_priority; @@ -801,6 +802,7 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu switch_core_hash_init(&node->consumer_hash, node->pool); switch_thread_rwlock_create(&node->rwlock, node->pool); switch_mutex_init(&node->mutex, SWITCH_MUTEX_NESTED, node->pool); + switch_mutex_init(&node->update_mutex, SWITCH_MUTEX_NESTED, node->pool); cbt.buf = outbound_count; cbt.len = sizeof(outbound_count); sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", name); @@ -1193,10 +1195,10 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->busy = 0; node->ring_consumer_count = 1; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } else { goto end; } @@ -1437,10 +1439,10 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void cbh->ready = 1; if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->ring_consumer_count = 0; node->busy = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } @@ -1501,10 +1503,10 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) switch_mutex_unlock(globals.mutex); if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->ring_consumer_count++; node->busy = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS); @@ -1601,12 +1603,12 @@ static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) switch_event_destroy(&ovars); if (node) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); if (node->ring_consumer_count-- < 0) { node->ring_consumer_count = 0; } node->busy = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } switch_core_destroy_memory_pool(&h->pool); @@ -1754,9 +1756,35 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o if (globals.debug) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Trying priority: %d\n", cur_priority); + restart: + for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, &var, NULL, &val); if ((node = (fifo_node_t *) val)) { + + if (node->ready == FIFO_DELAY_DESTROY) { + int doit = 0; + + switch_mutex_lock(node->update_mutex); + doit = node->consumer_count == 0 && node_caller_count(node) == 0; + switch_mutex_unlock(node->update_mutex); + + if (doit) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name); + switch_core_hash_delete(globals.fifo_hash, node->name); + + node->ready = 0; + switch_mutex_lock(node->mutex); + switch_core_hash_destroy(&node->consumer_hash); + switch_mutex_unlock(node->mutex); + switch_mutex_unlock(node->update_mutex); + switch_core_destroy_memory_pool(&node->pool); + goto restart; + } + + } + + if (node->outbound_priority == 0) node->outbound_priority = 5; if (node->has_outbound && node->ready && !node->busy && node->outbound_priority == cur_priority) { ppl_waiting = node_caller_count(node); @@ -2219,6 +2247,7 @@ SWITCH_STANDARD_APP(fifo_function) if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) { node = create_node(nlist[i], importance, globals.sql_mutex); node->ready = 1; + switch_thread_rwlock_rdlock(node->rwlock); } node_list[node_count++] = node; } @@ -2306,7 +2335,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_answer(channel); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); if ((pri = switch_channel_get_variable(channel, "fifo_priority"))) { p = atoi(pri); @@ -2344,7 +2373,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(channel, "fifo_priority", tmp); } - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); ts = switch_micro_time_now(); switch_time_exp_lt(&tm, ts); @@ -2450,9 +2479,9 @@ SWITCH_STANDARD_APP(fifo_function) } switch_mutex_lock(globals.mutex); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node_remove_uuid(node, uuid); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); send_presence(node); check_cancel(node); switch_mutex_unlock(globals.mutex); @@ -2682,9 +2711,9 @@ SWITCH_STANDARD_APP(fifo_function) } if (pop && !node_caller_count(node)) { - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); node->start_waiting = 0; - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } } @@ -3074,21 +3103,9 @@ SWITCH_STANDARD_APP(fifo_function) done: - switch_mutex_lock(globals.mutex); - if (node && node->ready == FIFO_DELAY_DESTROY && node->consumer_count == 0 && node_caller_count(node) == 0) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s removed.\n", node->name); - switch_core_hash_delete(globals.fifo_hash, node->name); - switch_thread_rwlock_wrlock(node->rwlock); - node->ready = 0; - switch_mutex_lock(node->mutex); - switch_core_hash_destroy(&node->consumer_hash); - switch_mutex_unlock(node->mutex); + if (node) { switch_thread_rwlock_unlock(node->rwlock); - switch_core_destroy_memory_pool(&node->pool); - } - switch_mutex_unlock(globals.mutex); - switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG); @@ -3699,9 +3716,9 @@ SWITCH_STANDARD_API(fifo_api_function) switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + 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); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); x++; } @@ -3710,9 +3727,9 @@ SWITCH_STANDARD_API(fifo_api_function) } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + 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); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } else { stream->write_function(stream, "none\n"); } @@ -3722,9 +3739,9 @@ SWITCH_STANDARD_API(fifo_api_function) switch_hash_this(hi, &var, NULL, &val); node = (fifo_node_t *) val; len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); stream->write_function(stream, "%s:%d\n", (char *) var, node->has_outbound); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); x++; } @@ -3733,9 +3750,9 @@ SWITCH_STANDARD_API(fifo_api_function) } } else if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { len = node_caller_count(node); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); stream->write_function(stream, "%s:%d\n", argv[1], node->has_outbound); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); } else { stream->write_function(stream, "none\n"); } @@ -4108,7 +4125,7 @@ static switch_status_t load_config(int reload, int del_all) node->ready = FIFO_DELAY_DESTROY; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", node->name); - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); for (x = 0; x < MAX_PRI; x++) { while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) { switch_event_destroy(&pop); @@ -4117,7 +4134,7 @@ static switch_status_t load_config(int reload, int del_all) switch_core_hash_delete(globals.fifo_hash, node->name); switch_core_hash_destroy(&node->consumer_hash); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); switch_core_destroy_memory_pool(&node->pool); goto top; } @@ -4393,7 +4410,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown) switch_hash_this(hi, NULL, NULL, &val); node = (fifo_node_t *) val; - switch_thread_rwlock_wrlock(node->rwlock); + switch_mutex_lock(node->update_mutex); switch_mutex_lock(node->mutex); for (x = 0; x < MAX_PRI; x++) { while (fifo_queue_pop(node->fifo_list[x], &pop, 2) == SWITCH_STATUS_SUCCESS) { @@ -4403,7 +4420,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown) switch_mutex_unlock(node->mutex); switch_core_hash_delete(globals.fifo_hash, node->name); switch_core_hash_destroy(&node->consumer_hash); - switch_thread_rwlock_unlock(node->rwlock); + switch_mutex_unlock(node->update_mutex); switch_core_destroy_memory_pool(&node->pool); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 07e125ad6c..8aa37b95be 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1084,7 +1084,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f tech_pvt->last_ts = 0; /* inform them of the codec they are actually sending */ - +#if 0 if (++tech_pvt->codec_reinvites > 2) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Ok, some devices *cough* X-lite *cough*\n" @@ -1093,7 +1093,10 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f } else { sofia_glue_do_invite(session); } +#endif + *frame = &silence_frame; + return SWITCH_STATUS_SUCCESS; } } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 0f52bbc8fb..029f60ad33 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2669,7 +2669,8 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force) tech_pvt->rm_encoding, tech_pvt->codec_ms, tech_pvt->rm_rate); - + + switch_yield(tech_pvt->read_impl.microseconds_per_packet); switch_core_session_lock_codec_write(tech_pvt->session); switch_core_session_lock_codec_read(tech_pvt->session); resetting = 1; diff --git a/src/mod/say/mod_say_es/mod_say_es.c b/src/mod/say/mod_say_es/mod_say_es.c index cf4d2f9b12..ff0ee944c2 100644 --- a/src/mod/say/mod_say_es/mod_say_es.c +++ b/src/mod/say/mod_say_es/mod_say_es.c @@ -39,8 +39,9 @@ * * Anthony Minessale II * Michael B. Murdock + * François Delawarde * - * mod_say_es.c -- Say for English + * mod_say_es.c -- Say for Spanish * */ @@ -102,7 +103,7 @@ static switch_status_t play_group(switch_say_method_t method, int a, int b, int break; default: say_file("digits/%d.wav", a); - say_file("digits/hundred.wav"); + say_file("digits/hundreds.wav"); break; } } @@ -175,7 +176,12 @@ static switch_status_t es_say_general_count(switch_core_session_t *session, char switch (say_args->method) { case SSM_COUNTED: case SSM_PRONOUNCED: - if ((status = play_group(SSM_PRONOUNCED, places[8], places[7], places[6], "digits/million.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + /* specific case, one million => un millón */ + if (!places[8] && !places[7] && (places[6] == 1)) { + say_file("digits/un.wav"); + say_file("digits/million.wav"); + } + else if ((status = play_group(SSM_PRONOUNCED, places[8], places[7], places[6], "digits/millions.wav", session, args)) != SWITCH_STATUS_SUCCESS) { return status; } if ((status = play_group(SSM_PRONOUNCED, places[5], places[4], places[3], "digits/thousand.wav", session, args)) != SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/say/mod_say_pt/Makefile b/src/mod/say/mod_say_pt/Makefile new file mode 100644 index 0000000000..2c35e6e98f --- /dev/null +++ b/src/mod/say/mod_say_pt/Makefile @@ -0,0 +1,2 @@ +BASE=../../../.. +include $(BASE)/build/modmake.rules diff --git a/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj b/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj new file mode 100644 index 0000000000..bf8c0333c5 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.2008.vcproj @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj b/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj new file mode 100644 index 0000000000..63fba6fae0 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.2010.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_say_pt + {FA429E98-8B03-45E6-A096-A4BC5E821DE4} + mod_say_pt + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + + + + + false + + + + + + + X64 + + + + + + + false + + + MachineX64 + + + + + + + + + false + + + + + + + X64 + + + + + + + false + + + MachineX64 + + + + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + + + + diff --git a/src/mod/say/mod_say_pt/mod_say_pt.c b/src/mod/say/mod_say_pt/mod_say_pt.c new file mode 100644 index 0000000000..747a0c8984 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.c @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2007, Anthony Minessale II + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * 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. + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * Michael B. Murdock + * António Silva + * + * mod_say_pt.c -- Say for Portuguese + * + */ + +#include +#include +#include + +SWITCH_MODULE_LOAD_FUNCTION(mod_say_pt_load); +SWITCH_MODULE_DEFINITION(mod_say_pt, mod_say_pt_load, NULL, NULL); + +#define say_num(num, meth) { \ + char tmp[80]; \ + switch_status_t tstatus; \ + switch_say_method_t smeth = say_args->method; \ + switch_say_type_t stype = say_args->type; \ + say_args->type = SST_ITEMS; say_args->method = meth; \ + switch_snprintf(tmp, sizeof(tmp), "%u", (unsigned)num); \ + if ((tstatus = \ + pt_say_general_count(session, tmp, say_args, args)) \ + != SWITCH_STATUS_SUCCESS) { \ + return tstatus; \ + } \ + say_args->method = smeth; say_args->type = stype; \ + } \ + + +#define say_file(...) { \ + char tmp[80]; \ + switch_status_t tstatus; \ + switch_snprintf(tmp, sizeof(tmp), __VA_ARGS__); \ + if ((tstatus = \ + switch_ivr_play_file(session, NULL, tmp, args)) \ + != SWITCH_STATUS_SUCCESS){ \ + return tstatus; \ + } \ + if (!switch_channel_ready(switch_core_session_get_channel(session))) { \ + return SWITCH_STATUS_FALSE; \ + }} \ + + +static switch_status_t play_group(switch_say_method_t method, int a, int b, int c, char *what, switch_core_session_t *session, switch_input_args_t *args) +{ + + /*a => 1xx-9xx*/ + if (a) { + switch (a) { + case 1: + if (b || c) { + say_file("digits/hundred.wav"); + } else { + say_file("digits/100.wav"); + } + break; + case 2: + say_file("digits/200.wav"); + break; + case 3: + say_file("digits/300.wav"); + break; + case 5: + say_file("digits/500.wav"); + break; + default: + say_file("digits/%d.wav", a); + say_file("digits/hundreds.wav"); + break; + } + if (b || c) { + say_file("currency/and.wav"); + } + } + /* b => 1x - 9x */ + if (b) { + if (b > 1) { + if (method == SSM_COUNTED) { + say_file("digits/h-%d0.wav", b); + } else { + say_file("digits/%d0.wav", b); + if (c > 0) { + say_file("currency/and.wav"); + } + } + } else { + say_file("digits/%d%d.wav", b, c); + c = 0; + } + } + /* c => 0 - 9*/ + if (c) { + if (method == SSM_COUNTED) { + say_file("digits/h-%d.wav", c); + } else { + say_file("digits/%d.wav", c); + } + } + + if (what && (a || b || c)) { + say_file(what); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t pt_say_general_count(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + int in; + int x = 0; + int places[9] = { 0 }; + char sbuf[128] = ""; + switch_status_t status; + + if (say_args->method == SSM_ITERATED) { + if ((tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)))) { + char *p; + for (p = tosay; p && *p; p++) { + say_file("digits/%c.wav", *p); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + return SWITCH_STATUS_SUCCESS; + } + + if (!(tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf))) || strlen(tosay) > 9) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + + in = atoi(tosay); + + if (in != 0) { + for (x = 8; x >= 0; x--) { + int num = (int) pow(10, x); + if ((places[(uint32_t) x] = in / num)) { + in -= places[(uint32_t) x] * num; + } + } + + switch (say_args->method) { + case SSM_COUNTED: + case SSM_PRONOUNCED: + /* specific case, one million => um milhão */ + if (!places[8] && !places[7] && (places[6] == 1)) { + say_file("digits/1.wav"); + say_file("digits/million.wav"); + } else if ((status = play_group(SSM_PRONOUNCED, places[8], places[7], places[6], "digits/millions.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + return status; + } + if ((status = play_group(SSM_PRONOUNCED, places[5], places[4], places[3], "digits/thousand.wav", session, args)) != SWITCH_STATUS_SUCCESS) { + return status; + } + if ((status = play_group(say_args->method, places[2], places[1], places[0], NULL, session, args)) != SWITCH_STATUS_SUCCESS) { + return status; + } + break; + default: + break; + } + } else { + say_file("digits/0.wav"); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t pt_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + int32_t t; + switch_time_t target = 0, target_now = 0; + switch_time_exp_t tm, tm_now; + uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0; + switch_channel_t *channel = switch_core_session_get_channel(session); + const char *tz = switch_channel_get_variable(channel, "timezone"); + + if (say_args->type == SST_TIME_MEASUREMENT) { + int64_t hours = 0; + int64_t minutes = 0; + int64_t seconds = 0; + int64_t r = 0; + + if (strchr(tosay, ':')) { + char *tme = switch_core_session_strdup(session, tosay); + char *p; + + if ((p = strrchr(tme, ':'))) { + *p++ = '\0'; + seconds = atoi(p); + if ((p = strchr(tme, ':'))) { + *p++ = '\0'; + minutes = atoi(p); + if (tme) { + hours = atoi(tme); + } + } else { + minutes = atoi(tme); + } + } + } else { + if ((seconds = atol(tosay)) <= 0) { + seconds = (int64_t) switch_epoch_time_now(NULL); + } + + if (seconds >= 60) { + minutes = seconds / 60; + r = seconds % 60; + seconds = r; + } + + if (minutes >= 60) { + hours = minutes / 60; + r = minutes % 60; + minutes = r; + } + } + + if (hours) { + say_num(hours, SSM_PRONOUNCED); + if (hours == 1) { + say_file("time/hour.wav"); + } else { + say_file("time/hours.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("time/hours.wav"); + } + + if (minutes) { + say_num(minutes, SSM_PRONOUNCED); + if (minutes == 1) { + say_file("time/minute.wav"); + } else { + say_file("time/minutes.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("time/minutes.wav"); + } + + if (seconds) { + say_num(seconds, SSM_PRONOUNCED); + if (seconds == 1) { + say_file("time/second.wav"); + } else { + say_file("time/seconds.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("time/seconds.wav"); + } + + return SWITCH_STATUS_SUCCESS; + } + + if ((t = atol(tosay)) > 0) { + target = switch_time_make(t, 0); + target_now = switch_micro_time_now(); + } else { + target = switch_micro_time_now(); + target_now = switch_micro_time_now(); + } + + if (tz) { + int check = atoi(tz); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz); + if (check) { + switch_time_exp_tz(&tm, target, check); + switch_time_exp_tz(&tm_now, target_now, check); + } else { + switch_time_exp_tz_name(tz, &tm, target); + switch_time_exp_tz_name(tz, &tm_now, target_now); + } + } else { + switch_time_exp_lt(&tm, target); + switch_time_exp_lt(&tm_now, target_now); + } + + switch (say_args->type) { + case SST_CURRENT_DATE_TIME: + say_date = say_time = 1; + break; + case SST_CURRENT_DATE: + say_date = 1; + break; + case SST_CURRENT_TIME: + say_time = 1; + break; + case SST_SHORT_DATE_TIME: + say_time = 1; + if (tm.tm_year != tm_now.tm_year) { + say_date = 1; + break; + } + if (tm.tm_yday == tm_now.tm_yday) { + say_today = 1; + break; + } + if (tm.tm_yday == tm_now.tm_yday - 1) { + say_yesterday = 1; + break; + } + if (tm.tm_yday >= tm_now.tm_yday - 5) { + say_dow = 1; + break; + } + if (tm.tm_mon != tm_now.tm_mon) { + say_month = say_day = say_dow = 1; + break; + } + + say_month = say_day = say_dow = 1; + + break; + default: + break; + } + + if (say_today) { + say_file("time/today.wav"); + } + if (say_yesterday) { + say_file("time/yesterday.wav"); + } + if (say_dow) { + say_file("time/day-%d.wav", tm.tm_wday); + } + + if (say_date) { + say_year = say_month = say_day = say_dow = 1; + say_today = say_yesterday = 0; + } + + if (say_month) { + say_file("time/mon-%d.wav", tm.tm_mon); + } + if (say_day) { + say_num(tm.tm_mday, SSM_COUNTED); + } + if (say_year) { + say_num(tm.tm_year + 1900, SSM_PRONOUNCED); + } + + if (say_time) { + int32_t hour = tm.tm_hour, pm = 0; + + if (say_date || say_today || say_yesterday || say_dow) { + if (hour == 1) { + say_file("time/at.wav"); + } else { + say_file("time/ats.wav"); + } + } + + if (hour > 12) { + hour -= 12; + pm = 1; + } else if (hour == 12) { + pm = 1; + } else if (hour == 0) { + hour = 12; + pm = 0; + } + + say_num(hour, SSM_PRONOUNCED); + + if (tm.tm_min) { + say_file("currency/and.wav"); + say_num(tm.tm_min, SSM_PRONOUNCED); + } else { + say_file("time/oclock.wav"); + } + + say_file("time/%s.wav", pm ? "p-m" : "a-m"); + } + + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t pt_say_money(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + char sbuf[16] = ""; /* enough for 999,999,999,999.99 (w/o the commas or leading $) */ + char *dollars = NULL; + char *cents = NULL; + + if (strlen(tosay) > 15 || !(tosay = switch_strip_nonnumerics(tosay, sbuf, sizeof(sbuf)))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + + dollars = sbuf; + + if ((cents = strchr(sbuf, '.'))) { + *cents++ = '\0'; + if (strlen(cents) > 2) { + cents[2] = '\0'; + } + } + + /* If positive sign - skip over" */ + if (sbuf[0] == '+') { + dollars++; + } + + /* If negative say "negative" */ + if (sbuf[0] == '-') { + say_file("currency/negative.wav"); + dollars++; + } + + /* Say dollar amount */ + pt_say_general_count(session, dollars, say_args, args); + if (atoi(dollars) == 1) { + say_file("currency/dollar.wav"); + } else { + say_file("currency/dollars.wav"); + } + + /* Say "and" */ + say_file("currency/and.wav"); + + /* Say cents */ + if (cents) { + pt_say_general_count(session, cents, say_args, args); + if (atoi(cents) == 1) { + say_file("currency/cent.wav"); + } else { + say_file("currency/cents.wav"); + } + } else { + say_file("digits/0.wav"); + say_file("currency/cents.wav"); + } + + return SWITCH_STATUS_SUCCESS; +} + + + +static switch_status_t pt_say(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args) +{ + + switch_say_callback_t say_cb = NULL; + + switch (say_args->type) { + case SST_NUMBER: + case SST_ITEMS: + case SST_PERSONS: + case SST_MESSAGES: + say_cb = pt_say_general_count; + break; + case SST_TIME_MEASUREMENT: + case SST_CURRENT_DATE: + case SST_CURRENT_TIME: + case SST_CURRENT_DATE_TIME: + case SST_SHORT_DATE_TIME: + say_cb = pt_say_time; + break; + case SST_IP_ADDRESS: + return switch_ivr_say_ip(session, tosay, pt_say_general_count, say_args, args); + break; + case SST_NAME_SPELLED: + case SST_NAME_PHONETIC: + return switch_ivr_say_spell(session, tosay, say_args, args); + break; + case SST_CURRENCY: + say_cb = pt_say_money; + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown Say type=[%d]\n", say_args->type); + break; + } + + if (say_cb) { + return say_cb(session, tosay, say_args, args); + } + + return SWITCH_STATUS_FALSE; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_say_pt_load) +{ + switch_say_interface_t *say_interface; + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + say_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SAY_INTERFACE); + say_interface->interface_name = "pt"; + say_interface->say_function = pt_say; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/say/mod_say_pt/mod_say_pt.vcproj b/src/mod/say/mod_say_pt/mod_say_pt.vcproj new file mode 100644 index 0000000000..fb5d2dbab9 --- /dev/null +++ b/src/mod/say/mod_say_pt/mod_say_pt.vcproj @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/switch_channel.c b/src/switch_channel.c index ef21e8c8f1..aa7f6699b7 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2382,12 +2382,48 @@ SWITCH_DECLARE(switch_status_t) switch_channel_caller_extension_masquerade(switc return status; } +SWITCH_DECLARE(void) switch_channel_sort_cid(switch_channel_t *channel, switch_bool_t in) +{ + + if (in) { + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(channel, CF_DIALPLAN)) { + switch_channel_set_flag(channel, CF_DIALPLAN); + + switch_mutex_lock(channel->profile_mutex); + if (channel->caller_profile->callee_id_name) { + switch_channel_set_variable(channel, "pre_transfer_caller_id_name", channel->caller_profile->caller_id_name); + channel->caller_profile->caller_id_name = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_name); + } + channel->caller_profile->callee_id_name = SWITCH_BLANK_STRING; + + if (channel->caller_profile->callee_id_number) { + switch_channel_set_variable(channel, "pre_transfer_caller_id_number", channel->caller_profile->caller_id_number); + channel->caller_profile->caller_id_number = switch_core_strdup(channel->caller_profile->pool, channel->caller_profile->callee_id_number); + } + channel->caller_profile->callee_id_number = SWITCH_BLANK_STRING; + switch_mutex_unlock(channel->profile_mutex); + } + + return; + } + + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(channel, CF_DIALPLAN)) { + switch_channel_clear_flag(channel, CF_DIALPLAN); + switch_mutex_lock(channel->profile_mutex); + channel->caller_profile->callee_id_name = SWITCH_BLANK_STRING; + channel->caller_profile->callee_id_number = SWITCH_BLANK_STRING; + switch_mutex_unlock(channel->profile_mutex); + } + +} + + SWITCH_DECLARE(void) switch_channel_set_caller_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension) { switch_assert(channel != NULL); - switch_channel_set_flag(channel, CF_DIALPLAN); - + switch_channel_sort_cid(channel, SWITCH_TRUE); + switch_mutex_lock(channel->profile_mutex); caller_extension->next = channel->caller_profile->caller_extension; channel->caller_profile->caller_extension = caller_extension; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 494871ec8a..cd74c332b7 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1544,21 +1544,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ new_profile->destination_number = switch_core_strdup(new_profile->pool, extension); new_profile->rdnis = switch_core_strdup(new_profile->pool, profile->destination_number); - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - if (profile->callee_id_name) { - switch_channel_set_variable(channel, "pre_transfer_caller_id_name", new_profile->caller_id_name); - new_profile->caller_id_name = switch_core_strdup(new_profile->pool, profile->callee_id_name); - profile->callee_id_name = SWITCH_BLANK_STRING; - } - - if (profile->callee_id_number) { - switch_channel_set_variable(channel, "pre_transfer_caller_id_number", new_profile->caller_id_number); - new_profile->caller_id_number = switch_core_strdup(new_profile->pool, profile->callee_id_number); - profile->callee_id_number = SWITCH_BLANK_STRING; - } - } - - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, NULL); /* If HANGUP_AFTER_BRIDGE is set to 'true', SWITCH_SIGNAL_BRIDGE_VARIABLE diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index aa5ddb9232..2f2dcdbc95 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1052,6 +1052,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t * switch_channel_set_variable(caller_channel, "signal_bridge", "true"); switch_channel_set_variable(peer_channel, "signal_bridge", "true"); + switch_channel_sort_cid(peer_channel, SWITCH_FALSE); + /* fire events that will change the data table from "show channels" */ if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); @@ -1117,6 +1119,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR); switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR); + switch_channel_sort_cid(peer_channel, SWITCH_FALSE); + b_leg->session = peer_session; switch_copy_string(b_leg->b_uuid, switch_core_session_get_uuid(session), sizeof(b_leg->b_uuid)); b_leg->stream_id = stream_id; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index b6ae346a66..87a47e65aa 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2383,24 +2383,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess new_profile->chan_name = SWITCH_BLANK_STRING; new_profile->destination_number = switch_core_strdup(new_profile->pool, chan_data); - if (switch_channel_direction(caller_channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - const char *callee_id_name = new_profile->callee_id_name; - const char *callee_id_number = new_profile->callee_id_number; - - if (zstr(callee_id_number)) { - callee_id_number = caller_caller_profile->destination_number; - } - - if (zstr(callee_id_name)) { - callee_id_name = callee_id_number; - } - - new_profile->caller_id_name = callee_id_name; - new_profile->caller_id_number = callee_id_number; - new_profile->callee_id_name = SWITCH_BLANK_STRING; - new_profile->callee_id_number = SWITCH_BLANK_STRING; - } - if (cid_name_override) { new_profile->caller_id_name = switch_core_strdup(new_profile->pool, cid_name_override); }