]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 176708 via svnmerge from
authorJeff Peeler <jpeeler@digium.com>
Tue, 17 Feb 2009 22:15:26 +0000 (22:15 +0000)
committerJeff Peeler <jpeeler@digium.com>
Tue, 17 Feb 2009 22:15:26 +0000 (22:15 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
  r176708 | jpeeler | 2009-02-17 16:08:00 -0600 (Tue, 17 Feb 2009) | 23 lines

  Merged revisions 176701 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.4

  ........
    r176701 | jpeeler | 2009-02-17 15:54:34 -0600 (Tue, 17 Feb 2009) | 17 lines

    Modify bridging to properly evaluate DTMF after first warning is played

    The main problem is currently if the Dial flag L is used with a warning sound,
    DTMF is not evaluated after the first warning sound. To fix this, a flag has
    been added in ast_generic_bridge for playing the warning which ensures that if
    a scheduled warning is missed, multiple warrnings are not played back (due to a
    feature evaluation or waiting for digits). ast_channel_bridge was modified to
    store the nexteventts in the ast_bridge_config structure as that information
    was lost every time ast_channel_bridge was reentered, causing a hangup due to
    incorrect time calculations.

    (closes issue #14315)
    Reported by: tim_ringenbach

    Reviewed on reviewboard:
    http://reviewboard.digium.com/r/163/
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@176711 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/channel.h
main/channel.c
main/features.c

index c1898bff1d6ceec04b89281ad24ef7ff59e2f051..d2d7b723d556e0adb3aa5dab299c3e4867f1916f 100644 (file)
@@ -572,6 +572,7 @@ enum {
        AST_FEATURE_PARKCALL =     (1 << 5),
        AST_FEATURE_AUTOMIXMON =   (1 << 6),
        AST_FEATURE_NO_H_EXTEN =   (1 << 7),
+       AST_FEATURE_WARNING_ACTIVE = (1 << 7),
 };
 
 /*! \brief bridge configuration */
@@ -579,6 +580,7 @@ struct ast_bridge_config {
        struct ast_flags features_caller;
        struct ast_flags features_callee;
        struct timeval start_time;
+       struct timeval nexteventts;
        long feature_timer;
        long timelimit;
        long play_warning;
index 5ab607a8e974bf1667020c069d03a3523ff40977..b17bd6e29d0dbf714dcc8774b619b38a320c6a34 100644 (file)
@@ -4352,10 +4352,13 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
                if (bridge_end.tv_sec) {
                        to = ast_tvdiff_ms(bridge_end, ast_tvnow());
                        if (to <= 0) {
-                               if (config->timelimit)
+                               if (config->timelimit) {
                                        res = AST_BRIDGE_RETRY;
-                               else
+                                       /* generic bridge ending to play warning */
+                                       ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
+                               } else {
                                        res = AST_BRIDGE_COMPLETE;
+                               }
                                break;
                        }
                } else
@@ -4434,6 +4437,7 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
                                ast_debug(1, "Got DTMF %s on channel (%s)\n", 
                                        f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
                                        who->name);
+
                                break;
                        }
                        /* Write immediately frames, not passed through jb */
@@ -4505,7 +4509,6 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
        int o0nativeformats;
        int o1nativeformats;
        long time_left_ms=0;
-       struct timeval nexteventts = { 0, };
        char caller_warning = 0;
        char callee_warning = 0;
 
@@ -4552,11 +4555,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
        o1nativeformats = c1->nativeformats;
 
        if (config->feature_timer) {
-               nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
-       } else if (config->timelimit) {
-               nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
+               config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
+       } else if (config->timelimit && firstpass) {
+               config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
                if (caller_warning || callee_warning)
-                       nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
+                       config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(config->play_warning, 1000));
        }
 
        if (!c0->tech->send_digit_begin)
@@ -4576,9 +4579,9 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
 
                to = -1;
 
-               if (!ast_tvzero(nexteventts)) {
+               if (!ast_tvzero(config->nexteventts)) {
                        now = ast_tvnow();
-                       to = ast_tvdiff_ms(nexteventts, now);
+                       to = ast_tvdiff_ms(config->nexteventts, now);
                        if (to <= 0) {
                                if (!config->timelimit) {
                                        res = AST_BRIDGE_COMPLETE;
@@ -4606,7 +4609,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                        }
                        
                        if (!to) {
-                               if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
+                               if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
                                        int t = (time_left_ms + 500) / 1000; /* round to nearest second */
                                        if (caller_warning)
                                                bridge_playfile(c0, c1, config->warning_sound, t);
@@ -4614,10 +4617,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                                                bridge_playfile(c1, c0, config->warning_sound, t);
                                }
                                if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
-                                       nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
+                                       config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
                                else
-                                       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
+                                       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
                        }
+                       ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
                }
 
                if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
@@ -4730,9 +4734,13 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
                if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
                        pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
 
-               res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
-               if (res != AST_BRIDGE_RETRY)
+               res = ast_generic_bridge(c0, c1, config, fo, rc, config->nexteventts);
+               if (res != AST_BRIDGE_RETRY) {
+                       break;
+               } else if (config->feature_timer) {
+                       /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */
                        break;
+               }
        }
 
        ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
index 9f59497d72ad193264849107ed5b54bef1713ccb..4ced238a250e0878cb74fc72bebc7c4af08ddc4a 100644 (file)
@@ -2464,6 +2464,15 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
                if (config->feature_timer) {
                        /* Update time limit for next pass */
                        diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
+                       if (res == AST_BRIDGE_RETRY) {
+                               /* The feature fully timed out but has not been updated. Skip
+                                * the potential round error from the diff calculation and
+                                * explicitly set to expired. */
+                               config->feature_timer = -1;
+                       } else {
+                               config->feature_timer -= diff;
+                       }
+
                        config->feature_timer -= diff;
                        if (hasfeatures) {
                                /* Running on backup config, meaning a feature might be being