Index: corelib/channel.c =================================================================== --- corelib/channel.c (revision 4155) +++ corelib/channel.c (working copy) @@ -3265,7 +3265,7 @@ } static enum opbx_bridge_result opbx_generic_bridge(struct opbx_channel *c0, struct opbx_channel *c1, - struct opbx_bridge_config *config, struct opbx_frame **fo, struct opbx_channel **rc, int to) + struct opbx_bridge_config *config, struct opbx_frame **fo, struct opbx_channel **rc, struct timeval bridge_end) { /* Copy voice back and forth between the two channels. */ struct opbx_channel *cs[3]; @@ -3277,7 +3277,7 @@ int watch_c0_dtmf; int watch_c1_dtmf; void *pvt0, *pvt1; - int toms = to; + int to, toms; /* Indicates whether a frame was queued into a jitterbuffer */ int frame_put_in_jb; @@ -3330,6 +3330,18 @@ break; } + if (bridge_end.tv_sec) { + to = opbx_tvdiff_ms(bridge_end, opbx_tvnow()); + if (to <= 0) { + if (config->timelimit) + res = OPBX_BRIDGE_RETRY; + else + res = OPBX_BRIDGE_COMPLETE; + break; + } + } else { + to = -1; + } /* Calculate the appropriate max sleep interval - * in general, this is the time, * left to the closest jb delivery moment */ @@ -3446,6 +3458,7 @@ char caller_warning = 0; char callee_warning = 0; int to; + struct timeval now = { 0, }; if (c0->_bridge) { opbx_log(OPBX_LOG_WARNING, "%s is already in a bridge with %s\n", @@ -3505,12 +3518,19 @@ for (/* ever */;;) { to = -1; - if (config->timelimit) { - struct timeval now; + now = { 0, }; + + if(!opxb_tvzero(nexteventts)) { now = opbx_tvnow(); to = opbx_tvdiff_ms(nexteventts, now); - if (to < 0) - to = 0; + if (to < 0 && !config->timelimit) { + res = OPBX_BRIDGE_COMPLETE; + break; + } + } + + if (config->timelimit) { + time_left_ms = config->timelimit - opbx_tvdiff_ms(now, config->start_time); if (time_left_ms < to) to = time_left_ms; @@ -3527,7 +3547,7 @@ break; } - if (!to) { + if (to <= 0) { if (time_left_ms >= 5000) { if (caller_warning && config->warning_sound && config->play_warning) bridge_playfile(c0, c1, config->warning_sound, time_left_ms / 1000); @@ -3536,8 +3556,10 @@ } if (config->warning_freq) { nexteventts = opbx_tvadd(nexteventts, opbx_samp2tv(config->warning_freq, 1000)); - } else + } + if ( (!config->warning_freq) || ( config->timelimit - opbx_tvdiff_ms(nexteventts, config->start_time) < 0)) { nexteventts = opbx_tvadd(config->start_time, opbx_samp2tv(config->timelimit, 1000)); + } } } @@ -3648,8 +3670,8 @@ o0nativeformats = c0->nativeformats; o1nativeformats = c1->nativeformats; } - res = opbx_generic_bridge(c0, c1, config, fo, rc, to); - if (res != OPBX_BRIDGE_RETRY) + res = opbx_generic_bridge(c0, c1, config, fo, rc, nexteventts); + if (res != OPBX_BRIDGE_RETRY && fo) break; }