From fcda4c6a06ec2ddeb719249fbd92f3fbf052a86d Mon Sep 17 00:00:00 2001 From: Seven Du Date: Wed, 6 Nov 2019 22:10:54 +0800 Subject: [PATCH] [core] add support to set group confirm on each leg --- src/switch_ivr_originate.c | 18 ++- tests/unit/conf/freeswitch.xml | 2 + tests/unit/switch_ivr_originate.c | 219 +++++++++++++++++++++++++++++- 3 files changed, 235 insertions(+), 4 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 48ec669a31..6adaba174e 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -764,7 +764,10 @@ static uint8_t check_channel_status(originate_global_t *oglobals, uint32_t len, && !switch_channel_test_flag(oglobals->originate_status[i].peer_channel, CF_TAGGED) ) { - if (!zstr(oglobals->key)) { + const char *group_confirm_key = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "group_confirm_key"); + const char *group_confirm_file = switch_channel_get_variable(oglobals->originate_status[i].peer_channel, "group_confirm_file"); + + if (!zstr(oglobals->key) || !zstr(group_confirm_key)) { struct key_collect *collect; if (oglobals->cancel_timeout == SWITCH_TRUE) { @@ -775,10 +778,15 @@ static uint8_t check_channel_status(originate_global_t *oglobals, uint32_t len, if ((collect = switch_core_session_alloc(oglobals->originate_status[i].peer_session, sizeof(*collect)))) { switch_channel_set_flag(oglobals->originate_status[i].peer_channel, CF_TAGGED); - if (!zstr(oglobals->key)) { + if (!zstr(group_confirm_key)) { + collect->key = switch_core_session_strdup(oglobals->originate_status[i].peer_session, group_confirm_key); + } else { collect->key = switch_core_session_strdup(oglobals->originate_status[i].peer_session, oglobals->key); } - if (!zstr(oglobals->file)) { + + if (!zstr(group_confirm_file)) { + collect->file = switch_core_session_strdup(oglobals->originate_status[i].peer_session, group_confirm_file); + } else if (!zstr(oglobals->file)) { collect->file = switch_core_session_strdup(oglobals->originate_status[i].peer_session, oglobals->file); } if (!zstr(oglobals->error_file)) { @@ -2377,6 +2385,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess oglobals.cancel_timeout = SWITCH_TRUE; } + if ((var = switch_event_get_header(var_event, "group_confirm_early_ok"))) { + oglobals.early_ok = switch_true(var); + } + if ((var = switch_event_get_header(var_event, "group_confirm_key"))) { switch_copy_string(oglobals.key, var, sizeof(oglobals.key)); if ((var = switch_event_get_header(var_event, "group_confirm_file"))) { diff --git a/tests/unit/conf/freeswitch.xml b/tests/unit/conf/freeswitch.xml index 3e25162a8c..cd9ba2131c 100644 --- a/tests/unit/conf/freeswitch.xml +++ b/tests/unit/conf/freeswitch.xml @@ -11,6 +11,8 @@ + + diff --git a/tests/unit/switch_ivr_originate.c b/tests/unit/switch_ivr_originate.c index 1354e3b921..701f1bfc44 100644 --- a/tests/unit/switch_ivr_originate.c +++ b/tests/unit/switch_ivr_originate.c @@ -50,7 +50,7 @@ static switch_status_t my_on_destroy(switch_core_session_t *session) { switch_assert(session); destroy++; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "session destroy %d\n", destroy); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "session destroy %d\n", destroy); return SWITCH_STATUS_SUCCESS; } @@ -220,6 +220,223 @@ FST_CORE_BEGIN("./conf") switch_dial_handle_destroy(&dh); } FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_one_leg) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + switch_dial_handle_t *dh; + switch_dial_leg_list_t *ll; + switch_dial_leg_t *leg = NULL; + + switch_dial_handle_create(&dh); + 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, "group_confirm_file", "playback silence_stream://1000"); + switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); + + status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + switch_core_session_rwunlock(session); + + switch_dial_handle_destroy(&dh); + } + FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_no_pre_answer) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + switch_dial_handle_t *dh; + switch_dial_leg_list_t *ll; + switch_dial_leg_t *leg = NULL; + + switch_dial_handle_create(&dh); + 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, "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"); + + status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + switch_core_session_rwunlock(session); + + switch_dial_handle_destroy(&dh); + + fst_check_duration(3000, 500); + } + FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_exec_in_pre_answer) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + switch_dial_handle_t *dh; + switch_dial_leg_list_t *ll; + switch_dial_leg_t *leg = NULL; + + switch_dial_handle_create(&dh); + 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, "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_pre_answer", "true"); + + status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + switch_core_session_rwunlock(session); + + switch_dial_handle_destroy(&dh); + + fst_check_duration(1000, 500); + } + FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_exec_after_answer_early_ok) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + switch_dial_handle_t *dh; + switch_dial_leg_list_t *ll; + switch_dial_leg_t *leg = NULL; + + switch_dial_handle_create(&dh); + 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, "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_pre_answer", "true"); + switch_dial_handle_add_global_var(dh, "group_confirm_early_ok", "false"); + + status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + switch_core_session_rwunlock(session); + + switch_dial_handle_destroy(&dh); + + fst_check_duration(3000, 500); + } + FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_exec_after_answer_ignore_early_media) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + switch_dial_handle_t *dh; + switch_dial_leg_list_t *ll; + switch_dial_leg_t *leg = NULL; + + switch_dial_handle_create(&dh); + 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, "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_pre_answer", "true"); + switch_dial_handle_add_global_var(dh, "ignore_early_media", "true"); + + status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + switch_core_session_rwunlock(session); + + switch_dial_handle_destroy(&dh); + + fst_check_duration(3000, 500); + } + FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_2_legs) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + switch_dial_handle_t *dh; + switch_dial_leg_list_t *ll; + switch_dial_leg_t *leg = NULL; + + switch_dial_handle_create(&dh); + switch_dial_handle_add_leg_list(dh, &ll); + + switch_dial_leg_list_add_leg(ll, &leg, "null/test1"); + 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_leg_list_add_leg(ll, &leg, "null/test2"); + switch_dial_handle_add_leg_var(leg, "group_confirm_file", "playback silence_stream://500"); + switch_dial_handle_add_leg_var(leg, "group_confirm_key", "exec"); + + status = switch_ivr_originate(NULL, &session, &cause, NULL, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + const char *name = switch_core_session_get_name(session); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "channel %s\n", name); + fst_check_string_equals(name, "null/test2"); + switch_core_session_rwunlock(session); + + switch_dial_handle_destroy(&dh); + } + FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_global_var) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + const char *dialstring = "{group_confirm_file='playback silence_stream://1000',group_confirm_key=exec}null/test"; + + status = switch_ivr_originate(NULL, &session, &cause, dialstring, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + const char *name = switch_core_session_get_name(session); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "channel %s\n", name); + fst_check_string_equals(name, "null/test"); + switch_core_session_rwunlock(session); + } + FST_TEST_END() + + FST_TEST_BEGIN(originate_test_group_confirm_local_var) + { + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + switch_status_t status; + switch_call_cause_t cause; + const char *dialstring = "[group_confirm_file='playback silence_stream://1000',group_confirm_key=exec]null/test1," + "[group_confirm_file='playback silence_stream://500',group_confirm_key=exec]null/test2"; + + status = switch_ivr_originate(NULL, &session, &cause, dialstring, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL); + fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_requires(session); + const char *name = switch_core_session_get_name(session); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "channel %s\n", name); + fst_check_string_equals(name, "null/test2"); + switch_core_session_rwunlock(session); + } + FST_TEST_END() } FST_SUITE_END() }