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 #include "asterisk.h"
00028
00029 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 196758 $");
00030
00031 #include "asterisk/channel.h"
00032 #include "asterisk/pbx.h"
00033 #include "asterisk/module.h"
00034 #include "asterisk/cli.h"
00035 #include "asterisk/utils.h"
00036 #include "asterisk/frame.h"
00037
00038
00039 #define TIMEOUT 30
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 static char *orig_app(int fd, const char *chan, const char *app, const char *appdata)
00051 {
00052 char *chantech;
00053 char *chandata;
00054 int reason = 0;
00055
00056 if (ast_strlen_zero(app))
00057 return CLI_SHOWUSAGE;
00058
00059 chandata = ast_strdupa(chan);
00060
00061 chantech = strsep(&chandata, "/");
00062 if (!chandata) {
00063 ast_cli(fd, "*** No data provided after channel type! ***\n");
00064 return CLI_SHOWUSAGE;
00065 }
00066
00067 ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL);
00068
00069 return CLI_SUCCESS;
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static char *orig_exten(int fd, const char *chan, const char *data)
00081 {
00082 char *chantech;
00083 char *chandata;
00084 char *exten = NULL;
00085 char *context = NULL;
00086 int reason = 0;
00087
00088 chandata = ast_strdupa(chan);
00089
00090 chantech = strsep(&chandata, "/");
00091 if (!chandata) {
00092 ast_cli(fd, "*** No data provided after channel type! ***\n");
00093 return CLI_SHOWUSAGE;
00094 }
00095
00096 if (!ast_strlen_zero(data)) {
00097 context = ast_strdupa(data);
00098 exten = strsep(&context, "@");
00099 }
00100
00101 if (ast_strlen_zero(exten))
00102 exten = "s";
00103 if (ast_strlen_zero(context))
00104 context = "default";
00105
00106 ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL);
00107
00108 return CLI_SUCCESS;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118 static char *handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00119 {
00120 static const char * const choices[] = { "application", "extension", NULL };
00121 char *res = NULL;
00122 switch (cmd) {
00123 case CLI_INIT:
00124 e->command = "channel originate";
00125 e->usage =
00126 " There are two ways to use this command. A call can be originated between a\n"
00127 "channel and a specific application, or between a channel and an extension in\n"
00128 "the dialplan. This is similar to call files or the manager originate action.\n"
00129 "Calls originated with this command are given a timeout of 30 seconds.\n\n"
00130
00131 "Usage1: channel originate <tech/data> application <appname> [appdata]\n"
00132 " This will originate a call between the specified channel tech/data and the\n"
00133 "given application. Arguments to the application are optional. If the given\n"
00134 "arguments to the application include spaces, all of the arguments to the\n"
00135 "application need to be placed in quotation marks.\n\n"
00136
00137 "Usage2: channel originate <tech/data> extension [exten@][context]\n"
00138 " This will originate a call between the specified channel tech/data and the\n"
00139 "given extension. If no context is specified, the 'default' context will be\n"
00140 "used. If no extension is given, the 's' extension will be used.\n";
00141 return NULL;
00142 case CLI_GENERATE:
00143
00144 ast_module_ref(ast_module_info->self);
00145 if (a->pos == 3) {
00146 res = ast_cli_complete(a->word, choices, a->n);
00147 } else if (a->pos == 4) {
00148 if (!strcasecmp("application", a->argv[3])) {
00149 res = ast_complete_applications(a->line, a->word, a->n);
00150 }
00151 }
00152 ast_module_unref(ast_module_info->self);
00153 return res;
00154 }
00155
00156 if (ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3]))
00157 return CLI_SHOWUSAGE;
00158
00159
00160 ast_module_ref(ast_module_info->self);
00161
00162 if (!strcasecmp("application", a->argv[3])) {
00163 res = orig_app(a->fd, a->argv[2], a->argv[4], a->argv[5]);
00164 } else if (!strcasecmp("extension", a->argv[3])) {
00165 res = orig_exten(a->fd, a->argv[2], a->argv[4]);
00166 } else {
00167 ast_log(LOG_WARNING, "else");
00168 res = CLI_SHOWUSAGE;
00169 }
00170
00171 ast_module_unref(ast_module_info->self);
00172
00173 return res;
00174 }
00175
00176 static char *handle_redirect(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00177 {
00178 const char *name, *dest;
00179 struct ast_channel *chan;
00180 int res;
00181
00182 switch (cmd) {
00183 case CLI_INIT:
00184 e->command = "channel redirect";
00185 e->usage = ""
00186 "Usage: channel redirect <channel> <[[context,]exten,]priority>\n"
00187 " Redirect an active channel to a specified extension.\n";
00188
00189
00190
00191
00192
00193 return NULL;
00194 case CLI_GENERATE:
00195 return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
00196 }
00197
00198 if (a->argc != e->args + 2) {
00199 return CLI_SHOWUSAGE;
00200 }
00201
00202 name = a->argv[2];
00203 dest = a->argv[3];
00204
00205 if (!(chan = ast_channel_get_by_name(name))) {
00206 ast_cli(a->fd, "Channel '%s' not found\n", name);
00207 return CLI_FAILURE;
00208 }
00209
00210 res = ast_async_parseable_goto(chan, dest);
00211
00212 chan = ast_channel_unref(chan);
00213
00214 if (!res) {
00215 ast_cli(a->fd, "Channel '%s' successfully redirected to %s\n", name, dest);
00216 } else {
00217 ast_cli(a->fd, "Channel '%s' failed to be redirected to %s\n", name, dest);
00218 }
00219
00220 return res ? CLI_FAILURE : CLI_SUCCESS;
00221 }
00222
00223 static struct ast_cli_entry cli_cliorig[] = {
00224 AST_CLI_DEFINE(handle_orig, "Originate a call"),
00225 AST_CLI_DEFINE(handle_redirect, "Redirect a call"),
00226 };
00227
00228 static int unload_module(void)
00229 {
00230 return ast_cli_unregister_multiple(cli_cliorig, ARRAY_LEN(cli_cliorig));
00231 }
00232
00233 static int load_module(void)
00234 {
00235 int res;
00236 res = ast_cli_register_multiple(cli_cliorig, ARRAY_LEN(cli_cliorig));
00237 return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00238 }
00239
00240 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call origination and redirection from the CLI");