aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorjpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-17 22:14:38 +0000
committerjpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-17 22:14:38 +0000
commit62b2e53625be7a0f90d0328aff129e63938b38ca (patch)
treee791a1a22861701e7308e4dc4da38271fa651ebe /main
parente081717c3c5031474e1d95120f15e842cf9649a6 (diff)
Merged revisions 176708 via svnmerge from
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: http://svn.digium.com/svn/asterisk/branches/1.6.0@176710 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/channel.c36
-rw-r--r--main/features.c9
2 files changed, 31 insertions, 14 deletions
diff --git a/main/channel.c b/main/channel.c
index e03ed2109..a57f64925 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -4359,10 +4359,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
@@ -4441,6 +4444,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 */
@@ -4512,7 +4516,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;
@@ -4559,11 +4562,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)
@@ -4582,9 +4585,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;
@@ -4612,7 +4615,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);
@@ -4620,10 +4623,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) {
@@ -4726,9 +4730,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);
diff --git a/main/features.c b/main/features.c
index d1dfcba7f..9ae81865e 100644
--- a/main/features.c
+++ b/main/features.c
@@ -2267,6 +2267,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