summaryrefslogtreecommitdiff
path: root/res/res_agi.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2013-10-08 15:12:46 +0000
committerRichard Mudgett <rmudgett@digium.com>2013-10-08 15:12:46 +0000
commit8eec8fbf8396848500edad3f52ab7a7cea2ef4c4 (patch)
treef8ba39e0291fdb3d365afe8b056d05db201c144a /res/res_agi.c
parent96d27333d2f2629565932b7ad90ca8fbf557b951 (diff)
Make app_queue and res_agi independent of AMI being enabled.
The https://reviewboard.asterisk.org/r/2888/ review changes manager to not subscribe to stasis when it is disabled for performance reasons. When manager is disabled app_queue and res_agi decline to load and fail to clean up what they have already allocated. * Made app_queue and res_agi clean up allocated resources when they decline to load. * Made app_queue and res_agi use their own subscriptions to the stasis topics instead of borrowing manager's message router structure inappropriately. (closes issue ASTERISK-22604) Reported by: rmudgett Review: https://reviewboard.asterisk.org/r/2902/ ........ Merged revisions 400671 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400672 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_agi.c')
-rw-r--r--res/res_agi.c156
1 files changed, 72 insertions, 84 deletions
diff --git a/res/res_agi.c b/res/res_agi.c
index e69a24cc1..ed70356dd 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -1033,38 +1033,66 @@ enum agi_result {
AGI_RESULT_HANGUP,
};
-STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_exec_start_type);
-STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_exec_end_type);
-STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_start_type);
-STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_exec_type);
-STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_end_type);
-
-static void agi_channel_manager_event(void *data,
- struct stasis_subscription *sub,
- struct stasis_message *message)
+static struct ast_manager_event_blob *agi_channel_to_ami(const char *type, struct stasis_message *message)
{
- const char *type = data;
struct ast_channel_blob *obj = stasis_message_data(message);
- RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
+ RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
RAII_VAR(struct ast_str *, event_string, NULL, ast_free);
- channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
- if (!channel_event_string) {
- return;
- }
-
+ channel_string = ast_manager_build_channel_state_string(obj->snapshot);
event_string = ast_manager_str_from_json_object(obj->blob, NULL);
- if (!event_string) {
- return;
+ if (!channel_string || !event_string) {
+ return NULL;
}
- manager_event(EVENT_FLAG_AGI, type,
+ return ast_manager_event_blob_create(EVENT_FLAG_AGI, type,
"%s"
"%s",
- ast_str_buffer(channel_event_string),
+ ast_str_buffer(channel_string),
ast_str_buffer(event_string));
}
+static struct ast_manager_event_blob *agi_exec_start_to_ami(struct stasis_message *message)
+{
+ return agi_channel_to_ami("AGIExecStart", message);
+}
+
+static struct ast_manager_event_blob *agi_exec_end_to_ami(struct stasis_message *message)
+{
+ return agi_channel_to_ami("AGIExecEnd", message);
+}
+
+static struct ast_manager_event_blob *agi_async_start_to_ami(struct stasis_message *message)
+{
+ return agi_channel_to_ami("AsyncAGIStart", message);
+}
+
+static struct ast_manager_event_blob *agi_async_exec_to_ami(struct stasis_message *message)
+{
+ return agi_channel_to_ami("AsyncAGIExec", message);
+}
+
+static struct ast_manager_event_blob *agi_async_end_to_ami(struct stasis_message *message)
+{
+ return agi_channel_to_ami("AsyncAGIEnd", message);
+}
+
+STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_exec_start_type,
+ .to_ami = agi_exec_start_to_ami,
+ );
+STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_exec_end_type,
+ .to_ami = agi_exec_end_to_ami,
+ );
+STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_start_type,
+ .to_ami = agi_async_start_to_ami,
+ );
+STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_exec_type,
+ .to_ami = agi_async_exec_to_ami,
+ );
+STASIS_MESSAGE_TYPE_DEFN_LOCAL(agi_async_end_type,
+ .to_ami = agi_async_end_to_ami,
+ );
+
static agi_command *find_command(const char * const cmds[], int exact);
AST_THREADSTORAGE(agi_buf);
@@ -3468,10 +3496,9 @@ int AST_OPTIONAL_API_NAME(ast_agi_unregister)(struct ast_module *mod, agi_comman
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&agi_commands);
- if (unregistered)
+ if (unregistered) {
ast_verb(2, "AGI Command '%s' unregistered\n",fullcmd);
- else
- ast_log(LOG_WARNING, "Unable to unregister command: '%s'!\n",fullcmd);
+ }
return unregistered;
}
@@ -4256,17 +4283,6 @@ AST_TEST_DEFINE(test_agi_null_docs)
static int unload_module(void)
{
- struct stasis_message_router *message_router;
-
- message_router = ast_manager_get_message_router();
- if (message_router) {
- stasis_message_router_remove(message_router, agi_exec_start_type());
- stasis_message_router_remove(message_router, agi_exec_end_type());
- stasis_message_router_remove(message_router, agi_async_start_type());
- stasis_message_router_remove(message_router, agi_async_exec_type());
- stasis_message_router_remove(message_router, agi_async_end_type());
- }
-
STASIS_MESSAGE_TYPE_CLEANUP(agi_exec_start_type);
STASIS_MESSAGE_TYPE_CLEANUP(agi_exec_end_type);
STASIS_MESSAGE_TYPE_CLEANUP(agi_async_start_type);
@@ -4274,67 +4290,39 @@ static int unload_module(void)
STASIS_MESSAGE_TYPE_CLEANUP(agi_async_end_type);
ast_cli_unregister_multiple(cli_agi, ARRAY_LEN(cli_agi));
- /* we can safely ignore the result of ast_agi_unregister_multiple() here, since it cannot fail, as
- we know that these commands were registered by this module and are still registered
- */
- (void) ast_agi_unregister_multiple(ast_module_info->self, commands, ARRAY_LEN(commands));
+ ast_agi_unregister_multiple(ast_module_info->self, commands, ARRAY_LEN(commands));
ast_unregister_application(eapp);
ast_unregister_application(deadapp);
ast_manager_unregister("AGI");
+ ast_unregister_application(app);
AST_TEST_UNREGISTER(test_agi_null_docs);
- return ast_unregister_application(app);
+ return 0;
}
static int load_module(void)
{
- struct stasis_message_router *message_router;
+ int err = 0;
- message_router = ast_manager_get_message_router();
- if (!message_router) {
- return AST_MODULE_LOAD_DECLINE;
- }
+ err |= STASIS_MESSAGE_TYPE_INIT(agi_exec_start_type);
+ err |= STASIS_MESSAGE_TYPE_INIT(agi_exec_end_type);
+ err |= STASIS_MESSAGE_TYPE_INIT(agi_async_start_type);
+ err |= STASIS_MESSAGE_TYPE_INIT(agi_async_exec_type);
+ err |= STASIS_MESSAGE_TYPE_INIT(agi_async_end_type);
+
+ err |= ast_cli_register_multiple(cli_agi, ARRAY_LEN(cli_agi));
+ err |= ast_agi_register_multiple(ast_module_info->self, commands, ARRAY_LEN(commands));
+ err |= ast_register_application_xml(deadapp, deadagi_exec);
+ err |= ast_register_application_xml(eapp, eagi_exec);
+ err |= ast_manager_register_xml("AGI", EVENT_FLAG_AGI, action_add_agi_cmd);
+ err |= ast_register_application_xml(app, agi_exec);
- STASIS_MESSAGE_TYPE_INIT(agi_exec_start_type);
- STASIS_MESSAGE_TYPE_INIT(agi_exec_end_type);
- STASIS_MESSAGE_TYPE_INIT(agi_async_start_type);
- STASIS_MESSAGE_TYPE_INIT(agi_async_exec_type);
- STASIS_MESSAGE_TYPE_INIT(agi_async_end_type);
-
- stasis_message_router_add(message_router,
- agi_exec_start_type(),
- agi_channel_manager_event,
- "AGIExecStart");
-
- stasis_message_router_add(message_router,
- agi_exec_end_type(),
- agi_channel_manager_event,
- "AGIExecEnd");
-
- stasis_message_router_add(message_router,
- agi_async_start_type(),
- agi_channel_manager_event,
- "AsyncAGIStart");
-
- stasis_message_router_add(message_router,
- agi_async_exec_type(),
- agi_channel_manager_event,
- "AsyncAGIExec");
-
- stasis_message_router_add(message_router,
- agi_async_end_type(),
- agi_channel_manager_event,
- "AsyncAGIEnd");
-
- ast_cli_register_multiple(cli_agi, ARRAY_LEN(cli_agi));
- /* we can safely ignore the result of ast_agi_register_multiple() here, since it cannot fail, as
- no other commands have been registered yet
- */
- (void) ast_agi_register_multiple(ast_module_info->self, commands, ARRAY_LEN(commands));
- ast_register_application_xml(deadapp, deadagi_exec);
- ast_register_application_xml(eapp, eagi_exec);
- ast_manager_register_xml("AGI", EVENT_FLAG_AGI, action_add_agi_cmd);
AST_TEST_REGISTER(test_agi_null_docs);
- return ast_register_application_xml(app, agi_exec);
+
+ if (err) {
+ unload_module();
+ return AST_MODULE_LOAD_DECLINE;
+ }
+ return AST_MODULE_LOAD_SUCCESS;
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Asterisk Gateway Interface (AGI)",