[svn-commits] rmudgett: branch 1.8 r375964 - in /branches/1.8: ./ include/asterisk/ main/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Nov 6 12:18:37 CST 2012
Author: rmudgett
Date: Tue Nov 6 12:18:32 2012
New Revision: 375964
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375964
Log:
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/
Modified:
branches/1.8/.cleancount
branches/1.8/include/asterisk/channel.h
branches/1.8/include/asterisk/features.h
branches/1.8/main/channel.c
branches/1.8/main/features.c
Modified: branches/1.8/.cleancount
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/.cleancount?view=diff&rev=375964&r1=375963&r2=375964
==============================================================================
--- branches/1.8/.cleancount (original)
+++ branches/1.8/.cleancount Tue Nov 6 12:18:32 2012
@@ -1,3 +1,1 @@
-39
-
-
+40
Modified: branches/1.8/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/channel.h?view=diff&rev=375964&r1=375963&r2=375964
==============================================================================
--- branches/1.8/include/asterisk/channel.h (original)
+++ branches/1.8/include/asterisk/channel.h Tue Nov 6 12:18:32 2012
@@ -870,6 +870,8 @@
char macrocontext[AST_MAX_CONTEXT]; /*!< Macro: Current non-macro context. See app_macro.c */
char macroexten[AST_MAX_EXTENSION]; /*!< Macro: Current non-macro extension. See app_macro.c */
char emulate_dtmf_digit; /*!< Digit being emulated */
+ char sending_dtmf_digit; /*!< Digit this channel is currently sending out. (zero if not sending) */
+ struct timeval sending_dtmf_tv; /*!< The time this channel started sending the current digit. (Invalid if sending_dtmf_digit is zero.) */
};
/*! \brief ast_channel_tech Properties */
Modified: branches/1.8/include/asterisk/features.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/include/asterisk/features.h?view=diff&rev=375964&r1=375963&r2=375964
==============================================================================
--- branches/1.8/include/asterisk/features.h (original)
+++ branches/1.8/include/asterisk/features.h Tue Nov 6 12:18:32 2012
@@ -169,6 +169,18 @@
/*! \brief Determine system call pickup extension */
const char *ast_pickup_ext(void);
+/*!
+ * \brief Simulate a DTMF end on a broken bridge channel.
+ *
+ * \param chan Channel sending DTMF that has not ended.
+ * \param digit DTMF digit to stop.
+ * \param start DTMF digit start time.
+ * \param why Reason bridge broken.
+ *
+ * \return Nothing
+ */
+void ast_bridge_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why);
+
/*! \brief Bridge a call, optionally allowing redirection */
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);
Modified: branches/1.8/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/channel.c?view=diff&rev=375964&r1=375963&r2=375964
==============================================================================
--- branches/1.8/main/channel.c (original)
+++ branches/1.8/main/channel.c Tue Nov 6 12:18:32 2012
@@ -71,6 +71,7 @@
#include "asterisk/stringfields.h"
#include "asterisk/global_datastores.h"
#include "asterisk/data.h"
+#include "asterisk/features.h"
#ifdef HAVE_EPOLL
#include <sys/epoll.h>
@@ -4665,6 +4666,11 @@
if (!chan->tech->send_digit_begin)
return 0;
+ ast_channel_lock(chan);
+ chan->sending_dtmf_digit = digit;
+ chan->sending_dtmf_tv = ast_tvnow();
+ ast_channel_unlock(chan);
+
if (!chan->tech->send_digit_begin(chan, digit))
return 0;
@@ -4687,6 +4693,12 @@
int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration)
{
int res = -1;
+
+ ast_channel_lock(chan);
+ if (chan->sending_dtmf_digit == digit) {
+ chan->sending_dtmf_digit = 0;
+ }
+ ast_channel_unlock(chan);
if (chan->tech->send_digit_end)
res = chan->tech->send_digit_end(chan, digit, duration);
@@ -6495,6 +6507,8 @@
char orig[AST_CHANNEL_NAME];
char masqn[AST_CHANNEL_NAME];
char zombn[AST_CHANNEL_NAME];
+ char clone_sending_dtmf_digit;
+ struct timeval clone_sending_dtmf_tv;
/* XXX This operation is a bit odd. We're essentially putting the guts of
* the clone channel into the original channel. Start by killing off the
@@ -6604,6 +6618,10 @@
free_translation(clonechan);
free_translation(original);
+ /* Save the current DTMF digit being sent if any. */
+ clone_sending_dtmf_digit = clonechan->sending_dtmf_digit;
+ clone_sending_dtmf_tv = clonechan->sending_dtmf_tv;
+
/* Save the original name */
ast_copy_string(orig, original->name, sizeof(orig));
/* Save the new name */
@@ -6847,6 +6865,15 @@
}
ast_channel_unlock(clonechan);
+
+ if (clone_sending_dtmf_digit) {
+ /*
+ * The clonechan was sending a DTMF digit that was not completed
+ * before the masquerade.
+ */
+ ast_bridge_end_dtmf(original, clone_sending_dtmf_digit, clone_sending_dtmf_tv,
+ "masquerade");
+ }
/*
* If an indication is currently playing, maintain it on the
Modified: branches/1.8/main/features.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/features.c?view=diff&rev=375964&r1=375963&r2=375964
==============================================================================
--- branches/1.8/main/features.c (original)
+++ branches/1.8/main/features.c Tue Nov 6 12:18:32 2012
@@ -3896,6 +3896,24 @@
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(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, chan->name, why, duration);
+}
+
/*!
* \brief bridge the call and set CDR
*
@@ -4342,6 +4360,15 @@
ast_cel_report_event(chan, AST_CEL_BRIDGE_END, NULL, NULL, peer);
before_you_go:
+ if (chan->sending_dtmf_digit) {
+ ast_bridge_end_dtmf(chan, chan->sending_dtmf_digit, chan->sending_dtmf_tv,
+ "bridge end");
+ }
+ if (peer->sending_dtmf_digit) {
+ ast_bridge_end_dtmf(peer, peer->sending_dtmf_digit, peer->sending_dtmf_tv,
+ "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);
More information about the svn-commits
mailing list