summaryrefslogtreecommitdiff
path: root/main/features.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-11-06 19:05:11 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-11-06 19:05:11 +0000
commit6ad0126425993bd9c9c73b0c05a52984cbcadc5d (patch)
treef070df191a27b220f3097e18ea17a9870ea666b6 /main/features.c
parent82dc21e0e1813b3f24099ad0c90918d95b39ff9d (diff)
Fix stuck DTMF when bridge is broken.
When a bridge is broken by an AMI Redirect action or the ChannelRedirect application, an in progress DTMF digit could be stuck sending forever. * Made simulate a DTMF end event when a bridge is broken and a DTMF digit was in progress. (closes issue ASTERISK-20492) Reported by: Jeremiah Gowdy Patches: bridge_end_dtmf-v3.patch.txt (license #6358) patch uploaded by Jeremiah Gowdy Modified to jira_asterisk_20492_v1.8.patch jira_asterisk_20492_v1.8.patch (license #5621) patch uploaded by rmudgett Tested by: rmudgett Review: https://reviewboard.asterisk.org/r/2169/ ........ Merged revisions 375964 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 375965 from http://svn.asterisk.org/svn/asterisk/branches/10 ........ Merged revisions 375966 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@375967 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/features.c')
-rw-r--r--main/features.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/main/features.c b/main/features.c
index e9f84eae1..847b29ee6 100644
--- a/main/features.c
+++ b/main/features.c
@@ -4249,6 +4249,24 @@ static void clear_dialed_interfaces(struct ast_channel *chan)
ast_channel_unlock(chan);
}
+void ast_bridge_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why)
+{
+ int dead;
+ long duration;
+
+ ast_channel_lock(chan);
+ dead = ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE) || ast_check_hangup(chan);
+ ast_channel_unlock(chan);
+ if (dead) {
+ return;
+ }
+
+ duration = ast_tvdiff_ms(ast_tvnow(), start);
+ ast_senddigit_end(chan, digit, duration);
+ ast_log(LOG_DTMF, "DTMF end '%c' simulated on %s due to %s, duration %ld ms\n",
+ digit, ast_channel_name(chan), why, duration);
+}
+
/*!
* \brief bridge the call and set CDR
*
@@ -4698,6 +4716,15 @@ int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct a
ast_cel_report_event(chan, AST_CEL_BRIDGE_END, NULL, NULL, peer);
before_you_go:
+ if (ast_channel_sending_dtmf_digit(chan)) {
+ ast_bridge_end_dtmf(chan, ast_channel_sending_dtmf_digit(chan),
+ ast_channel_sending_dtmf_tv(chan), "bridge end");
+ }
+ if (ast_channel_sending_dtmf_digit(peer)) {
+ ast_bridge_end_dtmf(peer, ast_channel_sending_dtmf_digit(peer),
+ ast_channel_sending_dtmf_tv(peer), "bridge end");
+ }
+
/* Just in case something weird happened and we didn't clean up the silence generator... */
if (silgen) {
ast_channel_stop_silence_generator(who == chan ? peer : chan, silgen);