From 0072806df183ee6f303fb624ee1484cdc68b3d76 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 24 Jan 2020 18:49:11 +0400 Subject: [PATCH] [mod_loopback] Split null_auto_answer into two variables null_enable_auto_answer and null_auto_answer_delay. Default auto_answer_delay is 0 instead of 1 ms. Auto answer is enabled by default if null_enable_auto_answer is not set. More carefully compute the delay in ms to not block channel longer than needed. --- src/mod/endpoints/mod_loopback/mod_loopback.c | 44 ++++++++++++------- tests/unit/switch_ivr_originate.c | 27 ++++++++---- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 67cfd8c13f..88400fcaf6 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -1306,8 +1306,12 @@ struct null_private_object { switch_frame_t read_frame; int16_t *null_buf; int rate; - int pre_answer; // pre answer the channel - int auto_answer; // answer after in ms + /* pre answer the channel */ + int pre_answer; + /* enable_auto_answer (enabled by default) */ + int enable_auto_answer; + /* auto_answer_delay (0 ms by default) */ + int auto_answer_delay; }; typedef struct null_private_object null_private_t; @@ -1463,14 +1467,15 @@ static switch_status_t null_channel_on_consume_media(switch_core_session_t *sess switch_channel_mark_pre_answered(channel); } - if (tech_pvt->auto_answer > 0) { - int sanity = tech_pvt->auto_answer; + if (tech_pvt->enable_auto_answer) { + switch_time_t start_time = switch_time_now(); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CHANNEL CONSUME_MEDIA - answering in %d ms\n", tech_pvt->auto_answer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CHANNEL CONSUME_MEDIA - answering in %d ms\n", tech_pvt->auto_answer_delay); - while(switch_channel_ready(channel) && sanity > 0) { - switch_yield(1000 * 1000); - sanity -= 1000; + if (tech_pvt->auto_answer_delay > 0) { + while (switch_channel_ready(channel) && ((int)((switch_time_now() - start_time) / 1000)) < tech_pvt->auto_answer_delay) { + switch_yield(1000 * 20); + } } switch_channel_mark_answered(channel); @@ -1610,7 +1615,8 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t * { char name[128]; switch_channel_t *ochannel = NULL; - const char *auto_answer = switch_event_get_header(var_event, "null_auto_answer"); + const char *enable_auto_answer = switch_event_get_header(var_event, "null_enable_auto_answer"); + const char *auto_answer_delay = switch_event_get_header(var_event, "null_auto_answer_delay"); const char *pre_answer = switch_event_get_header(var_event, "null_pre_answer"); const char *hangup_cause = switch_event_get_header(var_event, "null_hangup_cause"); @@ -1646,13 +1652,21 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t * tech_pvt->pre_answer = switch_true(pre_answer); - if (auto_answer) { - tech_pvt->auto_answer = atoi(auto_answer); - - if (tech_pvt->auto_answer < 0) tech_pvt->auto_answer = 0; - if (tech_pvt->auto_answer > 60000) tech_pvt->auto_answer = 60000; + if (!enable_auto_answer) { + /* if not set - enabled by default */ + tech_pvt->enable_auto_answer = SWITCH_TRUE; } else { - tech_pvt->auto_answer = 1; + tech_pvt->enable_auto_answer = switch_true(enable_auto_answer); + } + + if (!auto_answer_delay) { + /* if not set - 0 ms by default */ + tech_pvt->auto_answer_delay = 0; + } else { + tech_pvt->auto_answer_delay = atoi(auto_answer_delay); + + if (tech_pvt->auto_answer_delay < 0) tech_pvt->auto_answer_delay = 0; + if (tech_pvt->auto_answer_delay > 60000) tech_pvt->auto_answer_delay = 60000; } channel = switch_core_session_get_channel(*new_session); diff --git a/tests/unit/switch_ivr_originate.c b/tests/unit/switch_ivr_originate.c index 0b91f3ee16..49174f3b33 100644 --- a/tests/unit/switch_ivr_originate.c +++ b/tests/unit/switch_ivr_originate.c @@ -274,7 +274,8 @@ FST_CORE_BEGIN("./conf") switch_dial_leg_list_add_leg(ll, &leg, "null/test"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://1000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); - switch_dial_handle_add_global_var(dh, "null_auto_answer", "2000"); + switch_dial_handle_add_global_var(dh, "null_enable_auto_answer", "1"); + switch_dial_handle_add_global_var(dh, "null_auto_answer_delay", "2000"); status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); fst_requires(status == SWITCH_STATUS_SUCCESS); @@ -303,7 +304,8 @@ FST_CORE_BEGIN("./conf") switch_dial_leg_list_add_leg(ll, &leg, "null/test"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://1000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); - switch_dial_handle_add_global_var(dh, "null_auto_answer", "2000"); + switch_dial_handle_add_global_var(dh, "null_enable_auto_answer", "1"); + switch_dial_handle_add_global_var(dh, "null_auto_answer_delay", "2000"); switch_dial_handle_add_global_var(dh, "null_pre_answer", "true"); status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); @@ -333,7 +335,8 @@ FST_CORE_BEGIN("./conf") switch_dial_leg_list_add_leg(ll, &leg, "null/test"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://1000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); - switch_dial_handle_add_global_var(dh, "null_auto_answer", "2000"); + switch_dial_handle_add_global_var(dh, "null_enable_auto_answer", "1"); + switch_dial_handle_add_global_var(dh, "null_auto_answer_delay", "2000"); switch_dial_handle_add_global_var(dh, "null_pre_answer", "true"); switch_dial_handle_add_global_var(dh, "group_confirm_early_ok", "false"); @@ -364,7 +367,8 @@ FST_CORE_BEGIN("./conf") switch_dial_leg_list_add_leg(ll, &leg, "null/test"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://1000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); - switch_dial_handle_add_global_var(dh, "null_auto_answer", "2000"); + switch_dial_handle_add_global_var(dh, "null_enable_auto_answer", "1"); + switch_dial_handle_add_global_var(dh, "null_auto_answer_delay", "2000"); switch_dial_handle_add_global_var(dh, "null_pre_answer", "true"); switch_dial_handle_add_global_var(dh, "ignore_early_media", "true"); @@ -500,7 +504,8 @@ FST_CORE_BEGIN("./conf") switch_dial_handle_add_leg_list(dh, &ll); switch_dial_leg_list_add_leg(ll, &leg, "null/test"); - switch_dial_handle_add_leg_var(leg, "null_auto_answer", "2000"); + switch_dial_handle_add_leg_var(leg, "null_enable_auto_answer", "1"); + switch_dial_handle_add_leg_var(leg, "null_auto_answer_delay", "2000"); switch_dial_handle_add_leg_var(leg, "leg_timeout", "4"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://6000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); @@ -527,7 +532,8 @@ FST_CORE_BEGIN("./conf") switch_dial_handle_add_leg_list(dh, &ll); switch_dial_leg_list_add_leg(ll, &leg, "null/test"); - switch_dial_handle_add_leg_var(leg, "null_auto_answer", "2000"); + switch_dial_handle_add_leg_var(leg, "null_enable_auto_answer", "1"); + switch_dial_handle_add_leg_var(leg, "null_auto_answer_delay", "2000"); switch_dial_handle_add_leg_var(leg, "leg_timeout", "6"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://2000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); @@ -558,7 +564,8 @@ FST_CORE_BEGIN("./conf") switch_dial_leg_list_add_leg(ll, &leg, "null/test"); switch_dial_handle_add_leg_var(leg, "leg_timeout", "15"); - switch_dial_handle_add_leg_var(leg, "null_auto_answer", "2000"); + switch_dial_handle_add_leg_var(leg, "null_enable_auto_answer", "1"); + switch_dial_handle_add_leg_var(leg, "null_auto_answer_delay", "2000"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://10000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); switch_dial_handle_add_leg_var(leg, "group_confirm_timeout", "3"); @@ -586,7 +593,8 @@ FST_CORE_BEGIN("./conf") switch_dial_leg_list_add_leg(ll, &leg, "null/test"); switch_dial_handle_add_leg_var(leg, "leg_timeout", "15"); - switch_dial_handle_add_leg_var(leg, "null_auto_answer", "2000"); + switch_dial_handle_add_leg_var(leg, "null_enable_auto_answer", "1"); + switch_dial_handle_add_leg_var(leg, "null_auto_answer_delay", "2000"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://10000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); switch_dial_handle_add_global_var(dh, "group_confirm_timeout", "3"); @@ -614,7 +622,8 @@ FST_CORE_BEGIN("./conf") switch_dial_leg_list_add_leg(ll, &leg, "null/test"); switch_dial_handle_add_leg_var(leg, "leg_timeout", "3"); - switch_dial_handle_add_leg_var(leg, "null_auto_answer", "2000"); + switch_dial_handle_add_leg_var(leg, "null_enable_auto_answer", "1"); + switch_dial_handle_add_leg_var(leg, "null_auto_answer_delay", "2000"); switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://2000"); switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); switch_dial_handle_add_global_var(dh, "group_confirm_cancel_timeout", "true");