From 6e7d44af425b7b849715287655abe42eecde891c Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthm@freeswitch.org> Date: Wed, 14 Dec 2011 13:23:54 -0600 Subject: [PATCH] FS-3764 --resolve --- src/include/switch_core.h | 14 +++++- src/include/switch_types.h | 45 +++++++++++-------- .../applications/mod_commands/mod_commands.c | 39 ++++++++++++++-- src/mod/endpoints/mod_sofia/sofia.c | 5 ++- src/switch_core.c | 37 +++++++++++++-- src/switch_core_session.c | 11 +++++ 6 files changed, 122 insertions(+), 29 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index e38d4aba7c..9d0893565f 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -25,7 +25,7 @@ * * Anthony Minessale II <anthm@freeswitch.org> * Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC) - * + * Joseph Sullivan <jossulli@amazon.com> * * switch_core.h -- Core Library * @@ -1955,6 +1955,18 @@ SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel); */ SWITCH_DECLARE(switch_bool_t) switch_core_ready(void); +/*! + \brief Determines if the core is ready to take inbound calls + \return SWITCH_TRUE or SWITCH_FALSE +*/ +SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void); + +/*! + \brief Determines if the core is ready to place outbound calls + \return SWITCH_TRUE or SWITCH_FALSE +*/ +SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void); + /*! \brief return core flags \return core flags diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 351de2213f..2ab4c07984 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -25,6 +25,7 @@ * * Anthony Minessale II <anthm@freeswitch.org> * Bret McDanel <trixter AT 0xdecafbad dot com> + * Joseph Sullivan <jossulli@amazon.com> * * switch_types.h -- Data Types * @@ -293,25 +294,27 @@ typedef uint32_t switch_eavesdrop_flag_t; typedef enum { SCF_NONE = 0, SCF_USE_SQL = (1 << 0), - SCF_NO_NEW_SESSIONS = (1 << 1), - SCF_SHUTTING_DOWN = (1 << 2), - SCF_VG = (1 << 3), - SCF_RESTART = (1 << 4), - SCF_SHUTDOWN_REQUESTED = (1 << 5), - SCF_USE_AUTO_NAT = (1 << 6), - SCF_EARLY_HANGUP = (1 << 7), - SCF_CALIBRATE_CLOCK = (1 << 8), - SCF_USE_HEAVY_TIMING = (1 << 9), - SCF_USE_CLOCK_RT = (1 << 10), - SCF_VERBOSE_EVENTS = (1 << 11), - SCF_USE_WIN32_MONOTONIC = (1 << 12), - SCF_AUTO_SCHEMAS = (1 << 13), - SCF_MINIMAL = (1 << 14), - SCF_USE_NAT_MAPPING = (1 << 15), - SCF_CLEAR_SQL = (1 << 16), - SCF_THREADED_SYSTEM_EXEC = (1 << 17), - SCF_SYNC_CLOCK_REQUESTED = (1 << 18), - SCF_CORE_ODBC_REQ = (1 << 19) + SCF_NO_NEW_OUTBOUND_SESSIONS = (1 << 1), + SCF_NO_NEW_INBOUND_SESSIONS = (1 << 2), + SCF_NO_NEW_SESSIONS = (SCF_NO_NEW_OUTBOUND_SESSIONS | SCF_NO_NEW_INBOUND_SESSIONS), + SCF_SHUTTING_DOWN = (1 << 3), + SCF_VG = (1 << 4), + SCF_RESTART = (1 << 5), + SCF_SHUTDOWN_REQUESTED = (1 << 6), + SCF_USE_AUTO_NAT = (1 << 7), + SCF_EARLY_HANGUP = (1 << 8), + SCF_CALIBRATE_CLOCK = (1 << 9), + SCF_USE_HEAVY_TIMING = (1 << 10), + SCF_USE_CLOCK_RT = (1 << 11), + SCF_VERBOSE_EVENTS = (1 << 12), + SCF_USE_WIN32_MONOTONIC = (1 << 13), + SCF_AUTO_SCHEMAS = (1 << 14), + SCF_MINIMAL = (1 << 15), + SCF_USE_NAT_MAPPING = (1 << 16), + SCF_CLEAR_SQL = (1 << 17), + SCF_THREADED_SYSTEM_EXEC = (1 << 18), + SCF_SYNC_CLOCK_REQUESTED = (1 << 19), + SCF_CORE_ODBC_REQ = (1 << 20) } switch_core_flag_enum_t; typedef uint32_t switch_core_flag_t; @@ -1689,6 +1692,8 @@ typedef enum { typedef enum { SCSC_PAUSE_INBOUND, + SCSC_PAUSE_OUTBOUND, + SCSC_PAUSE_ALL, SCSC_HUPALL, SCSC_SHUTDOWN, SCSC_CHECK_RUNNING, @@ -1714,6 +1719,8 @@ typedef enum { SCSC_MIN_IDLE_CPU, SCSC_VERBOSE_EVENTS, SCSC_SHUTDOWN_CHECK, + SCSC_PAUSE_INBOUND_CHECK, + SCSC_PAUSE_OUTBOUND_CHECK, SCSC_PAUSE_CHECK, SCSC_READY_CHECK, SCSC_THREADED_SYSTEM_EXEC, diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index cffe756ad2..dac0de9a55 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -32,6 +32,7 @@ * Cesar Cepeda <cesar@auronix.com> * Massimo Cetra <devel@navynet.it> * Rupa Schomaker <rupa@rupa.com> + * Joseph Sullivan <jossulli@amazon.com> * * * mod_commands.c -- Misc. Command Module @@ -1792,7 +1793,7 @@ SWITCH_STANDARD_API(status_function) return SWITCH_STATUS_SUCCESS; } -#define CTL_SYNTAX "[send_sighup|hupall|pause|resume|shutdown [cancel|elegant|asap|now|restart]|sps|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]]" +#define CTL_SYNTAX "[send_sighup|hupall|pause [inbound|outbound]|resume [inbound|outbound]|shutdown [cancel|elegant|asap|now|restart]|sps|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]]" SWITCH_STANDARD_API(ctl_function) { int argc; @@ -1815,16 +1816,32 @@ SWITCH_STANDARD_API(ctl_function) switch_core_session_ctl(SCSC_FLUSH_DB_HANDLES, NULL); stream->write_function(stream, "+OK\n"); } else if (!strcasecmp(argv[0], "pause")) { + switch_session_ctl_t command = SCSC_PAUSE_ALL; arg = 1; - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg); + if (argv[1]) { + if (!strcasecmp(argv[1], "inbound")) { + command = SCSC_PAUSE_INBOUND; + } else if (!strcasecmp(argv[1], "outbound")) { + command = SCSC_PAUSE_OUTBOUND; + } + } + switch_core_session_ctl(command, &arg); stream->write_function(stream, "+OK\n"); } else if (!strcasecmp(argv[0], "send_sighup")) { arg = 1; switch_core_session_ctl(SCSC_SEND_SIGHUP, &arg); stream->write_function(stream, "+OK\n"); } else if (!strcasecmp(argv[0], "resume")) { + switch_session_ctl_t command = SCSC_PAUSE_ALL; arg = 0; - switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg); + if (argv[1]) { + if (!strcasecmp(argv[1], "inbound")) { + command = SCSC_PAUSE_INBOUND; + } else if (!strcasecmp(argv[1], "outbound")) { + command = SCSC_PAUSE_OUTBOUND; + } + } + switch_core_session_ctl(command, &arg); stream->write_function(stream, "+OK\n"); } else if (!strcasecmp(argv[0], "calibrate_clock")) { switch_core_session_ctl(SCSC_CALIBRATE_CLOCK, NULL); @@ -1855,7 +1872,15 @@ SWITCH_STANDARD_API(ctl_function) switch_core_session_ctl(SCSC_SAVE_HISTORY, NULL); stream->write_function(stream, "+OK\n"); } else if (!strcasecmp(argv[0], "pause_check")) { - switch_core_session_ctl(SCSC_PAUSE_CHECK, &arg); + switch_session_ctl_t command = SCSC_PAUSE_CHECK; + if (argv[1]) { + if (!strcasecmp(argv[1], "inbound")) { + command = SCSC_PAUSE_INBOUND_CHECK; + } else if (!strcasecmp(argv[1], "outbound")) { + command = SCSC_PAUSE_OUTBOUND_CHECK; + } + } + switch_core_session_ctl(command, &arg); stream->write_function(stream, arg ? "true" : "false"); } else if (!strcasecmp(argv[0], "ready_check")) { switch_core_session_ctl(SCSC_READY_CHECK, &arg); @@ -5431,13 +5456,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add fsctl max_sessions"); switch_console_set_complete("add fsctl min_dtmf_duration"); switch_console_set_complete("add fsctl pause"); + switch_console_set_complete("add fsctl pause inbound"); + switch_console_set_complete("add fsctl pause outbound"); switch_console_set_complete("add fsctl reclaim_mem"); switch_console_set_complete("add fsctl resume"); + switch_console_set_complete("add fsctl resume inbound"); + switch_console_set_complete("add fsctl resume outbound"); switch_console_set_complete("add fsctl calibrate_clock"); switch_console_set_complete("add fsctl crash"); switch_console_set_complete("add fsctl verbose_events"); switch_console_set_complete("add fsctl save_history"); switch_console_set_complete("add fsctl pause_check"); + switch_console_set_complete("add fsctl pause_check inbound"); + switch_console_set_complete("add fsctl pause_check outbound"); switch_console_set_complete("add fsctl ready_check"); switch_console_set_complete("add fsctl shutdown_check"); switch_console_set_complete("add fsctl shutdown"); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 9208e3a625..f934c4eea4 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -31,6 +31,7 @@ * Norman Brandinger * Raymond Chandler <intralanman@gmail.com> * Nathan Patrick <npatrick at corp.sonic.net> + * Joseph Sullivan <jossulli@amazon.com> * * * sofia.c -- SOFIA SIP Endpoint (sofia code) @@ -936,7 +937,7 @@ static void our_sofia_event_callback(nua_event_t event, uint32_t sess_count = switch_core_session_count(); uint32_t sess_max = switch_core_session_limit(0); - if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready()) { + if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready_inbound()) { nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END()); //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No more sessions allowed at this time.\n"); @@ -8351,7 +8352,7 @@ void sofia_handle_sip_i_options(int status, uint32_t sess_max = switch_core_session_limit(0); if (sofia_test_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY) && - (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready())) { + (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready_inbound())) { nua_respond(nh, 503, "Maximum Calls In Progress", NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_RETRY_AFTER_STR("300"), TAG_END()); } else { nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); diff --git a/src/switch_core.c b/src/switch_core.c index 4d00122b37..e07616d132 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -27,6 +27,7 @@ * Michael Jerris <mike@jerris.com> * Paul D. Tinsley <pdt at jackhammer.org> * Marcel Barbulescu <marcelbarbulescu@gmail.com> + * Joseph Sullivan <jossulli@amazon.com> * * * switch_core.c -- Main Core Library @@ -2000,13 +2001,27 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void * case SCSC_SYNC_CLOCK_WHEN_IDLE: newintval = switch_core_session_sync_clock(); break; - case SCSC_PAUSE_INBOUND: + case SCSC_PAUSE_ALL: if (oldintval) { switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); } else { switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); } break; + case SCSC_PAUSE_INBOUND: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + } + break; + case SCSC_PAUSE_OUTBOUND: + if (oldintval) { + switch_set_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + } else { + switch_clear_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); + } + break; case SCSC_HUPALL: switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST); break; @@ -2069,7 +2084,13 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void * } break; case SCSC_PAUSE_CHECK: - newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS); + newintval = !!(switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS); + break; + case SCSC_PAUSE_INBOUND_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS); + break; + case SCSC_PAUSE_OUTBOUND_CHECK: + newintval = !!switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS); break; case SCSC_READY_CHECK: newintval = switch_core_ready(); @@ -2169,7 +2190,17 @@ SWITCH_DECLARE(switch_core_flag_t) switch_core_flags(void) SWITCH_DECLARE(switch_bool_t) switch_core_ready(void) { - return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_SESSIONS) == SCF_NO_NEW_SESSIONS) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready_inbound(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_INBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_ready_outbound(void) +{ + return (switch_test_flag((&runtime), SCF_SHUTTING_DOWN) || switch_test_flag((&runtime), SCF_NO_NEW_OUTBOUND_SESSIONS)) ? SWITCH_FALSE : SWITCH_TRUE; } SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 1b27ad5e12..8f72afc893 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -26,6 +26,7 @@ * Anthony Minessale II <anthm@freeswitch.org> * Michael Jerris <mike@jerris.com> * Paul D. Tinsley <pdt at jackhammer.org> + * Joseph Sullivan <jossulli@amazon.com> * * * switch_core_session.c -- Main Core Library (session routines) @@ -1781,6 +1782,16 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ return NULL; } + if (direction == SWITCH_CALL_DIRECTION_INBOUND && !switch_core_ready_inbound()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any inbound sessions at this time.\n"); + return NULL; + } + + if (direction == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_core_ready_outbound()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any outbound sessions at this time.\n"); + return NULL; + } + if (!switch_core_ready() || endpoint_interface == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any sessions at this time.\n"); return NULL;