]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add digit_action_set_target app that can set the target (direction of the dtmf flow...
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 1 Sep 2011 15:11:16 +0000 (10:11 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 1 Sep 2011 15:11:24 +0000 (10:11 -0500)
src/include/switch_core.h
src/include/switch_types.h
src/mod/applications/mod_dptools/mod_dptools.c
src/switch_core_io.c
src/switch_ivr_async.c

index 8d4a0cd1221dbc9d28964d3c036c7ef23145863f..f6e611b91fb3685593b16dc82d677a71e474445f 100644 (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);
 
 /*! 
index 783b48e3b15f76cc850d9a0ba9c5e6da7e547c18..7eb27d2c45542ddc5c01f53f6381f47958b2ad9a 100644 (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;
index 271421a9d325af24322f262fef8fdde0c28c20bf..02c64d809306a6554ac56065097921315ef81554 100755 (executable)
@@ -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,9 +158,19 @@ 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", 
@@ -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)) {
@@ -266,7 +321,7 @@ SWITCH_STANDARD_APP(bind_digit_action_function)
        act->string = argv[2];
        act->value = argv[3];
        act->session = session;
-       
+
        switch_ivr_dmachine_bind(dmachine, act->realm, act->input, 0, digit_action_callback, act);
 }
 
@@ -3788,6 +3843,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",
index 100d8bf9f6dc7e164b09eb14d9f872e56557a067..3a30cdaf74fe8a979f4b18fc10e89199e9492815 100644 (file)
@@ -1293,9 +1293,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio
        } else if (!new_dtmf.duration) {
                new_dtmf.duration = switch_core_default_dtmf_duration(0);
        }
-
+       
        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;
@@ -1337,13 +1338,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf(switch_core_sessio
                new_dtmf.duration = switch_core_default_dtmf_duration(0);
        }
 
-
+       
        for (ptr = session->event_hooks.send_dtmf; ptr; ptr = ptr->next) {
                if ((status = ptr->send_dtmf(session, dtmf, SWITCH_DTMF_SEND)) != SWITCH_STATUS_SUCCESS) {
                        return SWITCH_STATUS_SUCCESS;
                }
        }
 
+       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;
index 7eeb1404e5e4524497159edb4f54fe2ddb7cbb26..fe8d9ddb1b007aba98cf94d6bb5400c417bfa013 100644 (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)
 {