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: 361471 $");
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 res = CLI_SHOWUSAGE;
00172 }
00173
00174 ast_module_unref(ast_module_info->self);
00175
00176 return res;
00177 }
00178
00179 static char *handle_redirect(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
00180 {
00181 const char *name, *dest;
00182 struct ast_channel *chan;
00183 int res;
00184
00185 switch (cmd) {
00186 case CLI_INIT:
00187 e->command = "channel redirect";
00188 e->usage = ""
00189 "Usage: channel redirect <channel> <[[context,]exten,]priority>\n"
00190 " Redirect an active channel to a specified extension.\n";
00191
00192
00193
00194
00195
00196 return NULL;
00197 case CLI_GENERATE:
00198 return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
00199 }
00200
00201 if (a->argc != e->args + 2) {
00202 return CLI_SHOWUSAGE;
00203 }
00204
00205 name = a->argv[2];
00206 dest = a->argv[3];
00207
00208 if (!(chan = ast_channel_get_by_name(name))) {
00209 ast_cli(a->fd, "Channel '%s' not found\n", name);
00210 return CLI_FAILURE;
00211 }
00212
00213 res = ast_async_parseable_goto(chan, dest);
00214
00215 chan = ast_channel_unref(chan);
00216
00217 if (!res) {
00218 ast_cli(a->fd, "Channel '%s' successfully redirected to %s\n", name, dest);
00219 } else {
00220 ast_cli(a->fd, "Channel '%s' failed to be redirected to %s\n", name, dest);
00221 }
00222
00223 return res ? CLI_FAILURE : CLI_SUCCESS;
00224 }
00225
00226 static struct ast_cli_entry cli_cliorig[] = {
00227 AST_CLI_DEFINE(handle_orig, "Originate a call"),
00228 AST_CLI_DEFINE(handle_redirect, "Redirect a call"),
00229 };
00230
00231 static int unload_module(void)
00232 {
00233 return ast_cli_unregister_multiple(cli_cliorig, ARRAY_LEN(cli_cliorig));
00234 }
00235
00236 static int load_module(void)
00237 {
00238 int res;
00239 res = ast_cli_register_multiple(cli_cliorig, ARRAY_LEN(cli_cliorig));
00240 return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00241 }
00242
00243 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call origination and redirection from the CLI");