Wed Jan 8 2020 09:49:40

Asterisk developer's documentation


app_originate.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008, Roberto Casas.
5  * Copyright (C) 2008, Digium, Inc.
6  *
7  * Roberto Casas <roberto.casas@diaple.com>
8  * Russell Bryant <russell@digium.com>
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20 
21 /*!
22  * \file
23  * \brief Originate application
24  *
25  * \author Roberto Casas <roberto.casas@diaple.com>
26  * \author Russell Bryant <russell@digium.com>
27  *
28  * \ingroup applications
29  *
30  * \todo Make a way to be able to set variables (and functions) on the outbound
31  * channel, similar to the Variable headers for the AMI Originate, and the
32  * Set options for call files.
33  */
34 
35 /*** MODULEINFO
36  <support_level>core</support_level>
37  ***/
38 
39 #include "asterisk.h"
40 
41 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
42 
43 #include "asterisk/file.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/pbx.h"
46 #include "asterisk/module.h"
47 #include "asterisk/app.h"
48 
49 static const char app_originate[] = "Originate";
50 
51 /*** DOCUMENTATION
52  <application name="Originate" language="en_US">
53  <synopsis>
54  Originate a call.
55  </synopsis>
56  <syntax>
57  <parameter name="tech_data" required="true">
58  <para>Channel technology and data for creating the outbound channel.
59  For example, SIP/1234.</para>
60  </parameter>
61  <parameter name="type" required="true">
62  <para>This should be <literal>app</literal> or <literal>exten</literal>, depending on whether the outbound channel should be connected to an application or extension.</para>
63  </parameter>
64  <parameter name="arg1" required="true">
65  <para>If the type is <literal>app</literal>, then this is the application name. If the type is <literal>exten</literal>, then this is the context that the channel will be sent to.</para>
66  </parameter>
67  <parameter name="arg2" required="false">
68  <para>If the type is <literal>app</literal>, then this is the data passed as arguments to the application. If the type is <literal>exten</literal>, then this is the extension that the channel will be sent to.</para>
69  </parameter>
70  <parameter name="arg3" required="false">
71  <para>If the type is <literal>exten</literal>, then this is the priority that the channel is sent to. If the type is <literal>app</literal>, then this parameter is ignored.</para>
72  </parameter>
73  </syntax>
74  <description>
75  <para>This application originates an outbound call and connects it to a specified extension or application. This application will block until the outgoing call fails or gets answered. At that point, this application will exit with the status variable set and dialplan processing will continue.</para>
76 
77  <para>This application sets the following channel variable before exiting:</para>
78  <variablelist>
79  <variable name="ORIGINATE_STATUS">
80  <para>This indicates the result of the call origination.</para>
81  <value name="FAILED"/>
82  <value name="SUCCESS"/>
83  <value name="BUSY"/>
84  <value name="CONGESTION"/>
85  <value name="HANGUP"/>
86  <value name="RINGING"/>
87  <value name="UNKNOWN">
88  In practice, you should never see this value. Please report it to the issue tracker if you ever see it.
89  </value>
90  </variable>
91  </variablelist>
92  </description>
93  </application>
94  ***/
95 
96 static int originate_exec(struct ast_channel *chan, const char *data)
97 {
99  AST_APP_ARG(tech_data);
100  AST_APP_ARG(type);
101  AST_APP_ARG(arg1);
102  AST_APP_ARG(arg2);
103  AST_APP_ARG(arg3);
104  );
105  char *parse;
106  char *chantech, *chandata;
107  int res = -1;
108  int outgoing_status = 0;
109  static const unsigned int timeout = 30;
110  static const char default_exten[] = "s";
111 
112  ast_autoservice_start(chan);
113 
114  if (ast_strlen_zero(data)) {
115  ast_log(LOG_ERROR, "Originate() requires arguments\n");
116  goto return_cleanup;
117  }
118 
119  parse = ast_strdupa(data);
120 
121  AST_STANDARD_APP_ARGS(args, parse);
122 
123  if (args.argc < 3) {
124  ast_log(LOG_ERROR, "Incorrect number of arguments\n");
125  goto return_cleanup;
126  }
127 
128  chandata = ast_strdupa(args.tech_data);
129  chantech = strsep(&chandata, "/");
130 
131  if (ast_strlen_zero(chandata) || ast_strlen_zero(chantech)) {
132  ast_log(LOG_ERROR, "Channel Tech/Data invalid: '%s'\n", args.tech_data);
133  goto return_cleanup;
134  }
135 
136  if (!strcasecmp(args.type, "exten")) {
137  int priority = 1; /* Initialized in case priority not specified */
138  const char *exten = args.arg2;
139 
140  if (args.argc == 5) {
141  /* Context/Exten/Priority all specified */
142  if (sscanf(args.arg3, "%30d", &priority) != 1) {
143  ast_log(LOG_ERROR, "Invalid priority: '%s'\n", args.arg3);
144  goto return_cleanup;
145  }
146  } else if (args.argc == 3) {
147  /* Exten not specified */
148  exten = default_exten;
149  }
150 
151  ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
152  chantech, chandata, args.arg1, exten, priority);
153 
154  ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata,
155  timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
156  NULL, NULL, NULL, NULL);
157  } else if (!strcasecmp(args.type, "app")) {
158  ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
159  chantech, chandata, args.arg1, S_OR(args.arg2, ""));
160 
161  ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata,
162  timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
163  NULL, NULL, NULL, NULL);
164  } else {
165  ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
166  args.type);
167  goto return_cleanup;
168  }
169 
170  res = 0;
171 
172 return_cleanup:
173  if (res) {
174  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "FAILED");
175  } else {
176  switch (outgoing_status) {
177  case 0:
178  case AST_CONTROL_ANSWER:
179  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "SUCCESS");
180  break;
181  case AST_CONTROL_BUSY:
182  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "BUSY");
183  break;
185  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "CONGESTION");
186  break;
187  case AST_CONTROL_HANGUP:
188  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "HANGUP");
189  break;
190  case AST_CONTROL_RINGING:
191  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "RINGING");
192  break;
193  default:
194  ast_log(LOG_WARNING, "Unknown originate status result of '%d'\n",
195  outgoing_status);
196  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "UNKNOWN");
197  break;
198  }
199  }
200 
201  ast_autoservice_stop(chan);
202 
203  return res;
204 }
205 
206 static int unload_module(void)
207 {
208  return ast_unregister_application(app_originate);
209 }
210 
211 static int load_module(void)
212 {
213  int res;
214 
215  res = ast_register_application_xml(app_originate, originate_exec);
216 
218 }
219 
static int load_module(void)
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
Asterisk main include file. File version handling, generic pbx functions.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
char * strsep(char **str, const char *delims)
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
static int originate_exec(struct ast_channel *chan, const char *data)
Definition: app_originate.c:96
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static const char app_originate[]
Definition: app_originate.c:49
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
General Asterisk PBX channel definitions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Core PBX routines and definitions.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
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
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int unload_module(void)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
static const char type[]
Definition: chan_nbs.c:57
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
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
Asterisk module definitions.
union ast_frame::@172 data
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180