Thu Apr 28 2011 16:57:10

Asterisk developer's documentation


func_devstate.c File Reference

Manually controlled blinky lights. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/devicestate.h"
#include "asterisk/cli.h"
#include "asterisk/astdb.h"
#include "asterisk/app.h"
Include dependency graph for func_devstate.c:

Go to the source code of this file.

Enumerations

enum  { HINT_OPT_NAME = (1 << 0) }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static enum ast_device_state custom_devstate_callback (const char *data)
static int devstate_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int devstate_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static char * handle_cli_devstate_change (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_devstate_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int hint_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Gets or sets a device state in the dialplan" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static const char astdb_family [] = "CustomDevstate"
static struct ast_cli_entry cli_funcdevstate []
static struct ast_custom_function devstate_function
static struct ast_custom_function hint_function
static struct ast_app_option hint_options [128] = { [ 'n' ] = { .flag = HINT_OPT_NAME }, }

Detailed Description

Manually controlled blinky lights.

Author:
Russell Bryant <russell@digium.com>
Todo:
Delete the entry from AstDB when set to nothing like Set(DEVICE_STATE(Custom:lamp1)=)
Note:
Props go out to Ahrimanes in #asterisk for requesting this at 4:30 AM when I couldn't sleep. :)

Definition in file func_devstate.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
HINT_OPT_NAME 

Definition at line 136 of file func_devstate.c.

     {
   HINT_OPT_NAME = (1 << 0),
};

Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 352 of file func_devstate.c.

static void __unreg_module ( void  ) [static]

Definition at line 352 of file func_devstate.c.

static enum ast_device_state custom_devstate_callback ( const char *  data) [static]

Definition at line 182 of file func_devstate.c.

References ast_db_get(), ast_devstate_val(), and buf.

Referenced by load_module().

{
   char buf[256] = "";

   ast_db_get(astdb_family, data, buf, sizeof(buf));

   return ast_devstate_val(buf);
}
static int devstate_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 100 of file func_devstate.c.

References ast_copy_string(), and ast_devstate_str().

static int devstate_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Definition at line 107 of file func_devstate.c.

References ast_db_put(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_devstate_val(), ast_log(), ast_strlen_zero(), len(), LOG_ERROR, and LOG_WARNING.

{
   size_t len = strlen("Custom:");
   enum ast_device_state state_val;

   if (strncasecmp(data, "Custom:", len)) {
      ast_log(LOG_WARNING, "The DEVICE_STATE function can only be used to set 'Custom:' device state!\n");
      return -1;
   }
   data += len;
   if (ast_strlen_zero(data)) {
      ast_log(LOG_WARNING, "DEVICE_STATE function called with no custom device name!\n");
      return -1;
   }

   state_val = ast_devstate_val(value);

   if (state_val == AST_DEVICE_UNKNOWN) {
      ast_log(LOG_ERROR, "DEVICE_STATE function given invalid state value '%s'\n", value);
      return -1;
   }

   ast_db_put(astdb_family, data, value);

   ast_devstate_changed(state_val, "Custom:%s", data);

   return 0;
}
static char* handle_cli_devstate_change ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 235 of file func_devstate.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_db_put(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_devstate_val(), ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

{
    size_t len;
   const char *dev, *state;
   enum ast_device_state state_val;

   switch (cmd) {
   case CLI_INIT:
      e->command = "devstate change";
      e->usage =
         "Usage: devstate change <device> <state>\n"
         "       Change a custom device to a new state.\n"
         "       The possible values for the state are:\n"
         "UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING\n"
         "RINGINUSE | ONHOLD\n",
         "\n"
         "Examples:\n"
         "       devstate change Custom:mystate1 INUSE\n"
         "       devstate change Custom:mystate1 NOT_INUSE\n"
         "       \n";
      return NULL;
   case CLI_GENERATE:
   {
      static char * const cmds[] = { "UNKNOWN", "NOT_INUSE", "INUSE", "BUSY",
         "UNAVAILABLE", "RINGING", "RINGINUSE", "ONHOLD", NULL };

      if (a->pos == e->args + 1)
         return ast_cli_complete(a->word, cmds, a->n);

      return NULL;
   }
   }

   if (a->argc != e->args + 2)
      return CLI_SHOWUSAGE;

   len = strlen("Custom:");
   dev = a->argv[e->args];
   state = a->argv[e->args + 1];

   if (strncasecmp(dev, "Custom:", len)) {
      ast_cli(a->fd, "The devstate command can only be used to set 'Custom:' device state!\n");
      return CLI_FAILURE;
   }

   dev += len;
   if (ast_strlen_zero(dev))
      return CLI_SHOWUSAGE;

   state_val = ast_devstate_val(state);

   if (state_val == AST_DEVICE_UNKNOWN)
      return CLI_SHOWUSAGE;

   ast_cli(a->fd, "Changing %s to %s\n", dev, state);

   ast_db_put(astdb_family, dev, state);

   ast_devstate_changed(state_val, "Custom:%s", dev);

   return CLI_SUCCESS;
}
static char* handle_cli_devstate_list ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 191 of file func_devstate.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), ast_db_freetree(), ast_db_gettree(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_db_entry::data, ast_cli_args::fd, ast_db_entry::key, ast_db_entry::next, and ast_cli_entry::usage.

{
   struct ast_db_entry *db_entry, *db_tree;

   switch (cmd) {
   case CLI_INIT:
      e->command = "devstate list";
      e->usage =
         "Usage: devstate list\n"
         "       List all custom device states that have been set by using\n"
         "       the DEVICE_STATE dialplan function.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }

   if (a->argc != e->args)
      return CLI_SHOWUSAGE;

   ast_cli(a->fd, "\n"
           "---------------------------------------------------------------------\n"
           "--- Custom Device States --------------------------------------------\n"
           "---------------------------------------------------------------------\n"
           "---\n");

   db_entry = db_tree = ast_db_gettree(astdb_family, NULL);
   for (; db_entry; db_entry = db_entry->next) {
      const char *dev_name = strrchr(db_entry->key, '/') + 1;
      if (dev_name <= (const char *) 1)
         continue;
      ast_cli(a->fd, "--- Name: 'Custom:%s'  State: '%s'\n"
                     "---\n", dev_name, db_entry->data);
   }
   ast_db_freetree(db_tree);
   db_tree = NULL;

   ast_cli(a->fd,
           "---------------------------------------------------------------------\n"
           "---------------------------------------------------------------------\n"
           "\n");

   return CLI_SUCCESS;
}
static int hint_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 144 of file func_devstate.c.

References AST_APP_ARG, ast_app_parse_options(), AST_DECLARE_APP_ARGS, ast_get_hint(), ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_test_flag, context, exten, HINT_OPT_NAME, hint_options, LOG_WARNING, and strsep().

{
   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 int load_module ( void  ) [static]

Definition at line 326 of file func_devstate.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_custom_function_register, ast_db_freetree(), ast_db_gettree(), ast_devstate_changed(), ast_devstate_prov_add(), ast_devstate_val(), custom_devstate_callback(), ast_db_entry::data, ast_db_entry::key, and ast_db_entry::next.

{
   int res = 0;
   struct ast_db_entry *db_entry, *db_tree;

   /* Populate the device state cache on the system with all of the currently
    * known custom device states. */
   db_entry = db_tree = ast_db_gettree(astdb_family, NULL);
   for (; db_entry; db_entry = db_entry->next) {
      const char *dev_name = strrchr(db_entry->key, '/') + 1;
      if (dev_name <= (const char *) 1)
         continue;
      ast_devstate_changed(ast_devstate_val(db_entry->data),
         "Custom:%s\n", dev_name);
   }
   ast_db_freetree(db_tree);
   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));

   return res;
}

Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Gets or sets a device state in the dialplan" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 352 of file func_devstate.c.

Definition at line 352 of file func_devstate.c.

const char astdb_family[] = "CustomDevstate" [static]

Definition at line 98 of file func_devstate.c.

struct ast_cli_entry cli_funcdevstate[] [static]
Initial value:
 {
   AST_CLI_DEFINE(handle_cli_devstate_list, "List currently known custom device states"),
   AST_CLI_DEFINE(handle_cli_devstate_change, "Change a custom device state"),
}

Definition at line 298 of file func_devstate.c.

Initial value:
 {
   .name = "DEVICE_STATE",
   .read = devstate_read,
   .write = devstate_write,
}

Definition at line 303 of file func_devstate.c.

Initial value:
 {
   .name = "HINT",
   .read = hint_read,
}

Definition at line 309 of file func_devstate.c.

struct ast_app_option hint_options[128] = { [ 'n' ] = { .flag = HINT_OPT_NAME }, } [static]

Definition at line 142 of file func_devstate.c.

Referenced by hint_read().