00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 229968 $")
00033
00034 #include <sys/ioctl.h>
00035
00036 #include "asterisk/lock.h"
00037 #include "asterisk/file.h"
00038 #include "asterisk/channel.h"
00039 #include "asterisk/pbx.h"
00040 #include "asterisk/module.h"
00041 #include "asterisk/app.h"
00042 #include "asterisk/devicestate.h"
00043
00044 static char *app = "ChanIsAvail";
00045
00046 static char *synopsis = "Check channel availability";
00047
00048 static char *descrip =
00049 " ChanIsAvail(Technology/resource[&Technology2/resource2...][,options]): \n"
00050 "This application will check to see if any of the specified channels are\n"
00051 "available.\n"
00052 " Options:\n"
00053 " a - Check for all available channels, not only the first one.\n"
00054 " s - Consider the channel unavailable if the channel is in use at all.\n"
00055 " t - Simply checks if specified channels exist in the channel list\n"
00056 " (implies option s).\n"
00057 "Note that the AVAILSTATUS variable is used for both device state\n"
00058 "and cause code. It is therefore possible for it to give a value that may\n"
00059 "indicate a device is available when it is not. It is suggested that the\n"
00060 "AVAILORIGCHAN variable is used instead to see whether a device is available\n"
00061 "or not.\n"
00062 "This application sets the following channel variable upon completion:\n"
00063 " AVAILCHAN - the name of the available channel, if one exists\n"
00064 " AVAILORIGCHAN - the canonical channel name that was used to create the channel\n"
00065 " AVAILSTATUS - the status code for the available channel\n";
00066
00067
00068 static int chanavail_exec(struct ast_channel *chan, void *data)
00069 {
00070 int inuse=-1, option_state=0, string_compare=0, option_all_avail=0;
00071 int status;
00072 char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur;
00073 struct ast_str *tmp_availchan = ast_str_alloca(2048);
00074 struct ast_str *tmp_availorig = ast_str_alloca(2048);
00075 struct ast_str *tmp_availstat = ast_str_alloca(2048);
00076 struct ast_channel *tempchan;
00077 AST_DECLARE_APP_ARGS(args,
00078 AST_APP_ARG(reqchans);
00079 AST_APP_ARG(options);
00080 );
00081
00082 if (ast_strlen_zero(data)) {
00083 ast_log(LOG_WARNING, "ChanIsAvail requires an argument (DAHDI/1&DAHDI/2)\n");
00084 return -1;
00085 }
00086
00087 info = ast_strdupa(data);
00088
00089 AST_STANDARD_APP_ARGS(args, info);
00090
00091 if (args.options) {
00092 if (strchr(args.options, 'a')) {
00093 option_all_avail = 1;
00094 }
00095 if (strchr(args.options, 's')) {
00096 option_state = 1;
00097 }
00098 if (strchr(args.options, 't')) {
00099 string_compare = 1;
00100 }
00101 }
00102 peers = args.reqchans;
00103 if (peers) {
00104 cur = peers;
00105 do {
00106
00107 rest = strchr(cur, '&');
00108 if (rest) {
00109 *rest = 0;
00110 rest++;
00111 }
00112 tech = cur;
00113 number = strchr(tech, '/');
00114 if (!number) {
00115 ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
00116 return -1;
00117 }
00118 *number = '\0';
00119 number++;
00120
00121 if (string_compare) {
00122
00123
00124
00125 snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
00126 status = inuse = ast_parse_device_state(trychan);
00127 } else if (option_state) {
00128
00129
00130
00131
00132 snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
00133 status = inuse = ast_device_state(trychan);
00134 }
00135 if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
00136 ast_str_append(&tmp_availchan, 0, "%s%s", tmp_availchan->used ? "&" : "", tempchan->name);
00137
00138 snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
00139 ast_str_append(&tmp_availorig, 0, "%s%s", tmp_availorig->used ? "&" : "", tmp);
00140
00141 snprintf(tmp, sizeof(tmp), "%d", status);
00142 ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
00143
00144 ast_hangup(tempchan);
00145 tempchan = NULL;
00146
00147 if (!option_all_avail) {
00148 break;
00149 }
00150 } else {
00151 snprintf(tmp, sizeof(tmp), "%d", status);
00152 ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
00153 }
00154 cur = rest;
00155 } while (cur);
00156 }
00157
00158 pbx_builtin_setvar_helper(chan, "AVAILCHAN", tmp_availchan->str);
00159
00160 pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp_availorig->str);
00161 pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp_availstat->str);
00162
00163 return 0;
00164 }
00165
00166 static int unload_module(void)
00167 {
00168 return ast_unregister_application(app);
00169 }
00170
00171 static int load_module(void)
00172 {
00173 return ast_register_application(app, chanavail_exec, synopsis, descrip) ?
00174 AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00175 }
00176
00177 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Check channel availability");