[svn-commits] rmudgett: branch rmudgett/bridge_phase r396519 - in /team/rmudgett/bridge_pha...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Fri Aug 9 20:20:37 CDT 2013
Author: rmudgett
Date: Fri Aug 9 20:20:35 2013
New Revision: 396519
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=396519
Log:
Handle channel owing events to a bridge when it moves to another bridge or leaves the bridging system.
Modified:
team/rmudgett/bridge_phase/include/asterisk/bridge_channel.h
team/rmudgett/bridge_phase/include/asterisk/bridge_channel_internal.h
team/rmudgett/bridge_phase/main/bridge.c
team/rmudgett/bridge_phase/main/bridge_channel.c
team/rmudgett/bridge_phase/main/channel.c
Modified: team/rmudgett/bridge_phase/include/asterisk/bridge_channel.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridge_channel.h?view=diff&rev=396519&r1=396518&r2=396519
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridge_channel.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridge_channel.h Fri Aug 9 20:20:35 2013
@@ -155,6 +155,13 @@
* \note Needs to be atomically settable.
*/
enum bridge_channel_thread_state activity;
+ /*! Owed events to the bridge. */
+ struct {
+ /*! Time started sending the current digit. (Invalid if owed.dtmf_digit is zero.) */
+ struct timeval dtmf_tv;
+ /*! Digit currently sending into the bridge. (zero if not sending) */
+ char dtmf_digit;
+ } owed;
};
/*!
Modified: team/rmudgett/bridge_phase/include/asterisk/bridge_channel_internal.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridge_channel_internal.h?view=diff&rev=396519&r1=396518&r2=396519
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridge_channel_internal.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridge_channel_internal.h Fri Aug 9 20:20:35 2013
@@ -86,6 +86,20 @@
/*!
* \internal
+ * \brief Clear owed events by the channel to the original bridge.
+ * \since 12.0.0
+ *
+ * \param orig_bridge Original bridge the channel was in before leaving.
+ * \param bridge_channel Channel that owes events to the original bridge.
+ *
+ * \note On entry, the orig_bridge is already locked.
+ *
+ * \return Nothing
+ */
+void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \internal
* \brief Push the bridge channel into its specified bridge.
* \since 12.0.0
*
Modified: team/rmudgett/bridge_phase/main/bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/bridge.c?view=diff&rev=396519&r1=396518&r2=396519
==============================================================================
--- team/rmudgett/bridge_phase/main/bridge.c (original)
+++ team/rmudgett/bridge_phase/main/bridge.c Fri Aug 9 20:20:35 2013
@@ -1993,11 +1993,15 @@
if (bridge_channel_internal_push(bridge_channel)) {
ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE);
+ bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
}
} else {
ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE);
+ bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
}
res = -1;
+ } else {
+ bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
}
bridge_reconfigured(dst_bridge, !optimized);
Modified: team/rmudgett/bridge_phase/main/bridge_channel.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/bridge_channel.c?view=diff&rev=396519&r1=396518&r2=396519
==============================================================================
--- team/rmudgett/bridge_phase/main/bridge_channel.c (original)
+++ team/rmudgett/bridge_phase/main/bridge_channel.c Fri Aug 9 20:20:35 2013
@@ -317,6 +317,24 @@
* simple_bridge/native_bridge are likely the only techs that will do this.
*/
bridge_channel->bridge->technology->write(bridge_channel->bridge, bridge_channel, frame);
+
+ /* Remember any owed events to the bridge. */
+ switch (frame->frametype) {
+ case AST_FRAME_DTMF_BEGIN:
+ bridge_channel->owed.dtmf_tv = ast_tvnow();
+ bridge_channel->owed.dtmf_digit = frame->subclass.integer;
+ break;
+ case AST_FRAME_DTMF_END:
+ bridge_channel->owed.dtmf_digit = '\0';
+ break;
+ case AST_FRAME_CONTROL:
+ /*
+ * We explicitly will not remember HOLD/UNHOLD frames because
+ * things like attended transfers will handle them.
+ */
+ default:
+ break;
+ }
ast_bridge_unlock(bridge_channel->bridge);
/*
@@ -324,6 +342,27 @@
* support is added, claim successfully deferred.
*/
return 0;
+}
+
+void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
+{
+ if (bridge_channel->owed.dtmf_digit) {
+ struct ast_frame frame = {
+ .frametype = AST_FRAME_DTMF_END,
+ .subclass.integer = bridge_channel->owed.dtmf_digit,
+ .src = "Bridge channel owed DTMF",
+ };
+
+ frame.len = ast_tvdiff_ms(ast_tvnow(), bridge_channel->owed.dtmf_tv);
+ if (frame.len < option_dtmfminduration) {
+ frame.len = option_dtmfminduration;
+ }
+ ast_log(LOG_DTMF, "DTMF end '%c' simulated to bridge %s because %s left. Duration %ld ms.\n",
+ bridge_channel->owed.dtmf_digit, orig_bridge->uniqueid,
+ ast_channel_name(bridge_channel->chan), frame.len);
+ bridge_channel->owed.dtmf_digit = '\0';
+ orig_bridge->technology->write(orig_bridge, NULL, &frame);
+ }
}
/*!
@@ -1350,8 +1389,6 @@
bridge->v_table->name,
bridge->uniqueid);
-/* BUGBUG This is where incoming HOLD/UNHOLD memory should write UNHOLD into bridge. (if not local optimizing) */
-/* BUGBUG This is where incoming DTMF begin/end memory should write DTMF end into bridge. (if not local optimizing) */
if (!bridge_channel->just_joined) {
/* Tell the bridge technology we are leaving so they tear us down */
ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology\n",
@@ -1649,7 +1686,6 @@
bridge_channel_handle_hangup(bridge_channel);
ast_frfree(frame);
return;
-/* BUGBUG This is where incoming HOLD/UNHOLD memory should register. Write UNHOLD into bridge when this channel is pulled. */
default:
break;
}
@@ -1665,7 +1701,6 @@
ast_frfree(frame);
return;
}
-/* BUGBUG This is where incoming DTMF begin/end memory should register. Write DTMF end into bridge when this channel is pulled. */
break;
default:
break;
@@ -1819,6 +1854,7 @@
int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)
{
int res = 0;
+
ast_format_copy(&bridge_channel->read_format, ast_channel_readformat(bridge_channel->chan));
ast_format_copy(&bridge_channel->write_format, ast_channel_writeformat(bridge_channel->chan));
@@ -1875,6 +1911,7 @@
}
bridge_channel_internal_pull(bridge_channel);
+ bridge_channel_settle_owed_events(bridge_channel->bridge, bridge_channel);
bridge_reconfigured(bridge_channel->bridge, 1);
ast_bridge_unlock(bridge_channel->bridge);
Modified: team/rmudgett/bridge_phase/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/channel.c?view=diff&rev=396519&r1=396518&r2=396519
==============================================================================
--- team/rmudgett/bridge_phase/main/channel.c (original)
+++ team/rmudgett/bridge_phase/main/channel.c Fri Aug 9 20:20:35 2013
@@ -10394,6 +10394,9 @@
}
duration = ast_tvdiff_ms(ast_tvnow(), start);
+ if (duration < option_dtmfminduration) {
+ duration = option_dtmfminduration;
+ }
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);
More information about the svn-commits
mailing list