Asterisk - The Open Source Telephony Project  GIT-master-b7027de
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"

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_VARIABLES = (1 << 5)
}
 
enum  {
  OPT_ARG_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLER, OPT_ARG_CALLER_NUM, OPT_ARG_CALLER_NAME,
  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 = AST_BUILDOPT_SUM, .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_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.nosp@m.to.c.nosp@m.asas@.nosp@m.diap.nosp@m.le.co.nosp@m.m
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..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_VARIABLES 

Definition at line 138 of file app_originate.c.

138  {
139  OPT_PREDIAL_CALLEE = (1 << 0),
140  OPT_PREDIAL_CALLER = (1 << 1),
141  OPT_ASYNC = (1 << 2),
142  OPT_CALLER_NUM = (1 << 3),
143  OPT_CALLER_NAME = (1 << 4),
144  OPT_VARIABLES = (1 << 5),
145 };

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_PREDIAL_CALLEE 
OPT_ARG_PREDIAL_CALLER 
OPT_ARG_CALLER_NUM 
OPT_ARG_CALLER_NAME 
OPT_ARG_VARIABLES 
OPT_ARG_ARRAY_SIZE 

Definition at line 147 of file app_originate.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 403 of file app_originate.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 403 of file app_originate.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 403 of file app_originate.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 394 of file app_originate.c.

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

395 {
396  int res;
397 
399 
401 }
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 166 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_slin, ast_format_slin12, ast_format_slin16, ast_format_slin192, ast_format_slin24, ast_format_slin32, ast_format_slin44, ast_format_slin48, ast_format_slin96, ast_log, 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_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLER, OPT_ARG_VARIABLES, OPT_ASYNC, OPT_CALLER_NAME, OPT_CALLER_NUM, 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().

167 {
169  AST_APP_ARG(tech_data);
170  AST_APP_ARG(type);
171  AST_APP_ARG(arg1);
172  AST_APP_ARG(arg2);
173  AST_APP_ARG(arg3);
176  );
177  struct ast_flags64 opts = { 0, };
178  char *opt_args[OPT_ARG_ARRAY_SIZE];
179  char *predial_callee = NULL;
180  char *parse, *cnum = NULL, *cname = NULL;
181 
182  struct ast_variable *vars = NULL;
183  char *chantech, *chandata;
184  int res = -1;
185  int continue_in_dialplan = 0;
186  int outgoing_status = 0;
187  unsigned int timeout = 30;
188  static const char default_exten[] = "s";
190 
191  ast_autoservice_start(chan);
192  if (!cap_slin) {
193  goto return_cleanup;
194  }
195 
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_CALLER_NUM)) {
261  if (!ast_strlen_zero(opt_args[OPT_ARG_CALLER_NUM])) {
262  cnum = opt_args[OPT_ARG_CALLER_NUM];
263  } else if (ast_channel_caller(chan)->id.number.str) {
264  cnum = ast_channel_caller(chan)->id.number.str;
265  }
266  }
267 
268  if (ast_test_flag64(&opts, OPT_CALLER_NAME)) {
269  if (!ast_strlen_zero(opt_args[OPT_ARG_CALLER_NAME])) {
270  cname = opt_args[OPT_ARG_CALLER_NAME];
271  } else if (ast_channel_caller(chan)->id.name.str) {
272  cname = ast_channel_caller(chan)->id.name.str;
273  }
274  }
275 
276  /* Assign variables */
277  if (ast_test_flag64(&opts, OPT_VARIABLES)
278  && !ast_strlen_zero(opt_args[OPT_ARG_VARIABLES])) {
279  char *vartext;
280  char *text = opt_args[OPT_ARG_VARIABLES];
281  while ((vartext = ast_strsep(&text, '^', 0))) {
282  struct ast_variable *var;
283  char *varname, *varvalue;
284  if (!(varname = ast_strsep(&vartext, '=', 0))) {
285  ast_log(LOG_ERROR, "Variable syntax error: %s\n", vartext);
286  goto return_cleanup;
287  }
288  if (!(varvalue = ast_strsep(&vartext, '=', 0))) {
289  varvalue = ""; /* empty values are allowed */
290  }
291  var = ast_variable_new(varname, varvalue, "");
292  if (!var) {
293  ast_log(LOG_ERROR, "Failed to allocate variable: %s\n", varname);
294  goto return_cleanup;
295  }
296  ast_debug(1, "Appending variable '%s' with value '%s'", varname, varvalue);
297  ast_variable_list_append(&vars, var);
298  }
299  }
300 
301  if (!strcasecmp(args.type, "exten")) {
302  const char *cid_num = cnum;
303  const char *cid_name = cname;
304  int priority = 1; /* Initialized in case priority not specified */
305  const char *exten = args.arg2;
306 
307  if (args.argc == 5) {
308  /* Context/Exten/Priority all specified */
309  if (sscanf(args.arg3, "%30d", &priority) != 1) {
310  ast_log(LOG_ERROR, "Invalid priority: '%s'\n", args.arg3);
311  goto return_cleanup;
312  }
313  } else if (args.argc == 3) {
314  /* Exten not specified */
315  exten = default_exten;
316  }
317 
318  ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
319  chantech, chandata, args.arg1, exten, priority);
320 
321  res = ast_pbx_outgoing_exten_predial(chantech, cap_slin, chandata,
322  timeout * 1000, args.arg1, exten, priority, &outgoing_status,
324  cid_num, cid_name, vars, NULL, NULL, 0, NULL,
325  predial_callee);
326  } else {
327  const char *cid_num = cnum;
328  const char *cid_name = cname;
329  ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
330  chantech, chandata, args.arg1, S_OR(args.arg2, ""));
331 
332  res = ast_pbx_outgoing_app_predial(chantech, cap_slin, chandata,
333  timeout * 1000, args.arg1, args.arg2, &outgoing_status,
335  cid_num, cid_name, vars, NULL, NULL, NULL,
336  predial_callee);
337  }
338 
339  /*
340  * Getting here means that we have passed the various validation checks and
341  * have at least attempted the dial. If we have a reason (outgoing_status),
342  * we clear our error indicator so that we ultimately report the right thing
343  * to the caller.
344  */
345  if (res && outgoing_status) {
346  res = 0;
347  }
348 
349  /* We need to exit cleanly if we've gotten this far */
350  continue_in_dialplan = 1;
351 
352 return_cleanup:
353  if (res) {
354  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "FAILED");
355  } else {
356  switch (outgoing_status) {
357  case 0:
358  case AST_CONTROL_ANSWER:
359  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "SUCCESS");
360  break;
361  case AST_CONTROL_BUSY:
362  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "BUSY");
363  break;
365  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "CONGESTION");
366  break;
367  case AST_CONTROL_HANGUP:
368  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "HANGUP");
369  break;
370  case AST_CONTROL_RINGING:
371  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "RINGING");
372  break;
373  default:
374  ast_log(LOG_WARNING, "Unknown originate status result of '%d'\n",
375  outgoing_status);
376  pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "UNKNOWN");
377  break;
378  }
379  }
380  if (vars) {
381  ast_variables_destroy(vars);
382  }
383  ao2_cleanup(cap_slin);
384  ast_autoservice_stop(chan);
385 
386  return continue_in_dialplan ? 0 : -1;
387 }
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
struct ast_format * ast_format_slin192
Built-in cached signed linear 192kHz format.
Definition: format_cache.c:81
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
struct ast_format * ast_format_slin32
Built-in cached signed linear 32kHz format.
Definition: format_cache.c:61
struct ast_format * ast_format_slin96
Built-in cached signed linear 96kHz format.
Definition: format_cache.c:76
#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
struct ast_format * ast_format_slin24
Built-in cached signed linear 24kHz format.
Definition: format_cache.c:56
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
Number structure.
Definition: app_followme.c:154
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
struct ast_format * ast_format_slin12
Built-in cached signed linear 12kHz format.
Definition: format_cache.c:46
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
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:2834
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
#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
#define ast_strlen_zero(a)
Definition: muted.c:73
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
struct ast_format * ast_format_slin44
Built-in cached signed linear 44kHz format.
Definition: format_cache.c:66
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
Definition: format_cache.c:51
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)
struct ast_format * ast_format_slin48
Built-in cached signed linear 48kHz format.
Definition: format_cache.c:71
#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 389 of file app_originate.c.

References app_originate, and ast_unregister_application().

390 {
392 }
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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 403 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 403 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_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 164 of file app_originate.c.

Referenced by originate_exec().