[asterisk-commits] rmudgett: branch rmudgett/bridge_phase r396519 - in /team/rmudgett/bridge_pha...

SVN commits to the Asterisk project asterisk-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 asterisk-commits mailing list