]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-5402 --resolve the problem is ent originate has many channels and many causes...
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 22 May 2013 16:01:39 +0000 (11:01 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Wed, 22 May 2013 16:01:59 +0000 (11:01 -0500)
src/include/switch_channel.h
src/mod/applications/mod_dptools/mod_dptools.c
src/switch_channel.c
src/switch_ivr_originate.c

index f7ace52676811ef405d694a6029a7634cad79d75..219663b0e08e5fc0fcd8a32b61a645f4769ffc1f 100644 (file)
@@ -658,7 +658,7 @@ SWITCH_DECLARE(switch_hold_record_t *) switch_channel_get_hold_record(switch_cha
 SWITCH_DECLARE(void) switch_channel_state_thread_lock(switch_channel_t *channel);
 SWITCH_DECLARE(void) switch_channel_state_thread_unlock(switch_channel_t *channel);
 SWITCH_DECLARE(switch_status_t) switch_channel_state_thread_trylock(switch_channel_t *channel);
-
+SWITCH_DECLARE(void) switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause);
 
 SWITCH_END_EXTERN_C
 #endif
index 5818bd0752b12c4584591afa3e0142ba14181db2..52c94633bf1ad164d0e42fd6129fad0fc47ba154 100755 (executable)
@@ -2933,11 +2933,6 @@ SWITCH_STANDARD_APP(audio_bridge_function)
 {
        switch_channel_t *caller_channel = switch_core_session_get_channel(session);
        switch_core_session_t *peer_session = NULL;
-       
-       const char *transfer_on_fail = NULL;
-       char *tof_data = NULL;
-       char *tof_array[4] = { 0 };
-       //int tof_arrayc = 0;
        const char *v_campon = NULL, *v_campon_retries, *v_campon_sleep, *v_campon_timeout, *v_campon_fallback_exten = NULL;
        switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
        int campon_retries = 100, campon_timeout = 10, campon_sleep = 10, tmp, camping = 0, fail = 0, thread_started = 0;
@@ -2953,11 +2948,6 @@ SWITCH_STANDARD_APP(audio_bridge_function)
                return;
        }
 
-       transfer_on_fail = switch_channel_get_variable(caller_channel, "transfer_on_fail");
-       tof_data = switch_core_session_strdup(session, transfer_on_fail);
-       switch_split(tof_data, ' ', tof_array);
-       transfer_on_fail = tof_array[0];
-       
        if ((v_campon = switch_channel_get_variable(caller_channel, "campon")) && switch_true(v_campon)) {
                const char *cid_name = NULL;
                const char *cid_number = NULL;
@@ -3105,126 +3095,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
        if (fail) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed.  Cause: %s\n", switch_channel_cause2str(cause));
 
-               /* 
-                  if the variable continue_on_fail is set it can be:
-                  'true' to continue on all failures.
-                  'false' to not continue.
-                  A list of codes either names or numbers eg "user_busy,normal_temporary_failure,603"
-                  failure_causes acts as the opposite version  
-                  EXCEPTION... ATTENDED_TRANSFER never is a reason to continue.......
-                */
-               if (cause != SWITCH_CAUSE_ATTENDED_TRANSFER) {
-                       const char *continue_on_fail = NULL, *failure_causes = NULL;
-
-                       continue_on_fail = switch_channel_get_variable(caller_channel, "continue_on_fail");
-                       failure_causes = switch_channel_get_variable(caller_channel, "failure_causes");
-
-                       if (continue_on_fail || failure_causes) {
-                               const char *cause_str;
-                               char cause_num[35] = "";
-
-                               cause_str = switch_channel_cause2str(cause);
-                               switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
-
-                               if (failure_causes) {
-                                       char *lbuf = switch_core_session_strdup(session, failure_causes);
-                                       char *argv[256] = { 0 };
-                                       int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
-                                       int i, x = 0;
-
-                                       for (i = 0; i < argc; i++) {
-                                               if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
-                                                       x++;
-                                                       break;
-                                               }
-                                       }
-                                       if (!x) {
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
-                                                                                 "Failure causes [%s]:  Cause: %s\n", failure_causes, cause_str);
-                                               return;
-                                       }
-                               }
-
-                               if (continue_on_fail) {
-                                       if (switch_true(continue_on_fail)) {
-                                               return;
-                                       } else {
-                                               char *lbuf = switch_core_session_strdup(session, continue_on_fail);
-                                               char *argv[256] = { 0 };
-                                               int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
-                                               int i;
-
-                                               for (i = 0; i < argc; i++) {
-                                                       if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
-                                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
-                                                                                                 "Continue on fail [%s]:  Cause: %s\n", continue_on_fail, cause_str);
-                                                               return;
-                                                       }
-                                               }
-                                       }
-                               }
-                       } else {
-                               /* no answer is *always* a reason to continue */
-                               if (cause == SWITCH_CAUSE_NO_ANSWER || cause == SWITCH_CAUSE_NO_USER_RESPONSE || cause == SWITCH_CAUSE_ORIGINATOR_CANCEL) {
-                                       return;
-                               }
-                       }
-                       
-                       if (transfer_on_fail || failure_causes) {
-                               const char *cause_str;
-                               char cause_num[35] = "";
-
-                               cause_str = switch_channel_cause2str(cause);
-                               switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
-
-                               if ((tof_array[1] == NULL ) || (!strcasecmp(tof_array[1], "auto_cause"))){
-                                       tof_array[1] = (char *) cause_str;
-                               }
-
-                               if (failure_causes) {
-                                       char *lbuf = switch_core_session_strdup(session, failure_causes);
-                                       char *argv[256] = { 0 };
-                                       int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
-                                       int i, x = 0;
-
-                                       for (i = 0; i < argc; i++) {
-                                               if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
-                                                       x++;
-                                                       break;
-                                               }
-                                       }
-                                       if (!x) {
-                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
-                                                                                 "Failure causes [%s]:  Cause: %s\n", failure_causes, cause_str);
-                                                                                 
-                                               switch_ivr_session_transfer(session, tof_array[1], tof_array[2], tof_array[3]);
-                                       }
-                               }
-
-                               if (transfer_on_fail) {
-                                       if (switch_true(transfer_on_fail)) {
-                                               return;
-                                       } else {
-                                               char *lbuf = switch_core_session_strdup(session, transfer_on_fail);
-                                               char *argv[256] = { 0 };
-                                               int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
-                                               int i;
-
-                                               for (i = 0; i < argc; i++) {
-                                                       if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
-                                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
-                                                                                                 "Transfer on fail [%s]:  Cause: %s\n", transfer_on_fail, cause_str);
-                                                               switch_ivr_session_transfer(session, tof_array[1], tof_array[2], tof_array[3]);
-                                                       }
-                                               }
-                                       }
-                               }
-                       } 
-               }
-               if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_CONFIRM_BLIND_TRANSFER) && 
-                       switch_channel_get_state(caller_channel) != CS_ROUTING) {
-                       switch_channel_hangup(caller_channel, cause);
-               }
+               switch_channel_handle_cause(caller_channel, cause);
                return;
        } else {
 
index 9f83d841770b8003bd0545f0748a5a8b06c8e607..e477bffa579a0949d4e8d502cc3a45b381e660b4 100644 (file)
@@ -4386,6 +4386,148 @@ SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *c
        return uuid;
 }
 
+SWITCH_DECLARE(void) switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)
+{
+       switch_core_session_t *session = channel->session;
+       const char *transfer_on_fail = NULL;
+       char *tof_data = NULL;
+       char *tof_array[4] = { 0 };
+       //int tof_arrayc = 0;
+
+       if (!switch_channel_up_nosig(channel)) {
+               return;
+       }
+
+       transfer_on_fail = switch_channel_get_variable(channel, "transfer_on_fail");
+       tof_data = switch_core_session_strdup(session, transfer_on_fail);
+       switch_split(tof_data, ' ', tof_array);
+       transfer_on_fail = tof_array[0];
+
+       /* 
+          if the variable continue_on_fail is set it can be:
+          'true' to continue on all failures.
+          'false' to not continue.
+          A list of codes either names or numbers eg "user_busy,normal_temporary_failure,603"
+          failure_causes acts as the opposite version  
+          EXCEPTION... ATTENDED_TRANSFER never is a reason to continue.......
+       */
+       if (cause != SWITCH_CAUSE_ATTENDED_TRANSFER) {
+               const char *continue_on_fail = NULL, *failure_causes = NULL;
+
+               continue_on_fail = switch_channel_get_variable(channel, "continue_on_fail");
+               failure_causes = switch_channel_get_variable(channel, "failure_causes");
+
+               if (continue_on_fail || failure_causes) {
+                       const char *cause_str;
+                       char cause_num[35] = "";
+
+                       cause_str = switch_channel_cause2str(cause);
+                       switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
+
+                       if (failure_causes) {
+                               char *lbuf = switch_core_session_strdup(session, failure_causes);
+                               char *argv[256] = { 0 };
+                               int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
+                               int i, x = 0;
+
+                               for (i = 0; i < argc; i++) {
+                                       if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
+                                               x++;
+                                               break;
+                                       }
+                               }
+                               if (!x) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                                         "Failure causes [%s]:  Cause: %s\n", failure_causes, cause_str);
+                                       return;
+                               }
+                       }
+
+                       if (continue_on_fail) {
+                               if (switch_true(continue_on_fail)) {
+                                       return;
+                               } else {
+                                       char *lbuf = switch_core_session_strdup(session, continue_on_fail);
+                                       char *argv[256] = { 0 };
+                                       int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
+                                       int i;
+
+                                       for (i = 0; i < argc; i++) {
+                                               if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
+                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                                                         "Continue on fail [%s]:  Cause: %s\n", continue_on_fail, cause_str);
+                                                       return;
+                                               }
+                                       }
+                               }
+                       }
+               } else {
+                       /* no answer is *always* a reason to continue */
+                       if (cause == SWITCH_CAUSE_NO_ANSWER || cause == SWITCH_CAUSE_NO_USER_RESPONSE || cause == SWITCH_CAUSE_ORIGINATOR_CANCEL) {
+                               return;
+                       }
+               }
+                       
+               if (transfer_on_fail || failure_causes) {
+                       const char *cause_str;
+                       char cause_num[35] = "";
+
+                       cause_str = switch_channel_cause2str(cause);
+                       switch_snprintf(cause_num, sizeof(cause_num), "%u", cause);
+
+                       if ((tof_array[1] == NULL ) || (!strcasecmp(tof_array[1], "auto_cause"))){
+                               tof_array[1] = (char *) cause_str;
+                       }
+
+                       if (failure_causes) {
+                               char *lbuf = switch_core_session_strdup(session, failure_causes);
+                               char *argv[256] = { 0 };
+                               int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
+                               int i, x = 0;
+
+                               for (i = 0; i < argc; i++) {
+                                       if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
+                                               x++;
+                                               break;
+                                       }
+                               }
+                               if (!x) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                                         "Failure causes [%s]:  Cause: %s\n", failure_causes, cause_str);
+                                                                                 
+                                       switch_ivr_session_transfer(session, tof_array[1], tof_array[2], tof_array[3]);
+                               }
+                       }
+
+                       if (transfer_on_fail) {
+                               if (switch_true(transfer_on_fail)) {
+                                       return;
+                               } else {
+                                       char *lbuf = switch_core_session_strdup(session, transfer_on_fail);
+                                       char *argv[256] = { 0 };
+                                       int argc = switch_separate_string(lbuf, ',', argv, (sizeof(argv) / sizeof(argv[0])));
+                                       int i;
+
+                                       for (i = 0; i < argc; i++) {
+                                               if (!strcasecmp(argv[i], cause_str) || !strcasecmp(argv[i], cause_num)) {
+                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+                                                                                         "Transfer on fail [%s]:  Cause: %s\n", transfer_on_fail, cause_str);
+                                                       switch_ivr_session_transfer(session, tof_array[1], tof_array[2], tof_array[3]);
+                                               }
+                                       }
+                               }
+                       }
+               } 
+       }
+
+
+       if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_CONFIRM_BLIND_TRANSFER) && 
+               switch_channel_get_state(channel) != CS_ROUTING) {
+               switch_channel_hangup(channel, cause);
+       }
+}
+
+
 /* For Emacs:
  * Local Variables:
  * mode:c
index 13896f7b134047345cd99dba0f3beedeed9358a6..d1b587479592ffcd1e4a53dd81f510e1de0df236 100644 (file)
@@ -1644,6 +1644,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess
        }
 
        for (i = 0; i < x_argc; i++) {
+
+               if (channel) {
+                       switch_channel_handle_cause(channel, handles[i].cause);
+               }
+
                if (hp == &handles[i]) {
                        continue;
                }
@@ -1861,6 +1866,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
        const char *ringback_data = NULL;
        switch_event_t *var_event = NULL;
        int8_t fail_on_single_reject = 0;
+       int8_t hangup_on_single_reject = 0;
        char *fail_on_single_reject_var = NULL;
        char *loop_data = NULL;
        uint32_t progress_timelimit_sec = 0;
@@ -2119,6 +2125,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
                                        ok = 1;
                                } else if (!strcasecmp((char *) hi->name, "fail_on_single_reject")) {
                                        ok = 1;
+                               } else if (!strcasecmp((char *) hi->name, "hangup_on_single_reject")) {
+                                       ok = 1;
                                } else if (!strcasecmp((char *) hi->name, "ignore_early_media")) {
                                        ok = 1;
                                } else if (!strcasecmp((char *) hi->name, "bridge_early_media")) {
@@ -2216,7 +2224,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
           If the value is set to 'true' any fail cause will end the attempt otherwise it can contain a comma (,) separated
           list of cause names which should be considered fatal
         */
-       if ((var = switch_event_get_header(var_event, "fail_on_single_reject"))) {
+       if ((var = switch_event_get_header(var_event, "hangup_on_single_reject"))) {
+               hangup_on_single_reject = 1;
+       }
+
+       if (hangup_on_single_reject || (var = switch_event_get_header(var_event, "fail_on_single_reject"))) {
                fail_on_single_reject_var = strdup(var);
                if (switch_true(var)) {
                        fail_on_single_reject = 1;
@@ -3807,6 +3819,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
        switch_safe_free(write_frame.data);
        switch_safe_free(fail_on_single_reject_var);
 
+       if (force_reason != SWITCH_CAUSE_NONE) {
+               *cause = force_reason;
+       }
+
        if (caller_channel) {
 
                switch_channel_execute_on(caller_channel, SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE);
@@ -3814,12 +3830,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
 
                switch_channel_clear_flag(caller_channel, CF_ORIGINATOR);
                switch_channel_clear_flag(caller_channel, CF_XFER_ZOMBIE);
-       }
 
-       if (force_reason != SWITCH_CAUSE_NONE) {
-               *cause = force_reason;
+               if (hangup_on_single_reject) {
+                       switch_channel_hangup(caller_channel, *cause);
+               }
        }
 
+
        switch_core_destroy_memory_pool(&oglobals.pool);
 
        return status;