Mon Jul 14 17:24:57 2008

Asterisk developer's documentation


func_devstate.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2007, Digium, Inc.
00005  *
00006  * Russell Bryant <russell@digium.com> 
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Manually controlled blinky lights
00022  *
00023  * \author Russell Bryant <russell@digium.com> 
00024  *
00025  * \ingroup functions
00026  *
00027  * \note Props go out to Ahrimanes in #asterisk for requesting this at 4:30 AM
00028  *       when I couldn't sleep.  :)
00029  */
00030 
00031 #include "asterisk.h"
00032 
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 4 $")
00034 
00035 #include <stdlib.h>
00036 
00037 #include "asterisk/module.h"
00038 #include "asterisk/channel.h"
00039 #include "asterisk/pbx.h"
00040 #include "asterisk/utils.h"
00041 #include "asterisk/linkedlists.h"
00042 #include "asterisk/devicestate.h"
00043 #include "asterisk/cli.h"
00044 #include "asterisk/astdb.h"
00045 
00046 static const char astdb_family[] = "CustomDevstate";
00047 
00048 static const char *ast_devstate_str(int state)
00049 {
00050    const char *res = "UNKNOWN";
00051 
00052    switch (state) {
00053    case AST_DEVICE_UNKNOWN:
00054       break;
00055    case AST_DEVICE_NOT_INUSE:
00056       res = "NOT_INUSE";
00057       break;
00058    case AST_DEVICE_INUSE:
00059       res = "INUSE";
00060       break;
00061    case AST_DEVICE_BUSY:
00062       res = "BUSY";
00063       break;
00064    case AST_DEVICE_INVALID:
00065       res = "INVALID";
00066       break;
00067    case AST_DEVICE_UNAVAILABLE:
00068       res = "UNAVAILABLE";
00069       break;
00070    case AST_DEVICE_RINGING:
00071       res = "RINGING";
00072       break;
00073    case AST_DEVICE_RINGINUSE:
00074       res = "RINGINUSE";
00075       break;
00076    case AST_DEVICE_ONHOLD:
00077       res = "ONHOLD";
00078       break;
00079    }
00080 
00081    return res;
00082 }
00083 
00084 static int ast_devstate_val(const char *val)
00085 {
00086    if (!strcasecmp(val, "NOT_INUSE"))
00087       return AST_DEVICE_NOT_INUSE;
00088    else if (!strcasecmp(val, "INUSE"))
00089       return AST_DEVICE_INUSE;
00090    else if (!strcasecmp(val, "BUSY"))
00091       return AST_DEVICE_BUSY;
00092    else if (!strcasecmp(val, "INVALID"))
00093       return AST_DEVICE_INVALID;
00094    else if (!strcasecmp(val, "UNAVAILABLE"))
00095       return AST_DEVICE_UNAVAILABLE;
00096    else if (!strcasecmp(val, "RINGING"))
00097       return AST_DEVICE_RINGING;
00098    else if (!strcasecmp(val, "RINGINUSE"))
00099       return AST_DEVICE_RINGINUSE;
00100    else if (!strcasecmp(val, "ONHOLD"))
00101       return AST_DEVICE_ONHOLD;
00102 
00103    return AST_DEVICE_UNKNOWN;
00104 }
00105 
00106 static int devstate_read(struct ast_channel *chan, char *cmd, char *data, 
00107    char *buf, size_t len)
00108 {
00109    ast_copy_string(buf, ast_devstate_str(ast_device_state(data)), len);
00110 
00111    return 0;
00112 }
00113 
00114 static int devstate_write(struct ast_channel *chan, char *function,
00115    char *data, const char *value)
00116 {
00117    size_t len = strlen("Custom:");
00118 
00119    if (strncasecmp(data, "Custom:", len)) {
00120       ast_log(LOG_WARNING, "The DEVSTATE function can only be used to set 'Custom:' device state!\n");
00121       return -1;
00122    }
00123    data += len;
00124    if (ast_strlen_zero(data)) {
00125       ast_log(LOG_WARNING, "DEVSTATE function called with no custom device name!\n");
00126       return -1;
00127    }
00128 
00129    ast_db_put(astdb_family, data, (char *) value);
00130 
00131    ast_device_state_changed("Custom:%s", data);
00132 
00133    return 0;
00134 }
00135 
00136 static int custom_devstate_callback(const char *data)
00137 {
00138    char buf[256] = "";
00139 
00140    ast_db_get(astdb_family, data, buf, sizeof(buf));
00141 
00142    return ast_devstate_val(buf);
00143 }
00144 
00145 static int cli_funcdevstate_list(int fd, int argc, char *argv[])
00146 {
00147    struct ast_db_entry *db_entry, *db_tree;
00148 
00149    if (argc != 2)
00150       return RESULT_SHOWUSAGE;
00151 
00152    ast_cli(fd, "\n"
00153            "---------------------------------------------------------------------\n"
00154            "--- Custom Device States --------------------------------------------\n"
00155            "---------------------------------------------------------------------\n"
00156            "---\n");
00157 
00158    db_entry = db_tree = ast_db_gettree(astdb_family, NULL);
00159    for (; db_entry; db_entry = db_entry->next) {
00160       const char *dev_name = strrchr(db_entry->key, '/') + 1;
00161       if (dev_name <= (const char *) 1)
00162          continue;
00163       ast_cli(fd, "--- name: 'custom:%s'  state: '%s'\n"
00164                      "---\n", dev_name, db_entry->data);
00165    }
00166    ast_db_freetree(db_tree);
00167    db_tree = NULL;
00168 
00169    ast_cli(fd,
00170            "---------------------------------------------------------------------\n"
00171            "---------------------------------------------------------------------\n"
00172            "\n");
00173 
00174    return RESULT_SUCCESS;
00175 }
00176 
00177 static struct ast_cli_entry cli_funcdevstate[] = {
00178    { { "funcdevstate", "list", }, cli_funcdevstate_list, NULL, NULL },
00179 };
00180 
00181 static struct ast_custom_function devstate_function = {
00182    .name = "DEVSTATE",
00183    .synopsis = "Get or Set a device state",
00184    .syntax = "DEVSTATE(device)",
00185    .desc =
00186    "  The DEVSTATE function can be used to retrieve the device state from any\n"
00187    "device state provider.  For example:\n"
00188    "   NoOp(SIP/mypeer has state ${DEVSTATE(SIP/mypeer)})\n"
00189    "   NoOp(Conference number 1234 has state ${DEVSTATE(MeetMe:1234)})\n"
00190    "\n"
00191    "  The DEVSTATE function can also be used to set custom device state from\n"
00192    "the dialplan.  The \"Custom:\" prefix must be used.  For example:\n"
00193    "  Set(DEVSTATE(Custom:lamp1)=BUSY)\n"
00194    "  Set(DEVSTATE(Custom:lamp2)=NOT_INUSE)\n"
00195    "You can subscribe to the status of a custom device state using a hint in\n"
00196    "the dialplan:\n"
00197    "  exten => 1234,hint,Custom:lamp1\n"
00198    "\n"
00199    "  The possible values for both uses of this function are:\n"
00200    "UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING\n"
00201    "RINGINUSE | ONHOLD\n",
00202    .read = devstate_read,
00203    .write = devstate_write,
00204 };
00205 
00206 static int unload_module(void)
00207 {
00208    int res = 0;
00209 
00210    res |= ast_custom_function_unregister(&devstate_function);
00211    ast_devstate_prov_del("Custom");
00212    ast_cli_unregister_multiple(cli_funcdevstate, ARRAY_LEN(cli_funcdevstate));
00213 
00214    return res;
00215 }
00216 
00217 static int load_module(void)
00218 {
00219    int res = 0;
00220 
00221    res |= ast_custom_function_register(&devstate_function);
00222    res |= ast_devstate_prov_add("Custom", custom_devstate_callback);
00223    ast_cli_register_multiple(cli_funcdevstate, ARRAY_LEN(cli_funcdevstate));
00224 
00225    return res;
00226 }
00227 
00228 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Gets or sets a device state in the dialplan");

Generated on Mon Jul 14 17:24:57 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1