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
changes/97/197/1
Jonathan Rose 11 years ago
parent dbec5e0d8d
commit 04a9123309

@ -20,6 +20,10 @@ AMI
res_manager_presence_state.so. If the high frequency of these events is
problematic for you, do not load these modules.
* Added DialplanExtensionAdd and DialplanExtensionRemove AMI commands. They
work in basically the same way as the 'dialplan add extension' and
'dialplan remove extension' CLI commands respectively.
* New AMI action LoggerRotate reloads and rotates logger in the same manner
as CLI command 'logger rotate'

@ -10046,8 +10046,8 @@ static int ast_add_extension2_lockopt(struct ast_context *con,
ast_unlock_context(con);
}
if (res < 0) {
errno = EEXIST; /* XXX do we care ? */
return 0; /* XXX should we return -1 maybe ? */
errno = EEXIST;
return -1;
}
} else {
/*

@ -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;

Loading…
Cancel
Save