diff --git a/CHANGES b/CHANGES index b10d7738083d28f694863dc1af1b9efb0d952332..4b3af721c4b3047ba2978cc5304be8426bed658e 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,10 @@ Dialplan functions mutex. No deadlocks are possible, as LOCK() only allows a single lock to be held for any given channel. Also, locks are automatically freed when a channel is hung up. + * Added HINT() dialplan function that allows retrieving hint information. + Hints are mappings between extensions and devices for the sake of + determining the state of an extension. This function can retrieve the list + of devices or the name associated with a hint. CLI Changes ----------- diff --git a/funcs/func_devstate.c b/funcs/func_devstate.c index 5f7595bb5a6b9819de69cdec56324d5d20ef4dd4..7ed389c9bdfe0bba39f299c1744cc5dab09bae17 100644 --- a/funcs/func_devstate.c +++ b/funcs/func_devstate.c @@ -42,6 +42,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/devicestate.h" #include "asterisk/cli.h" #include "asterisk/astdb.h" +#include "asterisk/app.h" static const char astdb_family[] = "CustomDevstate"; @@ -73,6 +74,52 @@ static int devstate_write(struct ast_channel *chan, const char *cmd, char *data, return 0; } +enum { + HINT_OPT_NAME = (1 << 0), +}; + +AST_APP_OPTIONS(hint_options, BEGIN_OPTIONS + AST_APP_OPTION('n', HINT_OPT_NAME), +END_OPTIONS ); + +static int hint_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) +{ + char *exten, *context; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(exten); + AST_APP_ARG(options); + ); + struct ast_flags opts = { 0, }; + int res; + + if (ast_strlen_zero(data)) { + ast_log(LOG_WARNING, "The HINT function requires an extension\n"); + return -1; + } + + AST_STANDARD_APP_ARGS(args, data); + + if (ast_strlen_zero(args.exten)) { + ast_log(LOG_WARNING, "The HINT function requires an extension\n"); + return -1; + } + + context = exten = args.exten; + strsep(&context, "@"); + if (ast_strlen_zero(context)) + context = "default"; + + if (!ast_strlen_zero(args.options)) + ast_app_parse_options(hint_options, &opts, NULL, args.options); + + if (ast_test_flag(&opts, HINT_OPT_NAME)) + res = ast_get_hint(NULL, 0, buf, len, chan, context, exten); + else + res = ast_get_hint(buf, len, NULL, 0, chan, context, exten); + + return !res; /* ast_get_hint returns non-zero on success */ +} + static enum ast_device_state custom_devstate_callback(const char *data) { char buf[256] = ""; @@ -155,11 +202,26 @@ static struct ast_custom_function devstate_function = { .write = devstate_write, }; +static struct ast_custom_function hint_function = { + .name = "HINT", + .synopsis = "Get the devices set for a dialplan hint", + .syntax = "HINT(extension[@context][|options])", + .desc = + " The HINT function can be used to retrieve the list of devices that are\n" + "mapped to a dialplan hint. For example:\n" + " NoOp(Hint for Extension 1234 is ${HINT(1234)})\n" + "Options:\n" + " 'n' - Retrieve name on the hint instead of list of devices\n" + "", + .read = hint_read, +}; + static int unload_module(void) { int res = 0; res |= ast_custom_function_unregister(&devstate_function); + res |= ast_custom_function_unregister(&hint_function); res |= ast_devstate_prov_del("Custom"); res |= ast_cli_unregister_multiple(cli_funcdevstate, ARRAY_LEN(cli_funcdevstate)); @@ -185,6 +247,7 @@ static int load_module(void) db_tree = NULL; res |= ast_custom_function_register(&devstate_function); + res |= ast_custom_function_register(&hint_function); res |= ast_devstate_prov_add("Custom", custom_devstate_callback); res |= ast_cli_register_multiple(cli_funcdevstate, ARRAY_LEN(cli_funcdevstate));