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: 122234 $")
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 "This application sets the following channel variable upon completion:\n"
00058 " AVAILCHAN - the name of the available channel, if one exists\n"
00059 " AVAILORIGCHAN - the canonical channel name that was used to create the channel\n"
00060 " AVAILSTATUS - the status code for the available channel\n";
00061
00062
00063 static int chanavail_exec(struct ast_channel *chan, void *data)
00064 {
00065 int inuse=-1, option_state=0, string_compare=0, option_all_avail=0;
00066 int status;
00067 char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur;
00068 struct ast_str *tmp_availchan = ast_str_alloca(2048);
00069 struct ast_str *tmp_availorig = ast_str_alloca(2048);
00070 struct ast_str *tmp_availstat = ast_str_alloca(2048);
00071 struct ast_channel *tempchan;
00072 AST_DECLARE_APP_ARGS(args,
00073 AST_APP_ARG(reqchans);
00074 AST_APP_ARG(options);
00075 );
00076
00077 if (ast_strlen_zero(data)) {
00078 ast_log(LOG_WARNING, "ChanIsAvail requires an argument (DAHDI/1&DAHDI/2)\n");
00079 return -1;
00080 }
00081
00082 info = ast_strdupa(data);
00083
00084 AST_STANDARD_APP_ARGS(args, info);
00085
00086 if (args.options) {
00087 if (strchr(args.options, 'a')) {
00088 option_all_avail = 1;
00089 }
00090 if (strchr(args.options, 's')) {
00091 option_state = 1;
00092 }
00093 if (strchr(args.options, 't')) {
00094 string_compare = 1;
00095 }
00096 }
00097 peers = args.reqchans;
00098 if (peers) {
00099 cur = peers;
00100 do {
00101
00102 rest = strchr(cur, '&');
00103 if (rest) {
00104 *rest = 0;
00105 rest++;
00106 }
00107 tech = cur;
00108 number = strchr(tech, '/');
00109 if (!number) {
00110 ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
00111 return -1;
00112 }
00113 *number = '\0';
00114 number++;
00115
00116 if (string_compare) {
00117
00118
00119
00120 snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
00121 status = inuse = ast_parse_device_state(trychan);
00122 } else if (option_state) {
00123
00124
00125
00126
00127 snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
00128 status = inuse = ast_device_state(trychan);
00129 }
00130 if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
00131 ast_str_append(&tmp_availchan, 0, "%s%s", tmp_availchan->used ? "&" : "", tempchan->name);
00132
00133 snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
00134 ast_str_append(&tmp_availorig, 0, "%s%s", tmp_availorig->used ? "&" : "", tmp);
00135
00136 snprintf(tmp, sizeof(tmp), "%d", status);
00137 ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
00138
00139 ast_hangup(tempchan);
00140 tempchan = NULL;
00141
00142 if (!option_all_avail) {
00143 break;
00144 }
00145 } else {
00146 snprintf(tmp, sizeof(tmp), "%d", status);
00147 ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
00148 }
00149 cur = rest;
00150 } while (cur);
00151 }
00152
00153 pbx_builtin_setvar_helper(chan, "AVAILCHAN", tmp_availchan->str);
00154
00155 pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp_availorig->str);
00156 pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp_availstat->str);
00157
00158 return 0;
00159 }
00160
00161 static int unload_module(void)
00162 {
00163 return ast_unregister_application(app);
00164 }
00165
00166 static int load_module(void)
00167 {
00168 return ast_register_application(app, chanavail_exec, synopsis, descrip) ?
00169 AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00170 }
00171
00172 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Check channel availability");