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: 40722 $")
00033
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <unistd.h>
00038 #include <errno.h>
00039 #include <sys/ioctl.h>
00040
00041 #include "asterisk/lock.h"
00042 #include "asterisk/file.h"
00043 #include "asterisk/logger.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/app.h"
00048 #include "asterisk/devicestate.h"
00049 #include "asterisk/options.h"
00050
00051 static char *app = "ChanIsAvail";
00052
00053 static char *synopsis = "Check channel availability";
00054
00055 static char *descrip =
00056 " ChanIsAvail(Technology/resource[&Technology2/resource2...][|options]): \n"
00057 "This application will check to see if any of the specified channels are\n"
00058 "available. The following variables will be set by this application:\n"
00059 " ${AVAILCHAN} - the name of the available channel, if one exists\n"
00060 " ${AVAILORIGCHAN} - the canonical channel name that was used to create the channel\n"
00061 " ${AVAILSTATUS} - the status code for the available channel\n"
00062 " Options:\n"
00063 " s - Consider the channel unavailable if the channel is in use at all\n"
00064 " j - Support jumping to priority n+101 if no channel is available\n";
00065
00066
00067 static int chanavail_exec(struct ast_channel *chan, void *data)
00068 {
00069 int res=-1, inuse=-1, option_state=0, priority_jump=0;
00070 int status;
00071 struct ast_module_user *u;
00072 char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur;
00073 struct ast_channel *tempchan;
00074 AST_DECLARE_APP_ARGS(args,
00075 AST_APP_ARG(reqchans);
00076 AST_APP_ARG(options);
00077 );
00078
00079 if (ast_strlen_zero(data)) {
00080 ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
00081 return -1;
00082 }
00083
00084 u = ast_module_user_add(chan);
00085
00086 info = ast_strdupa(data);
00087
00088 AST_STANDARD_APP_ARGS(args, info);
00089
00090 if (args.options) {
00091 if (strchr(args.options, 's'))
00092 option_state = 1;
00093 if (strchr(args.options, 'j'))
00094 priority_jump = 1;
00095 }
00096 peers = args.reqchans;
00097 if (peers) {
00098 cur = peers;
00099 do {
00100
00101 rest = strchr(cur, '&');
00102 if (rest) {
00103 *rest = 0;
00104 rest++;
00105 }
00106 tech = cur;
00107 number = strchr(tech, '/');
00108 if (!number) {
00109 ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
00110 ast_module_user_remove(u);
00111 return -1;
00112 }
00113 *number = '\0';
00114 number++;
00115
00116 if (option_state) {
00117
00118
00119
00120
00121 snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
00122 status = inuse = ast_device_state(trychan);
00123 }
00124 if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
00125 pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
00126
00127 snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
00128 pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
00129 snprintf(tmp, sizeof(tmp), "%d", status);
00130 pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
00131 ast_hangup(tempchan);
00132 tempchan = NULL;
00133 res = 1;
00134 break;
00135 } else {
00136 snprintf(tmp, sizeof(tmp), "%d", status);
00137 pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
00138 }
00139 cur = rest;
00140 } while (cur);
00141 }
00142 if (res < 1) {
00143 pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
00144 pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");
00145 if (priority_jump || ast_opt_priority_jumping) {
00146 if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
00147 ast_module_user_remove(u);
00148 return -1;
00149 }
00150 }
00151 }
00152
00153 ast_module_user_remove(u);
00154 return 0;
00155 }
00156
00157 static int unload_module(void)
00158 {
00159 int res = 0;
00160
00161 res = ast_unregister_application(app);
00162
00163 ast_module_user_hangup_all();
00164
00165 return res;
00166 }
00167
00168 static int load_module(void)
00169 {
00170 return ast_register_application(app, chanavail_exec, synopsis, descrip);
00171 }
00172
00173 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Check channel availability");