diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 1764c7b17e..c4d4e6d12b 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -290,6 +290,7 @@ SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, swi \param flag or'd list of flags to set */ SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flag); +SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag); /*! \brief Set given flag(s) on a given channel's bridge partner @@ -322,6 +323,7 @@ SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, sw \param flag flag to clear */ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag); +SWITCH_DECLARE(void) switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag); SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel, const char *file, const char *func, int line); diff --git a/src/switch_channel.c b/src/switch_channel.c index 710da181df..141a1d2f57 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -119,7 +119,7 @@ struct switch_channel { switch_core_session_t *session; switch_channel_state_t state; switch_channel_state_t running_state; - uint8_t flags[CF_FLAG_MAX]; + uint32_t flags[CF_FLAG_MAX]; uint8_t state_flags[CF_FLAG_MAX]; uint32_t private_flags; uint32_t app_flags; @@ -844,6 +844,20 @@ SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_c } } +SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag) +{ + switch_assert(channel); + switch_assert(channel->flag_mutex); + + switch_mutex_lock(channel->flag_mutex); + channel->flags[flag]++; + switch_mutex_unlock(channel->flag_mutex); + + if (flag == CF_OUTBOUND) { + switch_channel_set_variable(channel, "is_outbound", "true"); + } +} + SWITCH_DECLARE(void) switch_channel_set_private_flag(switch_channel_t *channel, uint32_t flags) { @@ -916,6 +930,22 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch } } + +SWITCH_DECLARE(void) switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag) +{ + switch_assert(channel != NULL); + switch_assert(channel->flag_mutex); + + switch_mutex_lock(channel->flag_mutex); + if (channel->flags[flag]) { + channel->flags[flag]--; + } + switch_mutex_unlock(channel->flag_mutex); + if (flag == CF_OUTBOUND) { + switch_channel_set_variable(channel, "is_outbound", NULL); + } +} + SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t *channel) { switch_channel_state_t state; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 176ddf034d..fa33ea1dec 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -470,10 +470,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se cmd_hash = switch_hashfunc_default(cmd, &hlen); - switch_channel_set_flag(channel, CF_EVENT_PARSE); + switch_channel_set_flag_recursive(channel, CF_EVENT_PARSE); if (switch_true(event_lock)) { - switch_channel_set_flag(channel, CF_EVENT_LOCK); + switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK); } if (lead_frames) { @@ -604,8 +604,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se status = SWITCH_STATUS_SUCCESS; done: - switch_channel_clear_flag(channel, CF_EVENT_PARSE); - switch_channel_clear_flag(channel, CF_EVENT_LOCK); + switch_channel_clear_flag_recursive(channel, CF_EVENT_PARSE); + switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK); return status; } diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index c5fd4d9fae..3f5fa5a94e 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -2311,6 +2311,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha char *cause = NULL; char *mypath; char *p; + int custom = 0; switch_assert(path); @@ -2320,29 +2321,28 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha channel = switch_core_session_get_channel(session); - if ((switch_channel_test_flag(channel, CF_EVENT_PARSE))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel [%s][%s] already broadcasting...broadcast aborted\n", - switch_channel_get_name(channel), path); - switch_core_session_rwunlock(session); - return SWITCH_STATUS_FALSE; - } - mypath = strdup(path); - - if (!mypath) { - switch_core_session_rwunlock(session); - return SWITCH_STATUS_MEMERR; - } - - if ((nomedia = switch_channel_test_flag(channel, CF_PROXY_MODE))) { - switch_ivr_media(uuid, SMF_REBRIDGE); - } + assert(mypath); if ((p = strchr(mypath, ':')) && *(p + 1) == ':') { app = mypath; *p++ = '\0'; *p++ = '\0'; path = p; + custom++; + } + + if (!custom && (switch_channel_test_flag(channel, CF_EVENT_PARSE))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel [%s][%s] already broadcasting...broadcast aborted\n", + switch_channel_get_name(channel), path); + switch_core_session_rwunlock(session); + switch_safe_free(mypath); + return SWITCH_STATUS_FALSE; + } + + + if ((nomedia = switch_channel_test_flag(channel, CF_PROXY_MODE))) { + switch_ivr_media(uuid, SMF_REBRIDGE); } if ((cause = strchr(app, '!'))) {