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/trunk@176708 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
fc0ec9bab2
commit
fa3ebc7f2c
|
@ -572,6 +572,7 @@ enum {
|
||||||
AST_FEATURE_PARKCALL = (1 << 5),
|
AST_FEATURE_PARKCALL = (1 << 5),
|
||||||
AST_FEATURE_AUTOMIXMON = (1 << 6),
|
AST_FEATURE_AUTOMIXMON = (1 << 6),
|
||||||
AST_FEATURE_NO_H_EXTEN = (1 << 7),
|
AST_FEATURE_NO_H_EXTEN = (1 << 7),
|
||||||
|
AST_FEATURE_WARNING_ACTIVE = (1 << 7),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief bridge configuration */
|
/*! \brief bridge configuration */
|
||||||
|
@ -579,6 +580,7 @@ struct ast_bridge_config {
|
||||||
struct ast_flags features_caller;
|
struct ast_flags features_caller;
|
||||||
struct ast_flags features_callee;
|
struct ast_flags features_callee;
|
||||||
struct timeval start_time;
|
struct timeval start_time;
|
||||||
|
struct timeval nexteventts;
|
||||||
long feature_timer;
|
long feature_timer;
|
||||||
long timelimit;
|
long timelimit;
|
||||||
long play_warning;
|
long play_warning;
|
||||||
|
|
|
@ -4378,10 +4378,13 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
|
||||||
if (bridge_end.tv_sec) {
|
if (bridge_end.tv_sec) {
|
||||||
to = ast_tvdiff_ms(bridge_end, ast_tvnow());
|
to = ast_tvdiff_ms(bridge_end, ast_tvnow());
|
||||||
if (to <= 0) {
|
if (to <= 0) {
|
||||||
if (config->timelimit)
|
if (config->timelimit) {
|
||||||
res = AST_BRIDGE_RETRY;
|
res = AST_BRIDGE_RETRY;
|
||||||
else
|
/* generic bridge ending to play warning */
|
||||||
|
ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
|
||||||
|
} else {
|
||||||
res = AST_BRIDGE_COMPLETE;
|
res = AST_BRIDGE_COMPLETE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -4460,6 +4463,7 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
|
||||||
ast_debug(1, "Got DTMF %s on channel (%s)\n",
|
ast_debug(1, "Got DTMF %s on channel (%s)\n",
|
||||||
f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
|
f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
|
||||||
who->name);
|
who->name);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Write immediately frames, not passed through jb */
|
/* Write immediately frames, not passed through jb */
|
||||||
|
@ -4531,7 +4535,6 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
int o0nativeformats;
|
int o0nativeformats;
|
||||||
int o1nativeformats;
|
int o1nativeformats;
|
||||||
long time_left_ms=0;
|
long time_left_ms=0;
|
||||||
struct timeval nexteventts = { 0, };
|
|
||||||
char caller_warning = 0;
|
char caller_warning = 0;
|
||||||
char callee_warning = 0;
|
char callee_warning = 0;
|
||||||
|
|
||||||
|
@ -4578,11 +4581,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
o1nativeformats = c1->nativeformats;
|
o1nativeformats = c1->nativeformats;
|
||||||
|
|
||||||
if (config->feature_timer) {
|
if (config->feature_timer) {
|
||||||
nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
|
config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
|
||||||
} else if (config->timelimit) {
|
} else if (config->timelimit && firstpass) {
|
||||||
nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
|
config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
|
||||||
if (caller_warning || callee_warning)
|
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)
|
if (!c0->tech->send_digit_begin)
|
||||||
|
@ -4602,9 +4605,9 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
|
|
||||||
to = -1;
|
to = -1;
|
||||||
|
|
||||||
if (!ast_tvzero(nexteventts)) {
|
if (!ast_tvzero(config->nexteventts)) {
|
||||||
now = ast_tvnow();
|
now = ast_tvnow();
|
||||||
to = ast_tvdiff_ms(nexteventts, now);
|
to = ast_tvdiff_ms(config->nexteventts, now);
|
||||||
if (to <= 0) {
|
if (to <= 0) {
|
||||||
if (!config->timelimit) {
|
if (!config->timelimit) {
|
||||||
res = AST_BRIDGE_COMPLETE;
|
res = AST_BRIDGE_COMPLETE;
|
||||||
|
@ -4632,7 +4635,7 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!to) {
|
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 */
|
int t = (time_left_ms + 500) / 1000; /* round to nearest second */
|
||||||
if (caller_warning)
|
if (caller_warning)
|
||||||
bridge_playfile(c0, c1, config->warning_sound, t);
|
bridge_playfile(c0, c1, config->warning_sound, t);
|
||||||
|
@ -4640,10 +4643,11 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
|
||||||
bridge_playfile(c1, c0, config->warning_sound, t);
|
bridge_playfile(c1, c0, config->warning_sound, t);
|
||||||
}
|
}
|
||||||
if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
|
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
|
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) {
|
if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
|
||||||
|
@ -4756,9 +4760,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")))
|
if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
|
||||||
pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
|
pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
|
||||||
|
|
||||||
res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
|
res = ast_generic_bridge(c0, c1, config, fo, rc, config->nexteventts);
|
||||||
if (res != AST_BRIDGE_RETRY)
|
if (res != AST_BRIDGE_RETRY) {
|
||||||
break;
|
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);
|
ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
|
||||||
|
|
|
@ -2533,6 +2533,15 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
|
||||||
if (config->feature_timer) {
|
if (config->feature_timer) {
|
||||||
/* Update time limit for next pass */
|
/* Update time limit for next pass */
|
||||||
diff = ast_tvdiff_ms(ast_tvnow(), config->start_time);
|
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;
|
config->feature_timer -= diff;
|
||||||
if (hasfeatures) {
|
if (hasfeatures) {
|
||||||
/* Running on backup config, meaning a feature might be being
|
/* Running on backup config, meaning a feature might be being
|
||||||
|
|
Reference in New Issue