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
{
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;
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;
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 {
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
}
for (i = 0; i < x_argc; i++) {
+
+ if (channel) {
+ switch_channel_handle_cause(channel, handles[i].cause);
+ }
+
if (hp == &handles[i]) {
continue;
}
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;
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")) {
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;
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);
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;