Merge HINT() dialplan function from my sandbox branch into trunk. This function
[asterisk/asterisk.git] / funcs / func_devstate.c
index 5f7595b..7ed389c 100644 (file)
@@ -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));