Add EXTENSION_STATE() function that can retrieve the state of an extension that
[asterisk/asterisk.git] / funcs / func_extstate.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007, Digium, Inc.
5  *
6  * Modified from func_devstate.c by Russell Bryant <russell@digium.com> 
7  * Adam Gundy <adam@starsilk.net>
8
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*! \file
21  *
22  * \brief Get the state of a hinted extension for dialplan control
23  *
24  * \author Adam Gundy <adam@starsilk.net> 
25  *
26  * \ingroup functions
27  */
28
29 #include "asterisk.h"
30
31 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32
33 #include <stdlib.h>
34
35 #include "asterisk/module.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/devicestate.h"
40
41 static const char *ast_extstate_str(int state)
42 {
43         const char *res = "UNKNOWN";
44
45         switch (state) {
46         case AST_EXTENSION_NOT_INUSE:
47                 res = "NOT_INUSE";
48                 break;
49         case AST_EXTENSION_INUSE:
50                 res = "INUSE";
51                 break;
52         case AST_EXTENSION_BUSY:
53                 res = "BUSY";
54                 break;
55         case AST_EXTENSION_UNAVAILABLE:
56                 res = "UNAVAILABLE";
57                 break;
58         case AST_EXTENSION_RINGING:
59                 res = "RINGING";
60                 break;
61         case AST_EXTENSION_INUSE | AST_EXTENSION_RINGING:
62                 res = "RINGINUSE";
63                 break;
64         case AST_EXTENSION_INUSE | AST_EXTENSION_ONHOLD:
65                 res = "HOLDINUSE";
66                 break;
67         case AST_EXTENSION_ONHOLD:
68                 res = "ONHOLD";
69                 break;
70         }
71
72         return res;
73 }
74
75 static int extstate_read(struct ast_channel *chan, const char *cmd, char *data,
76         char *buf, size_t len)
77 {
78         char *exten, *context;
79
80         if (ast_strlen_zero(data)) {
81                 ast_log(LOG_WARNING, "EXTENSION_STATE requires an extension\n");
82                 return -1;
83         }
84
85         context = exten = data;
86         strsep(&context, "@");
87         if (ast_strlen_zero(context))
88                 context = "default";
89
90         if (ast_strlen_zero(exten)) {
91                 ast_log(LOG_WARNING, "EXTENSION_STATE requires an extension\n");
92                 return -1;
93         }
94
95         ast_copy_string(buf, 
96                 ast_extstate_str(ast_extension_state(chan, context, exten)), len);
97
98         return 0;
99 }
100
101 static struct ast_custom_function extstate_function = {
102         .name = "EXTENSION_STATE",
103         .synopsis = "Get an extension's state",
104         .syntax = "EXTENSION_STATE(extension[@context])",
105         .desc =
106         "  The EXTENSION_STATE function can be used to retrieve the state from any\n"
107         "hinted extension.  For example:\n"
108         "   NoOp(1234@default has state ${EXTENSION_STATE(1234)})\n"
109         "   NoOp(4567@home has state ${EXTENSION_STATE(4567@home)})\n"
110         "\n"
111         "  The possible values returned by this function are:\n"
112         "UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING\n"
113         "RINGINUSE | HOLDINUSE | ONHOLD\n",
114         .read = extstate_read,
115 };
116
117 static int unload_module(void)
118 {
119         int res;
120
121         res = ast_custom_function_unregister(&extstate_function);
122
123         return res;
124 }
125
126 static int load_module(void)
127 {
128         int res;
129
130         res = ast_custom_function_register(&extstate_function);
131
132         return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
133 }
134
135 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Gets an extension's state in the dialplan");