Skip to content

Commit ab468a1

Browse files
author
root
committed
[Core] Add absolute answer timeout for bridges
1 parent 4c193f0 commit ab468a1

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

src/switch_ivr_bridge.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
372372
const char *silence_var;
373373
int silence_val = 0, bypass_media_after_bridge = 0;
374374
const char *bridge_answer_timeout = NULL;
375+
const char *abs_answer_timeout = NULL;
375376
int bridge_filter_dtmf, answer_timeout, sent_update = 0;
376377
time_t answer_limit = 0;
377378
const char *exec_app = NULL;
@@ -425,6 +426,45 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
425426
}
426427
}
427428

429+
/* absolute_answer_timeout: compute the answer deadline relative to the originate
430+
* start time, so that the timeout covers the entire INVITE -> 200 OK window and
431+
* is not extended by 180/183 early media. When both bridge_answer_timeout and
432+
* absolute_answer_timeout are present, the earlier deadline wins.
433+
* absolute_answer_timeout: 基于 originate 开始时刻计算应答截止时间,使超时
434+
* 覆盖从 INVITE 到 200 OK 的整个窗口,不会被 180/183 早期媒体延长。当
435+
* bridge_answer_timeout 与 absolute_answer_timeout 同时存在时,以更早到期者为准。 */
436+
if (!switch_channel_test_flag(chan_a, CF_ANSWERED) &&
437+
(abs_answer_timeout = switch_channel_get_variable(chan_a, "absolute_answer_timeout"))) {
438+
int abs_timeout = atoi(abs_answer_timeout);
439+
if (abs_timeout > 0) {
440+
const char *start_epoch_str = switch_channel_get_variable(chan_a, "originate_start_epoch");
441+
time_t start_epoch = 0;
442+
443+
if (!zstr(start_epoch_str)) {
444+
start_epoch = (time_t) atol(start_epoch_str);
445+
}
446+
/* Fall back to "now" if the originate start was not recorded (e.g. the
447+
* caller channel was bridged from a path that did not go through
448+
* switch_ivr_originate). This degrades gracefully to bridge-loop relative.
449+
* 若未记录 originate 开始时间(例如未经 switch_ivr_originate 进入 bridge),
450+
* 退化为以当前时刻为起点,保证功能可用。 */
451+
if (start_epoch == 0) {
452+
start_epoch = switch_epoch_time_now(NULL);
453+
}
454+
455+
{
456+
time_t abs_limit = start_epoch + abs_timeout;
457+
458+
if (answer_limit == 0 || abs_limit < answer_limit) {
459+
answer_limit = abs_limit;
460+
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG,
461+
"Absolute answer timeout set to %d seconds from originate start on %s.\n",
462+
abs_timeout, switch_channel_get_name(chan_a));
463+
}
464+
}
465+
}
466+
}
467+
428468
switch_channel_clear_flag(chan_a, CF_INTERCEPT);
429469
switch_channel_clear_flag(chan_a, CF_INTERCEPTED);
430470

src/switch_ivr_originate.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,6 +2412,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
24122412
ok = 1;
24132413
} else if (!strcasecmp((char *) hi->name, "progress_timeout")) {
24142414
ok = 1;
2415+
} else if (!strcasecmp((char *) hi->name, "absolute_answer_timeout")) {
2416+
/* absolute_answer_timeout: pass through so bridge loop can read it
2417+
* absolute_answer_timeout: 透传到 bridge 阶段用于绝对应答超时控制 */
2418+
ok = 1;
24152419
} else if (!strcasecmp((char *) hi->name, "language")) {
24162420
ok = 1;
24172421
}
@@ -2688,6 +2692,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
26882692
switch_epoch_time_now(&global_start);
26892693
last_retry_start = switch_micro_time_now();
26902694

2695+
/* Record the originate start epoch on the caller channel so that the bridge
2696+
* loop can compute an absolute (from-INVITE) answer timeout that is not
2697+
* influenced by 180/183 early media signals.
2698+
* 记录 originate 开始时刻到 caller channel 变量,供 bridge 阶段计算
2699+
* 不受 180/183 早期媒体影响的绝对应答超时使用。 */
2700+
if (caller_channel) {
2701+
switch_channel_set_variable_printf(caller_channel, "originate_start_epoch", "%ld", (long) global_start);
2702+
}
2703+
26912704
for (try = 0; try < retries; try++) {
26922705

26932706
if (try > 0) {

0 commit comments

Comments
 (0)