diff --git a/channel.c b/channel.c index d4e88854ceee7473446b4f76ea2a272f80469c22..eebcd517d1072f3b9d42170effa0f574fec743d6 100755 --- a/channel.c +++ b/channel.c @@ -2874,7 +2874,7 @@ static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, check = ast_autoservice_stop(peer); } -static int ast_generic_bridge(int *playitagain, int *playit, struct timeval *start_time, struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc) +static int ast_generic_bridge(int *playitagain, int *playit, struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc) { /* Copy voice back and forth between the two channels. Give the peer the ability to transfer calls with '#<extension' syntax. */ @@ -2905,7 +2905,7 @@ static int ast_generic_bridge(int *playitagain, int *playit, struct timeval *sta /* timestamp */ if (config->timelimit) { /* If there is a time limit, return now */ - elapsed_ms = ast_tvdiff_ms(ast_tvnow(), *start_time); + elapsed_ms = ast_tvdiff_ms(ast_tvnow(), config->start_time); time_left_ms = config->timelimit - elapsed_ms; if (*playitagain && ((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) || (ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING))) && (config->play_warning && time_left_ms <= config->play_warning)) { @@ -3027,7 +3027,6 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as int firstpass; int o0nativeformats; int o1nativeformats; - struct timeval start_time; long elapsed_ms=0, time_left_ms=0; int playit=0, playitagain=1, first_time=1; @@ -3036,7 +3035,8 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as config->firstpass = 0; /* timestamp */ - start_time = ast_tvnow(); + if (! (config->start_time.tv_sec && config->start_time.tv_usec)) + config->start_time = ast_tvnow(); time_left_ms = config->timelimit; if ((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) && config->start_sound && firstpass) @@ -3078,7 +3078,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as for (/* ever */;;) { /* timestamp */ if (config->timelimit) { - elapsed_ms = ast_tvdiff_ms(ast_tvnow(), start_time); + elapsed_ms = ast_tvdiff_ms(ast_tvnow(), config->start_time); time_left_ms = config->timelimit - elapsed_ms; if (playitagain && ((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) || (ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING))) && (config->play_warning && time_left_ms <= config->play_warning)) { @@ -3195,7 +3195,7 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as o0nativeformats = c0->nativeformats; o1nativeformats = c1->nativeformats; } - res = ast_generic_bridge(&playitagain, &playit, &start_time, c0, c1, config, fo, rc); + res = ast_generic_bridge(&playitagain, &playit, c0, c1, config, fo, rc); if (res != -3) break; } diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index f53b39e8995947bc31614c83974f75f862b1d729..de2099288b41ae177eeda4ca1a52cc18875b3147 100755 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -370,6 +370,8 @@ struct ast_channel { struct ast_bridge_config { struct ast_flags features_caller; struct ast_flags features_callee; + struct timeval start_time; + long feature_timer; long timelimit; long play_warning; long warning_freq; diff --git a/res/res_features.c b/res/res_features.c index 5e3dca1e21164efb4b9a05df4d14427305745d7f..1b5856a107938788cee4d6fb686a878eb028dd7e 100755 --- a/res/res_features.c +++ b/res/res_features.c @@ -1118,6 +1118,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast memset(&backup_config, 0, sizeof(backup_config)); + config->start_time = ast_tvnow(); + if (chan && peer) { pbx_builtin_setvar_helper(chan, "BRIDGEPEER", peer->name); pbx_builtin_setvar_helper(peer, "BRIDGEPEER", chan->name); @@ -1161,26 +1163,28 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast peer->cdr = NULL; } for (;;) { - if (config->timelimit) + if (config->feature_timer) start = ast_tvnow(); + res = ast_channel_bridge(chan, peer, config, &f, &who); - if (config->timelimit) { + + if (config->feature_timer) { /* Update time limit for next pass */ diff = ast_tvdiff_ms(ast_tvnow(), start); - config->timelimit -= diff; + config->feature_timer -= diff; if (hasfeatures) { /* Running on backup config, meaning a feature might be being activated, but that's no excuse to keep things going indefinitely! */ - if (backup_config.timelimit && ((backup_config.timelimit -= diff) <= 0)) { + if (backup_config.feature_timer && ((backup_config.feature_timer -= diff) <= 0)) { ast_log(LOG_DEBUG, "Timed out, realtime this time!\n"); - config->timelimit = 0; + config->feature_timer = 0; who = chan; if (f) ast_frfree(f); f = NULL; res = 0; - } else if (config->timelimit <= 0) { + } else if (config->feature_timer <= 0) { /* Not *really* out of time, just out of time for digits to come in for features. */ ast_log(LOG_DEBUG, "Timed out for feature!\n"); @@ -1205,9 +1209,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast continue; } } else { - if (config->timelimit <=0) { + if (config->feature_timer <=0) { /* We ran out of time */ - config->timelimit = 0; + config->feature_timer = 0; who = chan; if (f) ast_frfree(f); @@ -1272,7 +1276,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast featurecode = peer_featurecode; } featurecode[strlen(featurecode)] = f->subclass; - config->timelimit = backup_config.timelimit; + config->feature_timer = backup_config.feature_timer; res = ast_feature_interpret(chan, peer, config, featurecode, sense); switch(res) { case FEATURE_RETURN_PASSDIGITS: @@ -1307,8 +1311,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast config->start_sound = NULL; config->firstpass = 0; } - config->timelimit = featuredigittimeout; - ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->timelimit); + config->feature_timer = featuredigittimeout; + ast_log(LOG_DEBUG, "Set time limit to %ld\n", config->feature_timer); } } if (f)