Merge remote branch 'fsorig/master'

This commit is contained in:
Moises Silva 2010-10-04 22:07:03 -04:00
commit f6d4714b7f
11 changed files with 553 additions and 58 deletions

View File

@ -16,12 +16,16 @@ freeswitch (1.0.7)
build: VS 2010 - Change to V4 framework, add SWIG v2.0 files to fix release build exceptions(temp fix till we upgrade all SWIG files) (r:812f4309)
build: Windows VS2010 build - remove strange characters (r:ba1546e0/FSBUILD-297)
build: Make bootstrap.sh Bourne shell compatible (r:8dbd62ff/FSBUILD-301)
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
config: Remove 99xx extension numbers to avoid dp conflicts (r:0c9bb174/DP-17)
config: update config example for caller-id-type (r:8f03a7cd)
config: default to 48k since most sound cards can do that (r:170404a4)
config: Create RFC2822_DATE for use in emails. Some clients fail to sort emails properly without a Date: line. (r:a1f19d91)
config: move enum to the bottom of default. (r:4d448c97)
config: Add att_xfer example to default dialplan (r:20ec962a)
config: default example to resolve some issues with SCA in cases where host and ip are mixed causing the phone to be confused. (r:0279261b)
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
@ -78,8 +82,22 @@ freeswitch (1.0.7)
core: Implemented 'Block Fork' and removed possibility for "-nc -nf" potential issue. (r:f26a6972/FSCORE-652)
core: Add console callback for listing loaded/available modules for load/unload/reload commands (r:d68a1218/FSCORE-662)
core: strip trailing and leading whitespace in api execute args and commands (r:ca481842)
core: Fix SQLLEN to prevent queue buffer overrun (r:68d1c32a/FS-2149)
core: add origination_caller_profile to log all attempted calls for a paticular leg (r:977a8ad7)
core: Add attribute "path" to autoload_configs/modules.conf.xml <load> entry. (r:1a75821d)
core: add tone2wav (r:6f2c455f)
core: add speed boost to sql thread (r:ef79535c)
core: reverse the linked list in ivr menus to support accidental feature of multiple entries for the same keys (r:d4a01324)
core: Add time of day string compare function switch_tod_cmp. It usable in XML dialplan with time-of-day. String format is hh:mm:ss you can define a range like this : 09:00-17:00 (Second are not optional) (r:4ab8fa13)
core: Add date time range string compare function switch_fulldate_cmp. It usable in XML dialplan with date-time. String format example : 2009-10-10 14:33:22~2009-11-10 17:32:31. (r:c9fcce08)
core: Add day of week 3 letter initial usage in "wday" field in the dialplan. Example : mon-fri. Using number as before is still supported. Several public switch function are available. (r:59ec8ced)
core: set conditionals to only fire when the mutex can be obtained (r:07ec7867)
core: avoid segfault when sofia tries to update the callee id at the same time as the outbound call is transferred (r:df63657e)
core: make code more automagic to shut up the dude on the list (r:d093a4a4)
core: Fix memory leak if we fail to enqueue new event to EVENT_QUEUE in switch_event.c (r:ef773e07/FS-2148)
lang: Improve French phrase files (FSCONFIG-23)
libdingaling: fix race on shutdown causing crash (FSMOD-47)
libdingaling: Fix crash in new GV interface when exceeding 24 calls (r:be00609a/FS-2171)
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)
@ -93,6 +111,8 @@ freeswitch (1.0.7)
libesl: Fix SEGV when using serialize function without any arguments (r:910729b5/ESL-44)
libesl: fix leak-on-error in esl_connect_timeout() (r:4263d60e)
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)
libopenzap: Add CLI tracing
libs: Merged OpenZAP and FreeTDM into the FreeSWITCH tree.
libs: Add support for TLS on Windows using openssl (r:1abe3b93/MODSOFIA-92)
@ -103,6 +123,7 @@ freeswitch (1.0.7)
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)
libspandsp: Fix Windows build after libspandsp update (r:d70cc852/FSBUILD-293)
libspandsp: Fix for T.30 processing of operator interrupts, to improve compatibility with some machines, which seem to send them when no operator is around. (r:84ee0ae6)
mod_avmd: Initial check in - Advanced Voicemail Detect (r:10c6a30a) (by Eric Des Courtis)
mod_avmd: Add to windows build (r:df4bd935)
mod_callcenter: Initial commit of the mod_callcenter application. This module is in it early state of developpement. You can see documentation on the wiki at : <a href="http://wiki.freeswitch.org/wiki/Mod_callcenter">http://wiki.freeswitch.org/wiki/Mod_callcenter</a> For support/comments, please use <a href="http://jira.freeswitch.org/">http://jira.freeswitch.org/</a> and select the MOD CALLCENTER module. (r:ba09b96d)
@ -116,7 +137,8 @@ freeswitch (1.0.7)
mod_callcenter: You can now allow caller that have hangup before agent answer to call back and resume their previous position. (r:ab2529d4)
mod_callcenter: correct multiple little things following the recent tiers and join back features (r:9b33bd1c)
mod_callcenter: Add more channel variable and event and fix a mem leak (r:2d3d8c8d)
od_callcenter: Make more sence to bridge the caller to the agent. Before, in the xml_cdr you saw it it like the agent initiated the call to the member (r:0be95658)
mod_callcenter: Make more sence to bridge the caller to the agent. Before, in the xml_cdr you saw it it like the agent initiated the call to the member (r:0be95658)
mod_callcenter: Added max-wait-time and max-wait-time-with-no-agent param to a queue. (r:3482f95e)
mod_cidlookup: null xml is bad (r:095815f8)
mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53)
mod_commands: make break uuid_break and add cascade flag
@ -127,6 +149,9 @@ freeswitch (1.0.7)
mod_commands: Fix a segfault if no arguments is provided to limit_hash_usage (r:8ceb2a9b)
mod_commands: fsctl max_session should display int, not float (r:f7e2410e/FSCORE-634)
mod_commands: limit - reset rate and release resource apis Thanks Moy (r:a7c31e6f/FSCORE-637)
mod_commands: Fix user_data returning the first value found instead of the last. Also add support to get variable from the group. (r:402f2391)
mod_commands: Allow cond API to return empty false value (r:c8a897b9)
mod_commands: ***BEHAVIOUR CHANGE*** reloadacl, load <module>, reload <module> will now explicitly call reloadxml (r:42c9df72)
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
@ -139,6 +164,8 @@ freeswitch (1.0.7)
mod_dingaling: make mod_dingaling compat with google's new free phonecalls thing (r:ba0a2a32)
mod_dingaling: make dingaling work with google voice inbound too (r:4ee68141)
mod_dingaling: Fix crash when testing the new gv-dingaling with around 24 concurrent calls (r:73e1ec5e/FSCORE-667)
mod_dingaling: Fix NULL pointer (r:e3eff816/FS-1103)
mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f)
mod_db: fix stack corruption (MODAPP-407)
mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012)
mod_dptools: Make park app not send 183 session progress (r:76932995/FSCORE-567)
@ -153,6 +180,7 @@ freeswitch (1.0.7)
mod_fifo: cancel outbound call if customer hangs up (r:cadb4d94)
mod_fifo: add taking_calls param to fifo member add and config file (r:821488bf)
mod_fifo: add nomedia flag (r:2d30a8c2)
mod_fifo: Fix inconsistency between the fifo queue and the channels (num callers in queue can become "-1") (r:07487114/FS-1659)
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)
mod_freetdm: export and import boost custom data (r:edb2d582)
@ -213,9 +241,14 @@ freeswitch (1.0.7)
mod_lcr: fix dialplan issues with default profile and logging when no caller_profile set (r:00170558)
mod_lcr: assign default profile even if testing is skipped (r:6420099c)
mod_lcr: fix compiler warning on newer gcc (r:bfa414cb)
mod_lcr: don't count twice (r:eaeabc7b/FS-1810)
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_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)
mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165)
mod_managed: add additional support (r:5be58aac)
mod_mp4v: MP4V-ES passthru for washibechi on IRC
mod_nibblebill: free allocated mem at shutdown; free properly if using custom_sql
mod_nibblebill: Add SAF_SUPPORT_NOMEDIA to nibblebill
@ -303,12 +336,28 @@ freeswitch (1.0.7)
mod_sofia: Fix memleak and mwi event not generated on first register (r:04b9b3e2)
mod_sofia: when getting presence with no payload consider it an extension to the expires time in the dialog (r:70331e88)
mod_sofia: don't put blank 'version' attr in dialog-info packets (r:749dc864)
mod_sofia: speed up db action in sofia recover (r:8114b3f1)
mod_sofia: Support display updates for Cisco SIP endpoints (tested on SPA series) (r:ac205288/FS-884)
mod_sofia: dont put an rpid in 183 or 200 if pass-callee-id is false (r:86de47ff)
mod_sofia: improve sofia recover in some nat cases (r:4526ba30)
mod_sofia: edge cases for sofia recover (r:646a5609)
mod_sofia: Correct the order what param and variables are overriding them self in user/group/domain (r:5a6f0f5c)
mod_sofia: include accumulated stats from rtcp into vars (r:d5ff3e04)
mod_sofia: make sure hold-related code is skipped 100% with disable-hold set (r:403bf6af)
mod_sofia: make force-subscription-expires only work on nonzero expire deltas, 0 means unscubscribe (r:b7751868)
mod_sofia: presence tweaks and addition of all-reg-options-ping which is like nat-options-ping only for every registered host (r:04b52156)
mod_sofia: If sip_invite_domain is used lets use it for rpid_domain no matter what because I know best if I set it (r:8726104a)
mod_sofia: add inline lists for tab complete db using ::[a:b syntax (r:445731ee)
mod_sofia: add sofia profile <profile> gwlist up|down to list up or downed profiles for feeding into mod distributor to exclude dead gateways (r:0477cb67)
mod_sofia: add 'sofia global siptrace on' so we don't have to always teach people to enable sip trace on each profile (r:09fa6678)
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)
mod_spandsp: add start_tone_detect/stop_tone_detect app and api commands for tone and cadence detection (r:a6e65147/MODAPP-378)
mod_spandsp: Fix mod_spandsp receive t38 fax error in windows7 (r:fca93f29/MODAPP-443)
mod_spandsp: Moved spandsp to a more recent version. A huge number of little changes occur here, as recently spandsp lost all the $Id$ entries the source files had for the dark old days of CVS (r:f029f7ef)
mod_spandsp: move app flag into 'T38' namespace for the sake of housekeeping (r:0d0b4b43)
mod_spandsp: make t38 terminal mode more reliable (r:83da7bd3)
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)
@ -322,10 +371,14 @@ freeswitch (1.0.7)
mod_voicemail: fix vm msg being deleted when pressing key to forward to email (MODAPP-403)
mod_voicemail: make voicemails use the uuid of the channel who recorded it when applicable (r:98a5a30a)
mod_voicemail: user unable to play or delete voicemail via web API (r:b5205c0b/MODAPP-447)
mod_voicemail: Allow to forward a message or send it via email key during the playback of the recording, not just when the menu is playing. (r:83aeda79)
mod_voicemail: fix vm_inject to a group and change syntax for sending to a whole domain to domain= for clarity sake (r:f30a1cc6)
mod_voicemail: add quotes to vm_cc command generated internally to escape spaces in the caller id name (r:5f012813)
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)
mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62)
mod_xml_rpc: Fix crash if unauthorized XML RPC is attempted (r:9835395c/FS-184)
sofia-sip: fix null derefernce segfault in soa (r:f356c5e6)
sofia-sip: extend timeout for session expires on short timeouts to be 90% of timeout instead of 1/3 to handle devices that do not refresh in time such as polycom (r:a7f48928/SFSIP-212)

View File

@ -364,6 +364,21 @@
<prompt phrase="...files..." filename="ivr-files-.wav"/>
<!-- The following phrases still need to be recorded -->
<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"/>
@ -387,17 +402,37 @@
<prompt phrase="Thank you for calling. If you know your party's extension, please enter it now, or dial nine for a directory." filename="ivr-generic_greeting.wav"/>
<prompt phrase="If this is correct, press 1. If not, press 2." filename="ivr-if_correct_one_if_not_two.wav"/>
<prompt phrase="To repeat this information..." filename="ivr-repeat_this_information.wav"/>
<prompt phrase="No no no!" filename="ivr-nonono.wav"/>
<prompt phrase="No no no!" filename="ivr-no_no_no.wav"/>
<prompt phrase="Do you mean to press that key?" filename="ivr-did_you_mean_to_press_key.wav"/>
<prompt phrase="Seriously. Did you REALLY mean to press that key?" filename="ivr-seriously_mean_to_press_key.wav"/>
<prompt phrase="Oh whatever." filename="ivr-oh_whatever.wav"/>
<prompt phrase="Oh what-EVER." filename="ivr-oh_whatever.wav"/>
<prompt phrase="That's it! One more mistake and I WILL hang up on your ass." filename="ivr-one_more_mistake.wav"/>
<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. Please stay on the line and your call will be answered in the order it was received." filename="ivr-engineers_busy_assisting_other_sales.wav"/>
<prompt phrase="" filename="ivr-.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="This message will self-destruct in 5, 4, 3, 2, 1..." filename="ivr-message_self_destruct.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="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="Barracuda Networks" filename="ivr-barracuda_networks.wav"/>
<prompt phrase="CudaTel Communication Server" filename="ivr-cudatel_communication_server.wav"/>
<prompt phrase="Brian West" filename="misc-Brian_West.wav"/>
<prompt phrase="Anthony Minessale" filename="misc-Anthony_Minessale.wav"/>
<prompt phrase="Michael Jerris" filename="misc-Michael_Jerris.wav"/>
<prompt phrase="Raymond Chandler" filename="misc-Raymond_Chandler.wav"/>
<prompt phrase="Michael Collins" filename="misc-Michael_Collins.wav"/>
<prompt phrase="Mark Mann" filename="misc-Mark_Mann.wav"/>
<prompt phrase="William King" filename="misc-William_King.wav"/>
<prompt phrase="Rudy Fleminger" filename="misc-Rudy_Fleminger.wav"/>
<prompt phrase="Andrew Thompson" filename="misc-Andrew_Thompson.wav"/>
<prompt phrase="Graham Saathoff" filename="misc-Graham_Saathoff.wav"/>
<prompt phrase="Nicholaus Belluni" filename="misc-Nicholaus_Belluni.wav"/>
<prompt phrase="Sean Heiney" filename="misc-Sean_Heiney.wav">
</ivr>
<misc>
<prompt phrase="This call has been secured" filename="call_secured.wav"/>

View File

@ -842,6 +842,28 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sound_test(switch_core_session_t *ses
SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname);
SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid);
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
switch_memory_pool_t *pool,
uint32_t digit_timeout, uint32_t input_timeout);
SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine);
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
const char *digits,
int32_t key,
switch_ivr_dmachine_callback_t callback,
void *user_data);
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match);
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear(switch_ivr_dmachine_t *dmachine);
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p);
SWITCH_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(switch_ivr_dmachine_t *dmachine);
/** @} */
SWITCH_END_EXTERN_C

View File

@ -833,6 +833,7 @@ typedef enum {
SWITCH_STATUS_NOUNLOAD,
SWITCH_STATUS_IGNORE,
SWITCH_STATUS_TOO_SMALL,
SWITCH_STATUS_FOUND,
SWITCH_STATUS_NOT_INITALIZED
} switch_status_t;
@ -1684,12 +1685,27 @@ typedef switch_status_t (*switch_input_callback_function_t) (switch_core_session
switch_input_type_t input_type, void *buf, unsigned int buflen);
typedef switch_status_t (*switch_read_frame_callback_function_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
typedef struct switch_say_interface switch_say_interface_t;
struct switch_ivr_dmachine;
typedef struct switch_ivr_dmachine switch_ivr_dmachine_t;
struct switch_ivr_dmachine_match {
switch_ivr_dmachine_t *dmachine;
const char *match_digits;
int32_t match_key;
void *user_data;
};
typedef struct switch_ivr_dmachine_match switch_ivr_dmachine_match_t;
typedef switch_status_t (*switch_ivr_dmachine_callback_t) (switch_ivr_dmachine_match_t *match);
typedef struct {
switch_input_callback_function_t input_callback;
void *buf;
uint32_t buflen;
switch_read_frame_callback_function_t read_frame_callback;
void *user_data;
switch_ivr_dmachine_t *dmachine;
} switch_input_args_t;
typedef struct {

View File

@ -1330,6 +1330,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
switch_mutex_unlock(omember->audio_out_mutex);
if (!ok) {
switch_mutex_unlock(conference->mutex);
goto end;
}
}
@ -1913,6 +1914,8 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
uint32_t hangover = 40, hangunder = 15, hangover_hits = 0, hangunder_hits = 0, energy_level = 0, diff_level = 400;
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_t *session = member->session;
int check_floor_change;
switch_assert(member != NULL);
switch_clear_flag_locked(member, MFLAG_TALKING);
@ -1925,6 +1928,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
and mux it with any audio from other channels. */
while (switch_test_flag(member, MFLAG_RUNNING) && switch_channel_ready(channel)) {
check_floor_change = 0;
if (switch_channel_ready(channel) && switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
switch_yield(100000);
@ -2082,25 +2086,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
}
if (diff >= diff_level || ++hangunder_hits >= hangunder) {
switch_mutex_lock(member->conference->member_mutex);
if ((!member->conference->floor_holder ||
!switch_test_flag(member->conference->floor_holder, MFLAG_TALKING) ||
((member->score_iir > SCORE_IIR_SPEAKING_MAX) && (member->conference->floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN))) &&
(!switch_test_flag(member->conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
if (test_eflag(member->conference, EFLAG_FLOOR_CHANGE) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_member_data(member, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "floor-change");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d",
member->conference->floor_holder ? member->conference->floor_holder->id : 0);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", member->conference->floor_holder ? member->id : 0);
switch_event_fire(&event);
}
member->conference->floor_holder = member;
}
switch_mutex_unlock(member->conference->member_mutex);
check_floor_change = 1;
hangover_hits = hangunder_hits = 0;
member->last_talking = switch_epoch_time_now(NULL);
@ -2190,6 +2176,28 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
do_continue:
switch_mutex_unlock(member->read_mutex);
if (check_floor_change) {
switch_mutex_lock(member->conference->member_mutex);
if ((!member->conference->floor_holder ||
!switch_test_flag(member->conference->floor_holder, MFLAG_TALKING) ||
((member->score_iir > SCORE_IIR_SPEAKING_MAX) && (member->conference->floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN))) &&
(!switch_test_flag(member->conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
if (test_eflag(member->conference, EFLAG_FLOOR_CHANGE) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_member_data(member, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "floor-change");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d",
member->conference->floor_holder ? member->conference->floor_holder->id : 0);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", member->conference->floor_holder ? member->id : 0);
switch_event_fire(&event);
}
member->conference->floor_holder = member;
}
switch_mutex_unlock(member->conference->member_mutex);
}
}

View File

@ -507,19 +507,19 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session
args.buflen = sizeof(buf);
if (switch_ivr_play_file(session, NULL, cd->list[cd->index], &args) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
return SWITCH_STATUS_BREAK;
}
if (match_key(caller_exit_key, *buf)) {
cd->abort = 1;
return SWITCH_STATUS_FALSE;
return SWITCH_STATUS_BREAK;
}
cd->next = switch_epoch_time_now(NULL) + cd->freq;
cd->index++;
}
} else if (cd->orbit_timeout && switch_epoch_time_now(NULL) >= cd->orbit_timeout) {
cd->do_orbit = 1;
return SWITCH_STATUS_FALSE;
return SWITCH_STATUS_BREAK;
}
return SWITCH_STATUS_SUCCESS;
@ -540,7 +540,7 @@ static switch_status_t consumer_read_frame_callback(switch_core_session_t *sessi
}
if (total) {
return SWITCH_STATUS_FALSE;
return SWITCH_STATUS_BREAK;
}
return SWITCH_STATUS_SUCCESS;

View File

@ -199,6 +199,8 @@ static int sangoma_create_rtp_port(void *usr_priv, uint32_t host_ip, uint32_t *p
static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_req_leg, sngtc_codec_reply_leg_t* codec_reply_leg, void **rtp_fd)
{
switch_status_t status;
switch_memory_pool_t *sesspool = NULL;
switch_rtp_t *rtp_session = NULL;
char codec_ip[255];
switch_rtp_flag_t flags = 0;
@ -208,6 +210,18 @@ static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_r
char local_ip[255];
switch_port_t rtp_port;
struct sangoma_transcoding_session *sess = usr_priv;
/*
* We *MUST* use a new pool
* Do not use the session pool since the session may go away while the RTP socket should linger around
* until sangoma_transcode decides to kill it (possibly because the same RTP session is used for a different call)
* also do not use the module pool otherwise memory would keep growing because switch_rtp_destroy does not
* free the memory used (is assumed it'll be freed when the pool is destroyed)
*/
status = switch_core_new_memory_pool(&sesspool);
if (status != SWITCH_STATUS_SUCCESS) {
return -1;
}
rtp_port = (switch_port_t)(long)*rtp_fd;
@ -222,20 +236,20 @@ static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_r
local_ip, rtp_port, codec_ip, codec_reply_leg->codec_udp_port, iana,
codec_req_leg->ms*1000, sess->sessid);
/* create the RTP socket, dont use the session pool since the session may go away while the RTP socket should linger around
* until sangoma_transcode decides to kill it (possibly because the same RTP session is used for a different call) */
/* create the RTP socket */
rtp_session = switch_rtp_new(local_ip, rtp_port,
codec_ip, codec_reply_leg->codec_udp_port,
iana,
sess->impl->samples_per_packet,
codec_req_leg->ms * 1000, /* microseconds per packet */
flags, NULL, &err, g_pool);
flags, NULL, &err, sesspool);
if (!rtp_session) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create switch rtp session: %s\n", err);
switch_core_destroy_memory_pool(&sesspool);
return -1;
}
switch_rtp_set_private(rtp_session, sesspool);
*rtp_fd = rtp_session;
return 0;
@ -243,8 +257,11 @@ static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_r
static int sangoma_destroy_rtp(void *usr_priv, void *fd)
{
switch_memory_pool_t *sesspool;
switch_rtp_t *rtp = fd;
sesspool = switch_rtp_get_private(rtp);
switch_rtp_destroy(&rtp);
switch_core_destroy_memory_pool(&sesspool);
return 0;
}
@ -406,6 +423,7 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec
sess->encoder.tx++;
/* do the reading */
memset(&encoded_frame, 0, sizeof(encoded_frame));
for ( ; ; ) {
sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK);
if (sres == SWITCH_STATUS_GENERR) {
@ -525,6 +543,7 @@ static switch_status_t switch_sangoma_decode(switch_codec_t *codec, /* codec ses
sess->decoder.tx++;
/* do the reading */
memset(&ulaw_frame, 0, sizeof(ulaw_frame));
for ( ; ; ) {
sres = switch_rtp_zerocopy_read_frame(sess->decoder.rxrtp, &ulaw_frame, SWITCH_IO_FLAG_NOBLOCK);
if (sres == SWITCH_STATUS_GENERR) {

View File

@ -571,22 +571,22 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
switch_safe_free(sql);
sql = switch_mprintf("select sip_registrations.sip_user, sip_registrations.orig_server_host, sip_registrations.status, "
sql = switch_mprintf("select sip_registrations.sip_user, sip_registrations.orig_hostname, sip_registrations.status, "
"sip_registrations.rpid,'', sip_dialogs.uuid, sip_dialogs.state, sip_dialogs.direction, "
"sip_dialogs.sip_to_user, sip_dialogs.sip_to_host, sip_presence.status,sip_presence.rpid,sip_presence.open_closed,"
"'%q','%q' "
"from sip_registrations left join sip_dialogs on "
"(sip_dialogs.sip_from_user = sip_registrations.sip_user "
"and (sip_dialogs.sip_from_host = sip_registrations.orig_server_host or "
"and (sip_dialogs.sip_from_host = sip_registrations.orig_hostname or "
"sip_dialogs.sip_from_host = sip_registrations.sip_host) ) "
"left join sip_presence on "
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and "
"(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_hostname=sip_presence.sip_host and "
"sip_registrations.profile_name=sip_presence.profile_name) "
"where sip_registrations.sip_user='%q' and "
"(sip_registrations.orig_server_host='%q' or sip_registrations.sip_host='%q' "
"(sip_registrations.orig_hostname='%q' or sip_registrations.sip_host='%q' "
"or sip_registrations.presence_hosts like '%%%q%%')",
dh.status, dh.rpid, probe_euser, probe_host, probe_host, probe_host);
switch_assert(sql);

View File

@ -224,7 +224,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
switch_ivr_parse_all_events(session);
if (args && (args->input_callback || args->buf || args->buflen)) {
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
switch_dtmf_t dtmf;
/*
@ -237,7 +237,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
break;
}
switch_channel_dequeue_dtmf(channel, &dtmf);
if (args->input_callback) {
if (args->dmachine) {
char ds[2] = {dtmf.digit, '\0'};
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
} else if (args->input_callback) {
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
} else {
switch_copy_string((char *) args->buf, (void *) &dtmf, args->buflen);
@ -947,8 +953,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_collect_digits_callback(switch_core_s
break;
}
if (args && args->dmachine) {
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
}
if (read_frame && args && (args->read_frame_callback)) {
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
break;
}
}

View File

@ -35,6 +35,281 @@
#include <speex/speex_preprocess.h>
#include <speex/speex_echo.h>
struct switch_ivr_dmachine_binding {
char *digits;
int32_t key;
switch_ivr_dmachine_callback_t callback;
switch_byte_t is_regex;
void *user_data;
struct switch_ivr_dmachine_binding *next;
};
typedef struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t;
#define DM_MAX_DIGIT_LEN 512
struct switch_ivr_dmachine {
switch_memory_pool_t *pool;
switch_byte_t my_pool;
uint32_t digit_timeout_ms;
uint32_t input_timeout_ms;
switch_ivr_dmachine_binding_t *binding_list;
switch_ivr_dmachine_binding_t *tail;
switch_ivr_dmachine_binding_t *last_matching_binding;
switch_ivr_dmachine_match_t match;
char digits[DM_MAX_DIGIT_LEN];
char last_matching_digits[DM_MAX_DIGIT_LEN];
uint32_t cur_digit_len;
uint32_t max_digit_len;
switch_time_t last_digit_time;
switch_byte_t is_match;
};
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
switch_memory_pool_t *pool,
uint32_t digit_timeout_ms, uint32_t input_timeout_ms)
{
switch_byte_t my_pool = !!pool;
switch_ivr_dmachine_t *dmachine;
if (digit_timeout_ms < 1 || input_timeout_ms < 1) return SWITCH_STATUS_FALSE;
if (!pool) {
switch_core_new_memory_pool(&pool);
}
dmachine = switch_core_alloc(pool, sizeof(*dmachine));
dmachine->pool = pool;
dmachine->my_pool = my_pool;
dmachine->digit_timeout_ms = digit_timeout_ms;
dmachine->input_timeout_ms = input_timeout_ms;
dmachine->match.dmachine = dmachine;
*dmachine_p = dmachine;
return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine)
{
switch_memory_pool_t *pool;
if (!(dmachine && *dmachine)) return;
pool = (*dmachine)->pool;
if ((*dmachine)->my_pool) {
switch_core_destroy_memory_pool(&pool);
}
}
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
const char *digits,
int32_t key,
switch_ivr_dmachine_callback_t callback,
void *user_data)
{
switch_ivr_dmachine_binding_t *binding;
switch_size_t len;
if (strlen(digits) > DM_MAX_DIGIT_LEN -1) {
return SWITCH_STATUS_FALSE;
}
binding = switch_core_alloc(dmachine->pool, sizeof(*binding));
if (*digits == '~') {
binding->is_regex = 1;
digits++;
}
binding->key = key;
binding->digits = switch_core_strdup(dmachine->pool, digits);
binding->callback = callback;
binding->user_data = user_data;
if (dmachine->tail) {
dmachine->tail->next = binding;
} else {
dmachine->binding_list = binding;
}
dmachine->tail = binding;
len = strlen(digits);
if (binding->is_regex && dmachine->max_digit_len != DM_MAX_DIGIT_LEN -1) {
dmachine->max_digit_len = DM_MAX_DIGIT_LEN -1;
} else if (len > dmachine->max_digit_len) {
dmachine->max_digit_len = (uint32_t) len;
}
if (binding->is_regex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "binding regex: %s key: %.4d callback: %p data: %p\n",
digits, key, (void *)(intptr_t) callback, user_data);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "binding digits: %4s key: %.4d callback: %p data: %p\n",
digits, key, (void *)(intptr_t) callback, user_data);
}
return SWITCH_STATUS_SUCCESS;
}
typedef enum {
DM_MATCH_NONE,
DM_MATCH_EXACT,
DM_MATCH_PARTIAL,
DM_MATCH_BOTH
} dm_match_t;
static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachine, switch_bool_t is_timeout)
{
dm_match_t best = DM_MATCH_NONE;
switch_ivr_dmachine_binding_t *bp, *exact_bp = NULL;
int exact_count = 0, partial_count = 0, both_count = 0;
if (!dmachine->cur_digit_len) goto end;
for(bp = dmachine->binding_list; bp; bp = bp->next) {
if (bp->is_regex) {
switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
if (r_status == SWITCH_STATUS_SUCCESS) {
if (is_timeout) {
best = DM_MATCH_EXACT;
exact_count++;
exact_bp = bp;
break;
}
best = DM_MATCH_PARTIAL;
partial_count++;
continue;
}
} else {
if (!exact_bp && !strcmp(bp->digits, dmachine->digits)) {
exact_bp = bp;
best = DM_MATCH_EXACT;
exact_count++;
continue;
}
if (!strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits))) {
if (best == DM_MATCH_EXACT) {
if (is_timeout) {
best = DM_MATCH_EXACT;
exact_count++;
exact_bp = bp;
} else {
best = DM_MATCH_BOTH;
both_count++;
}
} else {
best = DM_MATCH_PARTIAL;
partial_count++;
}
break;
}
}
}
end:
if (!both_count && exact_bp) {
dmachine->last_matching_binding = exact_bp;
switch_set_string(dmachine->last_matching_digits, dmachine->digits);
best = DM_MATCH_EXACT;
}
return best;
}
static switch_bool_t switch_ivr_dmachine_check_timeout(switch_ivr_dmachine_t *dmachine)
{
switch_time_t now = switch_time_now();
uint32_t timeout = dmachine->cur_digit_len ? dmachine->digit_timeout_ms : dmachine->input_timeout_ms;
if ((uint32_t)((now - dmachine->last_digit_time) / 1000) > timeout) {
return SWITCH_TRUE;
}
return SWITCH_FALSE;
}
SWITCH_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(switch_ivr_dmachine_t *dmachine)
{
if (dmachine->is_match) {
dmachine->is_match = 0;
return &dmachine->match;
}
return NULL;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
{
switch_bool_t is_timeout = switch_ivr_dmachine_check_timeout(dmachine);
dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout);
switch_status_t r;
if (!dmachine->last_digit_time) {
r = SWITCH_STATUS_SUCCESS;
} else if (dmachine->cur_digit_len > dmachine->max_digit_len) {
r = SWITCH_STATUS_FALSE;
} else if (is_match == DM_MATCH_EXACT || (is_match == DM_MATCH_BOTH && is_timeout)) {
r = SWITCH_STATUS_FOUND;
dmachine->match.match_digits = dmachine->last_matching_digits;
dmachine->match.match_key = dmachine->last_matching_binding->key;
dmachine->match.user_data = dmachine->last_matching_binding->user_data;
if (dmachine->last_matching_binding->callback) {
dmachine->last_matching_binding->callback(&dmachine->match);
}
if (match_p) {
*match_p = &dmachine->match;
}
dmachine->is_match = 1;
} else if (is_timeout) {
r = SWITCH_STATUS_TIMEOUT;
} else if (dmachine->cur_digit_len == dmachine->max_digit_len) {
r = SWITCH_STATUS_NOTFOUND;
} else {
r = SWITCH_STATUS_SUCCESS;
}
if (r != SWITCH_STATUS_SUCCESS) {
switch_ivr_dmachine_clear(dmachine);
}
return r;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
{
if (strlen(digits) + strlen(dmachine->digits) > dmachine->max_digit_len) {
return SWITCH_STATUS_FALSE;
}
strncat(dmachine->digits, digits, dmachine->max_digit_len);
dmachine->cur_digit_len = strlen(dmachine->digits);
dmachine->last_digit_time = switch_time_now();
return switch_ivr_dmachine_ping(dmachine, match);
}
SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear(switch_ivr_dmachine_t *dmachine)
{
memset(dmachine->digits, 0, sizeof(dmachine->digits));
dmachine->cur_digit_len = 0;
dmachine->last_digit_time = 0;
return SWITCH_STATUS_SUCCESS;
}
#ifdef SWITCH_VIDEO_IN_THREADS
struct echo_helper {
switch_core_session_t *session;
@ -2528,7 +2803,7 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj
if (status == SWITCH_STATUS_SUCCESS && switch_true(switch_channel_get_variable(channel, "asr_intercept_dtmf"))) {
const char *p;
if ((p = switch_stristr("<input>", xmlstr))) {
p += 7;
}

View File

@ -493,7 +493,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
}
if ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p)) {
if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p))) {
file_flags |= SWITCH_FILE_WRITE_APPEND;
}
@ -613,18 +613,24 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
break;
}
if (args && (args->input_callback || args->buf || args->buflen)) {
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
/*
dtmf handler function you can hook up to be executed when a digit is dialed during playback
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
*/
if (switch_channel_has_dtmf(channel)) {
if (!args->input_callback && !args->buf) {
if (!args->input_callback && !args->buf && !args->dmachine) {
status = SWITCH_STATUS_BREAK;
break;
}
switch_channel_dequeue_dtmf(channel, &dtmf);
if (args->input_callback) {
if (args->dmachine) {
char ds[2] = {dtmf.digit, '\0'};
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
} else if (args->input_callback) {
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
} else {
*((char *) args->buf) = dtmf.digit;
@ -651,8 +657,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
break;
}
if (args && args->dmachine) {
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
}
if (args && (args->read_frame_callback)) {
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
break;
}
}
@ -810,16 +822,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
break;
}
if (args && args->dmachine) {
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
}
if (args && (args->read_frame_callback)) {
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
break;
}
}
switch_ivr_parse_all_events(session);
if (args && (args->input_callback || args->buf || args->buflen)) {
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
/*
dtmf handler function you can hook up to be executed when a digit is dialed during gentones
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
@ -831,7 +848,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
break;
}
switch_channel_dequeue_dtmf(channel, &dtmf);
if (args->input_callback) {
if (args->dmachine) {
char ds[2] = {dtmf.digit, '\0'};
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
} else if (args->input_callback) {
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
} else {
*((char *) args->buf) = dtmf.digit;
@ -841,7 +864,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi
if (args->input_callback) {
switch_event_t *event;
if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
switch_event_destroy(&event);
@ -1224,7 +1247,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
switch_ivr_parse_all_events(session);
if (args && (args->input_callback || args->buf || args->buflen)) {
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
/*
dtmf handler function you can hook up to be executed when a digit is dialed during playback
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
@ -1236,7 +1259,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
break;
}
switch_channel_dequeue_dtmf(channel, &dtmf);
if (args->input_callback) {
if (args->dmachine) {
char ds[2] = {dtmf.digit, '\0'};
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
} else if (args->input_callback) {
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
} else {
*((char *) args->buf) = dtmf.digit;
@ -1405,10 +1434,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
break;
}
if (args && args->dmachine) {
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
}
if (args && (args->read_frame_callback)) {
int ok = 1;
switch_set_flag(fh, SWITCH_FILE_CALLBACK);
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
ok = 0;
}
switch_clear_flag(fh, SWITCH_FILE_CALLBACK);
@ -1919,7 +1954,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
switch_event_destroy(&event);
}
if (args && (args->input_callback || args->buf || args->buflen)) {
if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) {
/* dtmf handler function you can hook up to be executed when a digit is dialed during playback
* if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
*/
@ -1933,7 +1968,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
status = SWITCH_STATUS_BREAK;
} else {
switch_channel_dequeue_dtmf(channel, &dtmf);
if (args->input_callback) {
if (args->dmachine) {
char ds[2] = {dtmf.digit, '\0'};
if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
break;
}
} else if (args->input_callback) {
status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
} else {
*((char *) args->buf) = dtmf.digit;
@ -1972,9 +2013,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
break;
}
if (args && args->dmachine) {
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
goto done;
}
}
if (args && (args->read_frame_callback)) {
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
break;
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
goto done;
}
}
}
@ -2038,15 +2085,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
break;
}
if (args && args->dmachine) {
if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
goto done;
}
}
if (args && (args->read_frame_callback)) {
if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
break;
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
goto done;
}
}
}
}
done:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done speaking text\n");
flags = 0;
switch_core_speech_flush_tts(sh);