SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session);
-SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force);
/*!
\brief Provide the total number of sessions
SCF_VG = (1 << 3),
SCF_RESTART = (1 << 4),
SCF_SHUTDOWN_REQUESTED = (1 << 5),
- SCF_USE_AUTO_NAT = (1 << 6)
+ SCF_USE_AUTO_NAT = (1 << 6),
+ SCF_EARLY_HANGUP = (1 << 7)
} switch_core_flag_enum_t;
typedef uint32_t switch_core_flag_t;
CF_BYPASS_MEDIA_AFTER_BRIDGE,
CF_LEG_HOLDING,
CF_BROADCAST_DROP_MEDIA,
+ CF_EARLY_HANGUP,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
CF_FLAG_MAX
} switch_channel_flag_t;
switch_channel_set_flag(switch_core_session_get_channel(session), CF_VERBOSE_EVENTS);
}
+SWITCH_STANDARD_APP(early_hangup_function)
+{
+ switch_channel_set_flag(switch_core_session_get_channel(session), CF_EARLY_HANGUP);
+}
+
#define WAIT_FOR_SILENCE_SYNTAX "<silence_thresh> <silence_hits> <listen_hits> <timeout_ms> [<file>]"
SWITCH_STANDARD_APP(wait_for_silence_function)
{
SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function,
"<ip> <acl | cidr> [<hangup_cause>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
+ SWITCH_ADD_APP(app_interface, "early_hangup", "Enable early hangup", "", early_hangup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "strftime", "strftime", "strftime", strftime_function, "[<epoch>|]<format string>", SAF_SUPPORT_NOMEDIA);
case nua_callstate_completed:
case nua_callstate_received:
case nua_callstate_proceeding:
+ case nua_callstate_completing:
if (!(session && channel && tech_pvt)) goto done;
break;
default:
break;
case nua_callstate_completing:
nua_ack(nh,
- TAG_IF(tech_pvt && !zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+ TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_END());
- break;
+ goto done;
case nua_callstate_received:
if (!sofia_test_flag(tech_pvt, TFLAG_SDP)) {
if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
switch_core_session_kill_channel(channel->session, SWITCH_SIG_KILL);
switch_core_session_signal_state_change(channel->session);
- switch_core_session_hangup_state(channel->session);
+ switch_core_session_hangup_state(channel->session, SWITCH_FALSE);
}
return channel->state;
if (tmp > -1 && tmp < 11) {
switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
}
+ } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
+ switch_set_flag((&runtime), SCF_EARLY_HANGUP);
} else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
runtime.colorize_console = SWITCH_TRUE;
} else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {
goto done;
case CS_HANGUP: /* Deactivate and end the thread */
{
- switch_core_session_hangup_state(session);
+ switch_core_session_hangup_state(session, SWITCH_TRUE);
switch_channel_set_state(session->channel, CS_REPORTING);
}
}
-SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session)
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force)
{
const char *hook_var;
switch_core_session_t *use_session = NULL;
const switch_state_handler_table_t *driver_state_handler = NULL;
const switch_state_handler_table_t *application_state_handler = NULL;
+
+ if (!force) {
+ if (!switch_channel_test_flag(session->channel, CF_EARLY_HANGUP) && !switch_test_flag((&runtime), SCF_EARLY_HANGUP)) {
+ return;
+ }
- if (switch_thread_self() != session->thread_id) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s thread mismatch skipping state handler.\n",
- switch_channel_get_name(session->channel));
- return;
+ if (switch_thread_self() != session->thread_id) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s thread mismatch skipping state handler.\n",
+ switch_channel_get_name(session->channel));
+ return;
+ }
}
if (switch_test_flag(session, SSF_HANGUP)) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s handler already called, skipping state handler.\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s handler already called, skipping state handler.\n",
switch_channel_get_name(session->channel));
return;
}
sanity_check_noreturn;
this->begin_allow_threads();
if (switch_channel_down(channel)) {
- switch_core_session_hangup_state(session);
+ switch_core_session_hangup_state(session, SWITCH_FALSE);
}
this->end_allow_threads();
}