Wed Jan 8 2020 09:49:49

Asterisk developer's documentation


res_clioriginate.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2005 - 2006, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \author Russell Bryant <russell@digium.com>
22  *
23  * \brief Originate calls via the CLI
24  *
25  */
26 
27 /*** MODULEINFO
28  <support_level>core</support_level>
29  ***/
30 
31 #include "asterisk.h"
32 
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 361471 $");
34 
35 #include "asterisk/channel.h"
36 #include "asterisk/pbx.h"
37 #include "asterisk/module.h"
38 #include "asterisk/cli.h"
39 #include "asterisk/utils.h"
40 #include "asterisk/frame.h"
41 
42 /*! The timeout for originated calls, in seconds */
43 #define TIMEOUT 30
44 
45 /*!
46  * \brief orginate a call from the CLI
47  * \param fd file descriptor for cli
48  * \param chan channel to create type/data
49  * \param app application you want to run
50  * \param appdata data for application
51  * \retval CLI_SUCCESS on success.
52  * \retval CLI_SHOWUSAGE on failure.
53 */
54 static char *orig_app(int fd, const char *chan, const char *app, const char *appdata)
55 {
56  char *chantech;
57  char *chandata;
58  int reason = 0;
59 
60  if (ast_strlen_zero(app))
61  return CLI_SHOWUSAGE;
62 
63  chandata = ast_strdupa(chan);
64 
65  chantech = strsep(&chandata, "/");
66  if (!chandata) {
67  ast_cli(fd, "*** No data provided after channel type! ***\n");
68  return CLI_SHOWUSAGE;
69  }
70 
71  ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL);
72 
73  return CLI_SUCCESS;
74 }
75 
76 /*!
77  * \brief orginate from extension
78  * \param fd file descriptor for cli
79  * \param chan channel to create type/data
80  * \param data contains exten\@context
81  * \retval CLI_SUCCESS on success.
82  * \retval CLI_SHOWUSAGE on failure.
83 */
84 static char *orig_exten(int fd, const char *chan, const char *data)
85 {
86  char *chantech;
87  char *chandata;
88  char *exten = NULL;
89  char *context = NULL;
90  int reason = 0;
91 
92  chandata = ast_strdupa(chan);
93 
94  chantech = strsep(&chandata, "/");
95  if (!chandata) {
96  ast_cli(fd, "*** No data provided after channel type! ***\n");
97  return CLI_SHOWUSAGE;
98  }
99 
100  if (!ast_strlen_zero(data)) {
101  context = ast_strdupa(data);
102  exten = strsep(&context, "@");
103  }
104 
105  if (ast_strlen_zero(exten))
106  exten = "s";
107  if (ast_strlen_zero(context))
108  context = "default";
109 
110  ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL);
111 
112  return CLI_SUCCESS;
113 }
114 
115 /*!
116  * \brief handle for orgination app or exten.
117  * \param e pointer to the CLI structure to initialize
118  * \param cmd operation to execute
119  * \param a structure that contains either application or extension arguments
120  * \retval CLI_SUCCESS on success.
121  * \retval CLI_SHOWUSAGE on failure.*/
122 static char *handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
123 {
124  static const char * const choices[] = { "application", "extension", NULL };
125  char *res = NULL;
126  switch (cmd) {
127  case CLI_INIT:
128  e->command = "channel originate";
129  e->usage =
130  " There are two ways to use this command. A call can be originated between a\n"
131  "channel and a specific application, or between a channel and an extension in\n"
132  "the dialplan. This is similar to call files or the manager originate action.\n"
133  "Calls originated with this command are given a timeout of 30 seconds.\n\n"
134 
135  "Usage1: channel originate <tech/data> application <appname> [appdata]\n"
136  " This will originate a call between the specified channel tech/data and the\n"
137  "given application. Arguments to the application are optional. If the given\n"
138  "arguments to the application include spaces, all of the arguments to the\n"
139  "application need to be placed in quotation marks.\n\n"
140 
141  "Usage2: channel originate <tech/data> extension [exten@][context]\n"
142  " This will originate a call between the specified channel tech/data and the\n"
143  "given extension. If no context is specified, the 'default' context will be\n"
144  "used. If no extension is given, the 's' extension will be used.\n";
145  return NULL;
146  case CLI_GENERATE:
147  /* ugly, can be removed when CLI entries have ast_module pointers */
149  if (a->pos == 3) {
150  res = ast_cli_complete(a->word, choices, a->n);
151  } else if (a->pos == 4) {
152  if (!strcasecmp("application", a->argv[3])) {
153  res = ast_complete_applications(a->line, a->word, a->n);
154  }
155  }
157  return res;
158  }
159 
160  if (ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3]))
161  return CLI_SHOWUSAGE;
162 
163  /* ugly, can be removed when CLI entries have ast_module pointers */
165 
166  if (!strcasecmp("application", a->argv[3])) {
167  res = orig_app(a->fd, a->argv[2], a->argv[4], a->argv[5]);
168  } else if (!strcasecmp("extension", a->argv[3])) {
169  res = orig_exten(a->fd, a->argv[2], a->argv[4]);
170  } else {
171  res = CLI_SHOWUSAGE;
172  }
173 
175 
176  return res;
177 }
178 
179 static char *handle_redirect(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
180 {
181  const char *name, *dest;
182  struct ast_channel *chan;
183  int res;
184 
185  switch (cmd) {
186  case CLI_INIT:
187  e->command = "channel redirect";
188  e->usage = ""
189  "Usage: channel redirect <channel> <[[context,]exten,]priority>\n"
190  " Redirect an active channel to a specified extension.\n";
191  /*! \todo It would be nice to be able to redirect 2 channels at the same
192  * time like you can with AMI redirect. However, it is not possible to acquire
193  * two channels without the potential for a deadlock with how ast_channel structs
194  * are managed today. Once ast_channel is a refcounted object, this command
195  * will be able to support that. */
196  return NULL;
197  case CLI_GENERATE:
198  return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
199  }
200 
201  if (a->argc != e->args + 2) {
202  return CLI_SHOWUSAGE;
203  }
204 
205  name = a->argv[2];
206  dest = a->argv[3];
207 
208  if (!(chan = ast_channel_get_by_name(name))) {
209  ast_cli(a->fd, "Channel '%s' not found\n", name);
210  return CLI_FAILURE;
211  }
212 
213  res = ast_async_parseable_goto(chan, dest);
214 
215  chan = ast_channel_unref(chan);
216 
217  if (!res) {
218  ast_cli(a->fd, "Channel '%s' successfully redirected to %s\n", name, dest);
219  } else {
220  ast_cli(a->fd, "Channel '%s' failed to be redirected to %s\n", name, dest);
221  }
222 
223  return res ? CLI_FAILURE : CLI_SUCCESS;
224 }
225 
226 static struct ast_cli_entry cli_cliorig[] = {
227  AST_CLI_DEFINE(handle_orig, "Originate a call"),
228  AST_CLI_DEFINE(handle_redirect, "Redirect a call"),
229 };
230 
231 static int unload_module(void)
232 {
233  return ast_cli_unregister_multiple(cli_cliorig, ARRAY_LEN(cli_cliorig));
234 }
235 
236 static int load_module(void)
237 {
238  int res;
239  res = ast_cli_register_multiple(cli_cliorig, ARRAY_LEN(cli_cliorig));
241 }
242 
243 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call origination and redirection from the CLI");
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
char * strsep(char **str, const char *delims)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
char * ast_complete_applications(const char *line, const char *word, int state)
Command completion for the list of installed applications.
Definition: pbx.c:11336
Definition: cli.h:146
static int unload_module(void)
#define TIMEOUT
static struct ast_cli_entry cli_cliorig[]
static char * orig_app(int fd, const char *chan, const char *app, const char *appdata)
orginate a call from the CLI
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
Utility functions.
int args
This gets set in ast_cli_register()
Definition: cli.h:179
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: cli.c:1535
struct ast_module * self
Definition: module.h:227
static const char app[]
Definition: app_adsiprog.c:49
General Asterisk PBX channel definitions.
const int fd
Definition: cli.h:153
static char * handle_orig(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
handle for orgination app or exten.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const int n
Definition: cli.h:159
Asterisk internal frame definitions.
static char * orig_exten(int fd, const char *chan, const char *data)
orginate from extension
Core PBX routines and definitions.
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
Definition: pbx.c:9375
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int load_module(void)
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
int ast_async_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:11331
#define CLI_SUCCESS
Definition: cli.h:43
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
Standard Command Line Interface.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
const int pos
Definition: cli.h:158
static char * handle_redirect(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: cli.c:1547
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
Definition: pbx.c:9544
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
Asterisk module definitions.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300