summaryrefslogtreecommitdiff
path: root/pbx
diff options
context:
space:
mode:
authorJonathan Rose <jrose@digium.com>2014-07-03 17:20:00 +0000
committerJonathan Rose <jrose@digium.com>2014-07-03 17:20:00 +0000
commit04a912330985d1197e58209b1ec98774e6cce68e (patch)
tree48c44ef9d1e6581102ccab67ae15fac370a35ec4 /pbx
parentdbec5e0d8d2d8c51e14f912354d12e1f713b6077 (diff)
pbx_config: Add manager actions to add/remove extensions
Adds two new manager commands to pbx_config - DialplanExtensionAdd and DialplanExtensionRemove which allow manager users to create and delete extensions respectively. Review: https://reviewboard.asterisk.org/r/3650/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@417910 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'pbx')
-rw-r--r--pbx/pbx_config.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/pbx/pbx_config.c b/pbx/pbx_config.c
index 478d3ce54..8301f25da 100644
--- a/pbx/pbx_config.c
+++ b/pbx/pbx_config.c
@@ -27,6 +27,59 @@
<support_level>core</support_level>
***/
+/*** DOCUMENTATION
+ <manager name="DialplanExtensionAdd" language="en_US">
+ <synopsis>
+ Add an extension to the dialplan
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Context" required="true">
+ <para>Context where the extension will be created. The context will
+ be created if it does not already exist.</para>
+ </parameter>
+ <parameter name="Extension" required="true">
+ <para>Name of the extension that will be created (may include callerid match by separating
+ with '/')</para>
+ </parameter>
+ <parameter name="Priority" required="true">
+ <para>Priority being added to this extension. Must be either <literal>hint</literal> or a
+ numerical value.</para>
+ </parameter>
+ <parameter name="Application" required="true">
+ <para>The application to use for this extension at the requested priority</para>
+ </parameter>
+ <parameter name="ApplicationData" required="false">
+ <para>Arguments to the application.</para>
+ </parameter>
+ <parameter name="Replace" required="false">
+ <para>If set to 'yes', '1', 'true' or any of the other values we evaluate as true, then
+ if an extension already exists at the requested context, extension, and priority it will
+ be overwritten. Otherwise, the existing extension will remain and the action will fail.
+ </para>
+ </parameter>
+ </syntax>
+ </manager>
+ <manager name="DialplanExtensionRemove" language="en_US">
+ <synopsis>
+ Remove an extension from the dialplan
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Context" required="true">
+ <para>Context of the extension being removed</para>
+ </parameter>
+ <parameter name="Extension" required="true">
+ <para>Name of the extension being removed (may include callerid match by separating with '/')</para>
+ </parameter>
+ <parameter name="Priority" required="false">
+ <para>If provided, only remove this priority from the extension instead of all
+ priorities in the extension.</para>
+ </parameter>
+ </syntax>
+ </manager>
+ ***/
+
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
@@ -432,6 +485,54 @@ static char *handle_cli_dialplan_remove_extension(struct ast_cli_entry *e, int c
return ret;
}
+static int manager_dialplan_extension_remove(struct mansession *s, const struct message *m)
+{
+ const char *context = astman_get_header(m, "Context");
+ const char *extension = astman_get_header(m, "Extension");
+ const char *priority = astman_get_header(m, "Priority");
+
+ int ipriority;
+ char *exten;
+ char *cidmatch = NULL;
+
+ if (ast_strlen_zero(context) || ast_strlen_zero(extension)) {
+ astman_send_error(s, m, "Context and Extension must be provided "
+ "for DialplanExtensionRemove");
+ return 0;
+ }
+
+ exten = ast_strdupa(extension);
+
+ if (strchr(exten, '/')) {
+ cidmatch = exten;
+ strsep(&cidmatch, "/");
+ }
+
+ if (ast_strlen_zero(priority)) {
+ ipriority = 0;
+ } else if (!strcmp("hint", priority)) {
+ ipriority = PRIORITY_HINT;
+ } else if ((sscanf(priority, "%30d", &ipriority) != 1) || ipriority <= 0) {
+ astman_send_error(s, m, "The priority specified was invalid.");
+ return 0;
+ }
+
+ if (!ast_context_remove_extension_callerid(context, exten, ipriority,
+ /* Do not substitute S_OR; it is not the same thing */
+ !ast_strlen_zero(cidmatch) ? cidmatch : (ipriority ? "" : NULL),
+ !ast_strlen_zero(cidmatch) ? 1 : 0, registrar)) {
+ if (ipriority) {
+ astman_send_ack(s, m, "Removed the requested priority from the extension");
+ } else {
+ astman_send_ack(s, m, "Removed the requested extension");
+ }
+ } else {
+ astman_send_error(s, m, "Failed to remove requested extension");
+ }
+
+ return 0;
+}
+
static char *complete_dialplan_remove_extension(struct ast_cli_args *a)
{
char *ret = NULL;
@@ -1055,6 +1156,88 @@ static char *handle_cli_dialplan_add_extension(struct ast_cli_entry *e, int cmd,
return CLI_SUCCESS;
}
+static int manager_dialplan_extension_add(struct mansession *s, const struct message *m)
+{
+ const char *context = astman_get_header(m, "Context");
+ const char *extension = astman_get_header(m, "Extension");
+ const char *priority = astman_get_header(m, "Priority");
+ const char *application = astman_get_header(m, "Application");
+ const char *application_data = astman_get_header(m, "ApplicationData");
+ int replace = ast_true(astman_get_header(m, "Replace"));
+ int ipriority;
+ char *exten;
+ char *cidmatch = NULL;
+ struct ast_context *add_context;
+
+ if (ast_strlen_zero(context) || ast_strlen_zero(extension) ||
+ ast_strlen_zero(priority) || ast_strlen_zero(application)) {
+ astman_send_error(s, m, "Context, Extension, Priority, and "
+ "Application must be defined for DialplanExtensionAdd.");
+ return 0;
+ }
+
+ /* Priority conversion/validation */
+ if (!strcmp(priority, "hint")) {
+ ipriority = PRIORITY_HINT;
+ } else if ((sscanf(priority, "%30d", &ipriority) != 1) || (ipriority < 0)) {
+ astman_send_error(s, m, "The priority specified was invalid.");
+ return 0;
+ }
+
+ /* Split extension from cidmatch */
+ exten = ast_strdupa(extension);
+
+ if (strchr(exten, '/')) {
+ cidmatch = exten;
+ strsep(&cidmatch, "/");
+ }
+
+ if (ast_wrlock_contexts()) {
+ astman_send_error(s, m, "Failed to lock contexts list. Try again later.");
+ return 0;
+ }
+
+ add_context = ast_context_find_or_create(NULL, NULL, context, registrar);
+ if (!add_context) {
+ astman_send_error(s, m, "Could not find or create context specified "
+ "for the extension.");
+ ast_unlock_contexts();
+ return 0;
+ }
+
+ if (ast_add_extension2(add_context, replace, exten, ipriority, NULL, cidmatch,
+ application, ast_strdup(application_data), ast_free_ptr, registrar)) {
+ ast_unlock_contexts();
+ switch (errno) {
+ case ENOMEM:
+ astman_send_error(s, m, "Out of Memory");
+ break;
+
+ case EBUSY:
+ astman_send_error(s, m, "Failed to lock context(s) list");
+ break;
+
+ case ENOENT:
+ astman_send_error(s, m, "Context does not exist");
+ break;
+
+ case EEXIST:
+ astman_send_error(s, m, "That extension and priority already exist at that context");
+ break;
+
+ default:
+ astman_send_error(s, m, "Failed to add extension");
+ break;
+ }
+ return 0;
+ }
+ ast_unlock_contexts();
+
+ astman_send_ack(s, m, "Added requested extension");
+
+ return 0;
+}
+
static char *complete_dialplan_remove_context(struct ast_cli_args *a)
{
struct ast_context *c = NULL;
@@ -1393,6 +1576,9 @@ static struct ast_cli_entry cli_pbx_config[] = {
static struct ast_cli_entry cli_dialplan_save =
AST_CLI_DEFINE(handle_cli_dialplan_save, "Save dialplan");
+#define AMI_EXTENSION_ADD "DialplanExtensionAdd"
+#define AMI_EXTENSION_REMOVE "DialplanExtensionRemove"
+
/*!
* Standard module functions ...
*/
@@ -1404,6 +1590,8 @@ static int unload_module(void)
ast_free(overrideswitch_config);
}
ast_cli_unregister_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config));
+ ast_manager_unregister(AMI_EXTENSION_ADD);
+ ast_manager_unregister(AMI_EXTENSION_REMOVE);
ast_context_destroy(NULL, registrar);
return 0;
}
@@ -1870,10 +2058,22 @@ static int pbx_load_module(void)
static int load_module(void)
{
+ int res;
+
if (static_config && !write_protect_config)
ast_cli_register(&cli_dialplan_save);
ast_cli_register_multiple(cli_pbx_config, ARRAY_LEN(cli_pbx_config));
+ res = ast_manager_register_xml_core(AMI_EXTENSION_ADD,
+ EVENT_FLAG_SYSTEM, manager_dialplan_extension_add);
+ res |= ast_manager_register_xml_core(AMI_EXTENSION_REMOVE,
+ EVENT_FLAG_SYSTEM, manager_dialplan_extension_remove);
+
+ if (res) {
+ unload_module();
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
if (pbx_load_module())
return AST_MODULE_LOAD_DECLINE;