aboutsummaryrefslogtreecommitdiffstats
path: root/channel.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-09-27 16:54:30 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-09-27 16:54:30 +0000
commita0b53a7da58f56277a57fdb1741d8151fb1a91b0 (patch)
tree47c4334bd5bea2e048ac5630f6937996701345af /channel.c
parenta029017f157cfd3b0b6bcbf3e64fa096a500f7d4 (diff)
Fix a problem that occurred if a user entered a digit that matched a bridge
feature that was configured using multiple digits, and the digit that was pressed timed out in the feature digit timeout period. For example, if blind transfer is configured as '##', and a user presses just '#'. In this situation, the call would lock up and no longer pass any frames. (issue #7977 reported by festr, and issue #7982 reported by michaels and valuable input provided by mneuhauser and kuj. Fixed by me, with testing help and peer review from Joshua Colp). There are a couple of issues involved in this fix: 1) When ast_generic_bridge determines that there has been a timeout, it returned AST_BRIDGE_RETRY. Then, when ast_channel_bridge gets this result, it calls ast_generic_bridge over again with the same timestamp for the next event. This results in an endless loop of nothing until the call is terminated. This is resolved by simply changing ast_generic_bridge to return AST_BRIDGE_COMPLETE when it sees a timeout. 2) I also changed ast_channel_bridge such that if in the process of calculating the time until the next event, it knows a timeout has already occured, to immediately return AST_BRIDGE_COMPLETE instead of attempting to bridge the channels anyway. 3) In the process of testing the previous two changes, I ran into a problem in res_features where ast_channel_bridge would return because it determined that there was a timeout. However, ast_bridge_call in res_features would then determine by its own calculation that there was still 1 ms before the timeout really occurs. It would then proceed, and since the bridge broke out and did *not* return a frame, it interpreted this as the call was over and hung up the channels. The reason for this was because ast_bridge_call in res_features and ast_channel_bridge in channel.c were using different times for their calculations. channel.c uses the start_time on the bridge config, which is the time that the feature digit was recieved. However, res_features had another time, 'start', which was set right before calling ast_channel_bridge. 'start' will always be slightly after start_time in the bridge config, and sometimes enough to round up to one ms. This is fixed by making ast_bridge_call use the same time as ast_channel_bridge for the timeout calculation. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@43778 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channel.c')
-rw-r--r--channel.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/channel.c b/channel.c
index a823e67ca..ae5d5f79c 100644
--- a/channel.c
+++ b/channel.c
@@ -3351,7 +3351,7 @@ 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) {
- res = AST_BRIDGE_RETRY;
+ res = AST_BRIDGE_COMPLETE;
break;
}
} else
@@ -3510,8 +3510,10 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
if (!ast_tvzero(nexteventts)) {
now = ast_tvnow();
to = ast_tvdiff_ms(nexteventts, now);
- if (to < 0)
- to = 0;
+ if (to <= 0) {
+ res = AST_BRIDGE_COMPLETE;
+ break;
+ }
}
if (config->timelimit) {