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);


--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to