Add application flag zombie_exec so registered applications can apply to be executed on channels that are already hungup, like the inline exec this is only limited to a small family of apps that do not use the channel for audio.

This commit is contained in:
Anthony Minessale 2011-09-13 09:35:41 -05:00
parent 4c3a0eb357
commit 637a5ed83d
6 changed files with 65 additions and 21 deletions

View File

@ -1214,7 +1214,8 @@ typedef enum {
SAF_NONE = 0,
SAF_SUPPORT_NOMEDIA = (1 << 0),
SAF_ROUTING_EXEC = (1 << 1),
SAF_MEDIA_TAP = (1 << 2)
SAF_MEDIA_TAP = (1 << 2),
SAF_ZOMBIE_EXEC = (1 << 3)
} switch_application_flag_enum_t;
typedef uint32_t switch_application_flag_t;

View File

@ -622,8 +622,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_db_load)
/* register limit interfaces */
SWITCH_ADD_LIMIT(limit_interface, "db", limit_incr_db, limit_release_db, limit_usage_db, limit_reset_db, limit_status_db, NULL);
SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "db", "Insert to the db", DB_DESC, db_function, DB_USAGE, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "group", "Manage a group", GROUP_DESC, group_function, GROUP_USAGE, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
SWITCH_ADD_API(commands_api_interface, "db", "db get/set", db_api_function, "[insert|delete|select]/<realm>/<key>/<value>");
switch_console_set_complete("add db insert");
switch_console_set_complete("add db delete");

View File

@ -3916,7 +3916,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
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);
SWITCH_ADD_APP(app_interface, "phrase", "Say a Phrase", "Say a Phrase", phrase_function, "<macro_name>,<data>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "eval", "Do Nothing", "Do Nothing", eval_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "eval", "Do Nothing", "Do Nothing", eval_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "pre_answer", "Pre-Answer the call", "Pre-Answer the call for a channel.", pre_answer_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "answer", "Answer the call", "Answer the call for a channel.", answer_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "hangup", "Hangup the call", "Hangup the call for a channel.", hangup_function, "[<cause>]", SAF_SUPPORT_NOMEDIA);
@ -3924,29 +3924,29 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "presence", "Send Presence", "Send Presence.", presence_function, "<rpid> <status> [<id>]",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "log", "Logs to the logger", LOG_LONG_DESC, log_function, "<log_level> <log_string>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "info", "Display Call Info", "Display Call Info", info_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "event", "Fire an event", "Fire an event", event_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "info", "Display Call Info", "Display Call Info", info_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "event", "Fire an event", "Fire an event", event_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "sound_test", "Analyze Audio", "Analyze Audio", sound_test_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, export_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "bridge_export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, bridge_export_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "push", "Set a channel variable", SET_LONG_DESC, push_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "unshift", "Set a channel variable", SET_LONG_DESC, unshift_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "set_global", "Set a global variable", SET_GLOBAL_LONG_DESC, set_global_function, "<varname>=<value>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "set_profile_var", "Set a caller profile variable", SET_PROFILE_VAR_LONG_DESC, set_profile_var_function,
"<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
"<varname>=<value>", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "unset", "Unset a channel variable", UNSET_LONG_DESC, unset_function, "<varname>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "remove_bugs", "Remove media bugs", "Remove all media bugs from a channel.", remove_bugs_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);

View File

@ -945,7 +945,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_hash_load)
switch_scheduler_add_task(switch_epoch_time_now(NULL) + LIMIT_HASH_CLEANUP_INTERVAL, limit_hash_cleanup_callback, "limit_hash_cleanup", "mod_hash", 0, NULL,
SSHF_NONE);
SWITCH_ADD_APP(app_interface, "hash", "Insert into the hashtable", HASH_DESC, hash_function, HASH_USAGE, SAF_SUPPORT_NOMEDIA)
SWITCH_ADD_APP(app_interface, "hash", "Insert into the hashtable", HASH_DESC, hash_function, HASH_USAGE, SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC)
SWITCH_ADD_API(commands_api_interface, "hash", "hash get/set", hash_api_function, "[insert|delete|select]/<realm>/<key>/<value>");
SWITCH_ADD_API(commands_api_interface, "hash_dump", "dump hash/limit_hash data (used for synchronization)", hash_dump_function, HASH_DUMP_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "hash_remote", "hash remote", hash_remote_function, HASH_REMOTE_SYNTAX);

View File

@ -2025,15 +2025,37 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag
switch_application_interface_t *application_interface;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (!arg && strstr(app, "::")) {
return switch_core_session_execute_application_async(session, app, arg);
if (switch_channel_down(session->channel)) {
char *p;
if (!arg && (p = strstr(app, "::"))) {
*p++ = '0';
*p++ = '0';
arg = p;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s ASYNC CALL CONVERTED TO INLINE %s(%s)\n",
switch_channel_get_name(session->channel), app, switch_str_nil(arg));
}
if (switch_channel_down(session->channel)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is hungup, aborting execution of application: %s\n", app);
if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
return SWITCH_STATUS_FALSE;
}
if (switch_test_flag(application_interface, SAF_ZOMBIE_EXEC)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s ZOMBIE EXEC %s(%s)\n",
switch_channel_get_name(session->channel), app, switch_str_nil(arg));
goto exec;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
"%s Channel is hungup and application '%s' does not have the zombie_exec flag.\n",
switch_channel_get_name(session->channel), app);
return SWITCH_STATUS_FALSE;
}
if (!arg && strstr(app, "::")) {
return switch_core_session_execute_application_async(session, app, arg);
}
if ((application_interface = switch_loadable_module_get_application_interface(app)) == 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", app);
switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
@ -2079,6 +2101,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag
}
}
exec:
switch_core_session_exec(session, application_interface, arg);
done:

View File

@ -42,9 +42,28 @@ static void switch_core_standard_on_init(switch_core_session_t *session)
static void switch_core_standard_on_hangup(switch_core_session_t *session)
{
switch_caller_extension_t *extension;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard HANGUP, cause: %s\n",
switch_channel_get_name(session->channel), switch_channel_cause2str(switch_channel_get_cause(session->channel)));
if ((extension = switch_channel_get_caller_extension(session->channel)) == 0) {
return;
}
while(extension->current_application) {
switch_caller_application_t *current_application = extension->current_application;
extension->current_application = extension->current_application->next;
if (switch_core_session_execute_application(session,
current_application->application_name,
current_application->application_data) != SWITCH_STATUS_SUCCESS) {
return;
}
}
}
static void switch_core_standard_on_reporting(switch_core_session_t *session)