add digit_action_set_target app that can set the target (direction of the dtmf flow and subsequent channel who gets the events) to self or peer (bridged channel when possible)

This commit is contained in:
Anthony Minessale 2011-09-01 10:11:16 -05:00
parent 3a352e67f4
commit cf9859ea69
5 changed files with 107 additions and 16 deletions

View File

@ -718,6 +718,9 @@ SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *sessio
SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine);
SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session);
SWITCH_DECLARE(switch_digit_action_target_t) switch_ivr_dmachine_get_target(switch_ivr_dmachine_t *dmachine);
SWITCH_DECLARE(void) switch_ivr_dmachine_set_target(switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target);
SWITCH_DECLARE(switch_status_t) switch_core_session_set_codec_slin(switch_core_session_t *session, switch_slin_data_t *data);
/*!

View File

@ -221,6 +221,13 @@ typedef enum {
SWITCH_DTMF_APP
} switch_dtmf_source_t;
typedef enum {
DIGIT_TARGET_SELF,
DIGIT_TARGET_PEER
} switch_digit_action_target_t;
typedef enum {
DTMF_FLAG_SKIP_PROCESS = (1 << 0)
} dtmf_flag_t;

View File

@ -108,23 +108,33 @@ struct action_binding {
static switch_status_t digit_nomatch_action_callback(switch_ivr_dmachine_match_t *match)
{
switch_core_session_t *session = (switch_core_session_t *) match->user_data;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_t *channel;
char str[DMACHINE_MAX_DIGIT_LEN + 2];
switch_event_t *event;
switch_status_t status;
switch_core_session_t *use_session = session;
if (switch_ivr_dmachine_get_target(match->dmachine) == DIGIT_TARGET_PEER) {
if (switch_core_session_get_partner(session, &use_session) != SWITCH_STATUS_SUCCESS) {
use_session = session;
}
}
channel = switch_core_session_get_channel(use_session);
switch_channel_set_variable(channel, "last_non_matching_digits", match->match_digits);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Digit NOT match binding [%s]\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(use_session), SWITCH_LOG_DEBUG, "%s Digit NOT match binding [%s]\n",
switch_channel_get_name(channel), match->match_digits);
if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "digits", match->match_digits);
if ((status = switch_core_session_queue_event(session, &event)) != SWITCH_STATUS_SUCCESS) {
if ((status = switch_core_session_queue_event(use_session, &event)) != SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&event);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
switch_core_session_get_name(session));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(use_session), SWITCH_LOG_WARNING, "%s event queue failure.\n",
switch_core_session_get_name(use_session));
}
}
@ -133,6 +143,11 @@ static switch_status_t digit_nomatch_action_callback(switch_ivr_dmachine_match_t
switch_channel_queue_dtmf_string(channel, str);
if (use_session != session) {
switch_core_session_rwunlock(use_session);
}
return SWITCH_STATUS_SUCCESS;
}
@ -143,10 +158,20 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
switch_status_t status;
int exec = 0;
char *string = act->string;
switch_channel_t *channel = switch_core_session_get_channel(act->session);
switch_channel_t *channel;
switch_core_session_t *use_session = act->session;
if (switch_ivr_dmachine_get_target(match->dmachine) == DIGIT_TARGET_PEER) {
if (switch_core_session_get_partner(act->session, &use_session) != SWITCH_STATUS_SUCCESS) {
use_session = act->session;
}
}
channel = switch_core_session_get_channel(use_session);
switch_channel_set_variable(channel, "last_matching_digits", match->match_digits);
if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_DEBUG, "%s Digit match binding [%s][%s]\n",
switch_channel_get_name(channel), act->string, act->value);
@ -163,18 +188,24 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute", exec == 2 ? "non-blocking" : "blocking");
}
if ((status = switch_core_session_queue_event(act->session, &event)) != SWITCH_STATUS_SUCCESS) {
if ((status = switch_core_session_queue_event(use_session, &event)) != SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&event);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
switch_core_session_get_name(act->session));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(use_session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
switch_core_session_get_name(use_session));
}
}
if (exec) {
char *cmd = switch_core_session_sprintf(act->session, "%s::%s", string, act->value);
switch_ivr_broadcast_in_thread(act->session, cmd, SMF_ECHO_ALEG|SMF_HOLD_BLEG);
char *cmd = switch_core_session_sprintf(use_session, "%s::%s", string, act->value);
switch_ivr_broadcast_in_thread(use_session, cmd, SMF_ECHO_ALEG|SMF_HOLD_BLEG);
}
if (use_session != act->session) {
switch_core_session_rwunlock(use_session);
}
return SWITCH_STATUS_SUCCESS;
}
@ -212,6 +243,30 @@ SWITCH_STANDARD_APP(digit_action_set_realm_function)
}
#define DIGIT_ACTION_SET_TARGET_USAGE "<target>"
SWITCH_STANDARD_APP(digit_action_set_target_function)
{
switch_ivr_dmachine_t *dmachine;
char *target_str = (char *) data;
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", DIGIT_ACTION_SET_TARGET_USAGE);
return;
}
if ((dmachine = switch_core_session_get_dmachine(session))) {
switch_digit_action_target_t target = DIGIT_TARGET_SELF;
if (!strcasecmp(target_str, "peer")) {
target = DIGIT_TARGET_PEER;
}
switch_ivr_dmachine_set_target(dmachine, target);
}
}
#define BIND_DIGIT_ACTION_USAGE "<realm>,<digits|~regex>,<string>,<value>"
SWITCH_STANDARD_APP(bind_digit_action_function)
{
@ -219,7 +274,7 @@ SWITCH_STANDARD_APP(bind_digit_action_function)
switch_ivr_dmachine_t *dmachine;
char *mydata;
int argc = 0;
char *argv[4] = { 0 };
char *argv[5] = { 0 };
struct action_binding *act;
if (zstr(data)) {
@ -3789,6 +3844,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "digit_action_set_realm", "change binding realm", "",
digit_action_set_realm_function, DIGIT_ACTION_SET_REALM_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "digit_action_set_target", "change binding target", "",
digit_action_set_target_function, DIGIT_ACTION_SET_TARGET_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number",
SAF_SUPPORT_NOMEDIA);

View File

@ -1295,7 +1295,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio
}
if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)) {
if (session->dmachine && !switch_channel_test_flag(session->channel, CF_BROADCAST)) {
if (session->dmachine && switch_ivr_dmachine_get_target(session->dmachine) == DIGIT_TARGET_SELF &&
!switch_channel_test_flag(session->channel, CF_BROADCAST)) {
char str[2] = { dtmf->digit, '\0' };
switch_ivr_dmachine_feed(session->dmachine, str, NULL);
fed = 1;
@ -1344,6 +1345,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf(switch_core_sessio
}
}
if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)) {
if (session->dmachine && switch_ivr_dmachine_get_target(session->dmachine) == DIGIT_TARGET_PEER &&
!switch_channel_test_flag(session->channel, CF_BROADCAST)) {
char str[2] = { new_dtmf.digit, '\0' };
switch_ivr_dmachine_feed(session->dmachine, str, NULL);
return SWITCH_STATUS_SUCCESS;
}
}
if (session->endpoint_interface->io_routines->send_dtmf) {
int send = 0;
status = SWITCH_STATUS_SUCCESS;

View File

@ -59,6 +59,7 @@ struct switch_ivr_dmachine {
uint32_t input_timeout_ms;
switch_hash_t *binding_hash;
switch_ivr_dmachine_match_t match;
switch_digit_action_target_t target;
char digits[DMACHINE_MAX_DIGIT_LEN];
char last_matching_digits[DMACHINE_MAX_DIGIT_LEN];
char last_failed_digits[DMACHINE_MAX_DIGIT_LEN];
@ -74,6 +75,17 @@ struct switch_ivr_dmachine {
};
SWITCH_DECLARE(switch_digit_action_target_t) switch_ivr_dmachine_get_target(switch_ivr_dmachine_t *dmachine)
{
return dmachine->target;
}
SWITCH_DECLARE(void) switch_ivr_dmachine_set_target(switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target)
{
dmachine->target = target;
}
SWITCH_DECLARE(void) switch_ivr_dmachine_set_match_callback(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_callback_t match_callback)
{