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