Asterisk - The Open Source Telephony Project  18.5.0
Enumerations | Functions | Variables
app_originate.c File Reference

Originate application. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/format_cache.h"
Include dependency graph for app_originate.c:

Go to the source code of this file.

Enumerations

enum  {
  OPT_PREDIAL_CALLEE = (1 << 0), OPT_PREDIAL_CALLER = (1 << 1), OPT_ASYNC = (1 << 2), OPT_CALLER_NUM = (1 << 3),
  OPT_CALLER_NAME = (1 << 4), OPT_CODECS = (1 << 5), OPT_VARIABLES = (1 << 6)
}
 
enum  {
  OPT_ARG_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLER, OPT_ARG_CALLER_NUM, OPT_ARG_CALLER_NAME,
  OPT_ARG_CODECS, OPT_ARG_VARIABLES, OPT_ARG_ARRAY_SIZE
}
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static int originate_exec (struct ast_channel *chan, const char *data)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Originate call" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const char app_originate [] = "Originate"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_app_option originate_exec_options [128] = { [ 'a' ] = { .flag = OPT_ASYNC }, [ 'b' ] = { .flag = OPT_PREDIAL_CALLEE , .arg_index = OPT_ARG_PREDIAL_CALLEE + 1 }, [ 'B' ] = { .flag = OPT_PREDIAL_CALLER , .arg_index = OPT_ARG_PREDIAL_CALLER + 1 }, [ 'C' ] = { .flag = OPT_CODECS , .arg_index = OPT_ARG_CODECS + 1 }, [ 'c' ] = { .flag = OPT_CALLER_NUM , .arg_index = OPT_ARG_CALLER_NUM + 1 }, [ 'n' ] = { .flag = OPT_CALLER_NAME , .arg_index = OPT_ARG_CALLER_NAME + 1 }, [ 'v' ] = { .flag = OPT_VARIABLES , .arg_index = OPT_ARG_VARIABLES + 1 }, }
 

Detailed Description

Originate application.

Author
Roberto Casas rober[email protected]to.c[email protected][email protected][email protected]diap[email protected]le.co[email protected]m
Russell Bryant russe[email protected][email protected][email protected]igium[email protected].com

Definition in file app_originate.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPT_PREDIAL_CALLEE 
OPT_PREDIAL_CALLER 
OPT_ASYNC 
OPT_CALLER_NUM 
OPT_CALLER_NAME 
OPT_CODECS 
OPT_VARIABLES 

Definition at line 142 of file app_originate.c.

142  {
143  OPT_PREDIAL_CALLEE = (1 << 0),
144  OPT_PREDIAL_CALLER = (1 << 1),
145  OPT_ASYNC = (1 << 2),
146  OPT_CALLER_NUM = (1 << 3),
147  OPT_CALLER_NAME = (1 << 4),
148  OPT_CODECS = (1 << 5),
149  OPT_VARIABLES = (1 << 6),
150 };

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_PREDIAL_CALLEE 
OPT_ARG_PREDIAL_CALLER 
OPT_ARG_CALLER_NUM 
OPT_ARG_CALLER_NAME 
OPT_ARG_CODECS 
OPT_ARG_VARIABLES 
OPT_ARG_ARRAY_SIZE 

Definition at line 152 of file app_originate.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 410 of file app_originate.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 410 of file app_originate.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 410 of file app_originate.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 401 of file app_originate.c.

References app_originate, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and originate_exec().

402 {
403  int res;
404 
406 
408 }
static int originate_exec(struct ast_channel *chan, const char *data)
static const char app_originate[]
Definition: app_originate.c:45
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ originate_exec()

static int originate_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 173 of file app_originate.c.

References ao2_cleanup, args, AST_APP_ARG, ast_app_exec_sub(), ast_app_parse_options64(), ast_autoservice_start(), ast_autoservice_stop(), ast_channel_caller(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_debug, AST_DECLARE_APP_ARGS, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_remove_by_type(), ast_format_cap_update_by_allow_disallow(), ast_format_slin, ast_log, AST_MEDIA_TYPE_UNKNOWN, AST_OUTGOING_NO_WAIT, AST_OUTGOING_WAIT, ast_pbx_outgoing_app_predial(), ast_pbx_outgoing_exten_predial(), ast_replace_subargument_delimiter(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_strsep(), ast_test_flag64, ast_variable_list_append, ast_variable_new, ast_variables_destroy(), cid_name, cid_num, exten, ast_party_caller::id, LOG_ERROR, LOG_NOTICE, LOG_WARNING, name, ast_party_id::name, NULL, ast_party_id::number, OPT_ARG_ARRAY_SIZE, OPT_ARG_CALLER_NAME, OPT_ARG_CALLER_NUM, OPT_ARG_CODECS, OPT_ARG_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLER, OPT_ARG_VARIABLES, OPT_ASYNC, OPT_CALLER_NAME, OPT_CALLER_NUM, OPT_CODECS, OPT_PREDIAL_CALLEE, OPT_PREDIAL_CALLER, OPT_VARIABLES, options, originate_exec_options, parse(), pbx_builtin_setvar_helper(), priority, S_OR, ast_party_name::str, ast_party_number::str, strsep(), text, timeout, type, and var.

Referenced by load_module().

174 {
176  AST_APP_ARG(tech_data);
177  AST_APP_ARG(type);
178  AST_APP_ARG(arg1);
179  AST_APP_ARG(arg2);
180  AST_APP_ARG(arg3);
183  );
184  struct ast_flags64 opts = { 0, };
185  char *opt_args[OPT_ARG_ARRAY_SIZE];
186  char *predial_callee = NULL;
187  char *parse, *cnum = NULL, *cname = NULL;
188 
189  struct ast_variable *vars = NULL;
190  char *chantech, *chandata;
191  int res = -1;
192  int continue_in_dialplan = 0;
193  int outgoing_status = 0;
194  unsigned int timeout = 30;
195  static const char default_exten[] = "s";
196  struct ast_format_cap *capabilities;
198 
199  ast_autoservice_start(chan);
200  if (!capabilities) {
201  goto return_cleanup;
202  }
203 
204  ast_format_cap_append(capabilities, ast_format_slin, 0);
205 
206  if (ast_strlen_zero(data)) {
207  ast_log(LOG_ERROR, "Originate() requires arguments\n");
208  goto return_cleanup;
209  }
210 
211  parse = ast_strdupa(data);
212 
213  AST_STANDARD_APP_ARGS(args, parse);
214 
215  if (args.argc < 3) {
216  ast_log(LOG_ERROR, "Incorrect number of arguments\n");
217  goto return_cleanup;
218  }
219 
220  if (!ast_strlen_zero(args.timeout)) {
221  if(sscanf(args.timeout, "%u", &timeout) != 1) {
222  ast_log(LOG_NOTICE, "Invalid timeout: '%s'. Setting timeout to 30 seconds\n", args.timeout);
223  timeout = 30;
224  }
225  }
226 
227  chandata = ast_strdupa(args.tech_data);
228  chantech = strsep(&chandata, "/");
229 
230  if (ast_strlen_zero(chandata) || ast_strlen_zero(chantech)) {
231  ast_log(LOG_ERROR, "Channel Tech/Data invalid: '%s'\n", args.tech_data);
232  goto return_cleanup;
233  }
234 
235  if (!ast_strlen_zero(args.options) &&
236  ast_app_parse_options64(originate_exec_options, &opts, opt_args, args.options)) {
237  ast_log(LOG_ERROR, "Invalid options: '%s'\n", args.options);
238  goto return_cleanup;
239  }
240 
241  /* PREDIAL: Run gosub on the caller's channel */
243  && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
244  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLER]);
245  ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
246  }
247 
249  && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLEE])) {
250  ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
251  predial_callee = opt_args[OPT_ARG_PREDIAL_CALLEE];
252  }
253 
254  if (strcasecmp(args.type, "exten") && strcasecmp(args.type, "app")) {
255  ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
256  args.type);
257  goto return_cleanup;
258  }
259 
260  if (ast_test_flag64(&opts, OPT_CODECS)) {
261  if (!ast_strlen_zero(opt_args[OPT_ARG_CODECS])) {
263  ast_format_cap_update_by_allow_disallow(capabilities, opt_args[OPT_ARG_CODECS], 1);
264  }
265  }
266 
267  if (ast_test_flag64(&opts, OPT_CALLER_NUM)) {
268  if (!ast_strlen_zero(opt_args[OPT_ARG_CALLER_NUM])) {
269  cnum = opt_args[OPT_ARG_CALLER_NUM];
270  } else if (ast_channel_caller(chan)->id.number.str) {
271  cnum = ast_channel_caller(chan)->id.number.str;
272  }
273  }
274 
275  if (ast_test_flag64(&opts, OPT_CALLER_NAME)) {
276  if (!ast_strlen_zero(opt_args[OPT_ARG_CALLER_NAME])) {
277  cname = opt_args[OPT_ARG_CALLER_NAME];
278  } else if (ast_channel_caller(chan)->id.name.str) {
279  cname = ast_channel_caller(chan)->id.name.str;
280  }
281  }
282 
283  /* Assign variables */
284  if (ast_test_flag64(&opts, OPT_VARIABLES)
285  && !ast_strlen_zero(opt_args[OPT_ARG_VARIABLES])) {
286  char *vartext;
287  char *text = opt_args[OPT_ARG_VARIABLES];
288  while ((vartext = ast_strsep(&text, '^', 0))) {
289  struct ast_variable *var;
290  char *varname, *varvalue;
291  if (!(varname = ast_strsep(&vartext, '=', 0))) {
292  ast_log(LOG_ERROR, "Variable syntax error: %s\n", vartext);
293  goto return_cleanup;
294  }
295  if (!(varvalue = ast_strsep(&vartext, '=', 0))) {
296  varvalue = ""; /* empty values are allowed */
297  }
298  var = ast_variable_new(varname, varvalue, "");
299  if (!var) {
300  ast_log(LOG_ERROR, "Failed to allocate variable: %s\n", varname);
301  goto return_cleanup;
302  }
303  ast_debug(1, "Appending variable '%s' with value '%s'", varname, varvalue);
304  ast_variable_list_append(&vars, var);
305  }
306  }
307 
308  if (!strcasecmp(args.type, "exten")) {
309  const char *cid_num = cnum;
310  const char *cid_name = cname;
311  int priority = 1; /* Initialized in case priority not specified */
312  const char *exten = args.arg2;
313 
314  if (args.argc == 5) {
315  /* Context/Exten/Priority all specified */
316  if (sscanf(args.arg3, "%30d", &priority) != 1) {
317  ast_log(LOG_ERROR, "Invalid priority: '%s'\n", args.arg3);
318  goto return_cleanup;
319  }
320  } else if (args.argc == 3) {
321  /* Exten not specified */
322  exten = default_exten;
323  }
324 
325  ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
326  chantech, chandata, args.arg1, exten, priority);
327 
328  res = ast_pbx_outgoing_exten_predial(chantech, capabilities, chandata,
329  timeout * 1000, args.arg1, exten, priority, &outgoing_status,
331  cid_num, cid_name, vars, NULL, NULL, 0, NULL,
332  predial_callee);
333  } else {
334  const char *cid_num = cnum;
335  const char *cid_name = cname;
336  ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
337  chantech, chandata, args.arg1, S_OR(args.arg2, ""));
338 
339  res = ast_pbx_outgoing_app_predial(chantech, capabilities, chandata,
340  timeout * 1000, args.arg1, args.arg2, &outgoing_status,
342  cid_num, cid_name, vars, NULL, NULL, NULL,
343  predial_callee);
344  }
345 
346  /*
347  * Getting here means that we have passed the various validation checks and
348  * have at least attempted the dial. If we have a reason (outgoing_status),
349  * we clear our error indicator so that we ultimately report the right thing
350  * to the caller.
351  */
352  if (res && outgoing_status) {
353  res = 0;
354  }
355 
356  /* We need to exit cleanly if we've gotten this far */
357  continue_in_dialplan = 1;
358 
359 return_cleanup:
360  if (res) {
361  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "FAILED");
362  } else {
363  switch (outgoing_status) {
364  case 0:
365  case AST_CONTROL_ANSWER:
366  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "SUCCESS");
367  break;
368  case AST_CONTROL_BUSY:
369  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "BUSY");
370  break;
372  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "CONGESTION");
373  break;
374  case AST_CONTROL_HANGUP:
375  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "HANGUP");
376  break;
377  case AST_CONTROL_RINGING:
378  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "RINGING");
379  break;
380  default:
381  ast_log(LOG_WARNING, "Unknown originate status result of '%d'\n",
382  outgoing_status);
383  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "UNKNOWN");
384  break;
385  }
386  }
387  if (vars) {
388  ast_variables_destroy(vars);
389  }
390  ao2_cleanup(capabilities);
391  ast_autoservice_stop(chan);
392 
393  return continue_in_dialplan ? 0 : -1;
394 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static const char type[]
Definition: chan_ooh323.c:109
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static int timeout
Definition: cdr_mysql.c:86
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
int ast_pbx_outgoing_exten_predial(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
Definition: pbx.c:7961
char * str
Subscriber name (Malloced)
Definition: channel.h:265
char * text
Definition: app_queue.c:1508
const char * args
#define NULL
Definition: resample.c:96
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
static int priority
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:164
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing)
Parse an "allow" or "deny" list and modify a format capabilities structure accordingly.
Definition: format_cap.c:320
Number structure.
Definition: app_followme.c:154
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void ast_replace_subargument_delimiter(char *s)
Replace &#39;^&#39; in a string with &#39;,&#39;.
Definition: main/utils.c:2095
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: main/utils.c:1656
#define ast_variable_new(name, value, filename)
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:2911
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Remove all formats matching a specific format type.
Definition: format_cap.c:525
#define LOG_ERROR
Definition: logger.h:285
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
static const struct ast_app_option originate_exec_options[128]
#define LOG_NOTICE
Definition: logger.h:263
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static const char name[]
Definition: cdr_mysql.c:74
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:165
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...
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:370
int ast_pbx_outgoing_app_predial(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, const struct ast_assigned_ids *assignedids, const char *predial_callee)
Definition: pbx.c:8025
static struct test_options options
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define ast_variable_list_append(head, new_var)
#define AST_APP_ARG(name)
Define an application argument.
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
#define ast_test_flag64(p, flag)
Definition: utils.h:120

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 396 of file app_originate.c.

References app_originate, and ast_unregister_application().

397 {
399 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static const char app_originate[]
Definition: app_originate.c:45

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Originate call" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 410 of file app_originate.c.

◆ app_originate

const char app_originate[] = "Originate"
static

Definition at line 45 of file app_originate.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 410 of file app_originate.c.

◆ originate_exec_options

const struct ast_app_option originate_exec_options[128] = { [ 'a' ] = { .flag = OPT_ASYNC }, [ 'b' ] = { .flag = OPT_PREDIAL_CALLEE , .arg_index = OPT_ARG_PREDIAL_CALLEE + 1 }, [ 'B' ] = { .flag = OPT_PREDIAL_CALLER , .arg_index = OPT_ARG_PREDIAL_CALLER + 1 }, [ 'C' ] = { .flag = OPT_CODECS , .arg_index = OPT_ARG_CODECS + 1 }, [ 'c' ] = { .flag = OPT_CALLER_NUM , .arg_index = OPT_ARG_CALLER_NUM + 1 }, [ 'n' ] = { .flag = OPT_CALLER_NAME , .arg_index = OPT_ARG_CALLER_NAME + 1 }, [ 'v' ] = { .flag = OPT_VARIABLES , .arg_index = OPT_ARG_VARIABLES + 1 }, }
static

Definition at line 171 of file app_originate.c.

Referenced by originate_exec().