Add a function, CHANNELS(), which retrieves a list of all active channels.
[asterisk-bristuff.git] / apps / app_chanisavail.c
blob6a9cd8128aa34fec671b1c476337e0e74d002516
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
7 * James Golovich <james@gnuinter.net>
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.
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.
20 /*! \file
22 * \brief Check if Channel is Available
24 * \author Mark Spencer <markster@digium.com>
25 * \author James Golovich <james@gnuinter.net>
27 * \ingroup applications
30 #include "asterisk.h"
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34 #include <sys/ioctl.h>
36 #include "asterisk/lock.h"
37 #include "asterisk/file.h"
38 #include "asterisk/channel.h"
39 #include "asterisk/pbx.h"
40 #include "asterisk/module.h"
41 #include "asterisk/app.h"
42 #include "asterisk/devicestate.h"
44 static char *app = "ChanIsAvail";
46 static char *synopsis = "Check channel availability";
48 static char *descrip =
49 " ChanIsAvail(Technology/resource[&Technology2/resource2...][,options]): \n"
50 "This application will check to see if any of the specified channels are\n"
51 "available.\n"
52 " Options:\n"
53 " a - Check for all available channels, not only the first one.\n"
54 " s - Consider the channel unavailable if the channel is in use at all.\n"
55 " t - Simply checks if specified channels exist in the channel list\n"
56 " (implies option s).\n"
57 "This application sets the following channel variable upon completion:\n"
58 " AVAILCHAN - the name of the available channel, if one exists\n"
59 " AVAILORIGCHAN - the canonical channel name that was used to create the channel\n"
60 " AVAILSTATUS - the status code for the available channel\n";
63 static int chanavail_exec(struct ast_channel *chan, void *data)
65 int inuse=-1, option_state=0, string_compare=0, option_all_avail=0;
66 int status;
67 char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur;
68 struct ast_str *tmp_availchan = ast_str_alloca(2048);
69 struct ast_str *tmp_availorig = ast_str_alloca(2048);
70 struct ast_str *tmp_availstat = ast_str_alloca(2048);
71 struct ast_channel *tempchan;
72 AST_DECLARE_APP_ARGS(args,
73 AST_APP_ARG(reqchans);
74 AST_APP_ARG(options);
77 if (ast_strlen_zero(data)) {
78 ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
79 return -1;
82 info = ast_strdupa(data);
84 AST_STANDARD_APP_ARGS(args, info);
86 if (args.options) {
87 if (strchr(args.options, 'a')) {
88 option_all_avail = 1;
90 if (strchr(args.options, 's')) {
91 option_state = 1;
93 if (strchr(args.options, 't')) {
94 string_compare = 1;
97 peers = args.reqchans;
98 if (peers) {
99 cur = peers;
100 do {
101 /* remember where to start next time */
102 rest = strchr(cur, '&');
103 if (rest) {
104 *rest = 0;
105 rest++;
107 tech = cur;
108 number = strchr(tech, '/');
109 if (!number) {
110 ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
111 return -1;
113 *number = '\0';
114 number++;
116 if (string_compare) {
117 /* ast_parse_device_state checks for "SIP/1234" as a channel name.
118 ast_device_state will ask the SIP driver for the channel state. */
120 snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
121 status = inuse = ast_parse_device_state(trychan);
122 } else if (option_state) {
123 /* If the pbx says in use then don't bother trying further.
124 This is to permit testing if someone's on a call, even if the
125 channel can permit more calls (ie callwaiting, sip calls, etc). */
127 snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
128 status = inuse = ast_device_state(trychan);
130 if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
131 ast_str_append(&tmp_availchan, 0, "%s%s", tmp_availchan->used ? "&" : "", tempchan->name);
133 snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
134 ast_str_append(&tmp_availorig, 0, "%s%s", tmp_availorig->used ? "&" : "", tmp);
136 snprintf(tmp, sizeof(tmp), "%d", status);
137 ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
139 ast_hangup(tempchan);
140 tempchan = NULL;
142 if (!option_all_avail) {
143 break;
145 } else {
146 snprintf(tmp, sizeof(tmp), "%d", status);
147 ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
149 cur = rest;
150 } while (cur);
153 pbx_builtin_setvar_helper(chan, "AVAILCHAN", tmp_availchan->str);
154 /* Store the originally used channel too */
155 pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp_availorig->str);
156 pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp_availstat->str);
158 return 0;
161 static int unload_module(void)
163 return ast_unregister_application(app);
166 static int load_module(void)
168 return ast_register_application(app, chanavail_exec, synopsis, descrip) ?
169 AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
172 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Check channel availability");