Asterisk - The Open Source Telephony Project GIT-master-7805f28
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 = 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_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.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_CODECS 
OPT_VARIABLES 

Definition at line 145 of file app_originate.c.

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

◆ 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 155 of file app_originate.c.

155 {
162 /* note: this entry _MUST_ be the last one in the enum */
164};
@ OPT_ARG_VARIABLES
@ OPT_ARG_CALLER_NAME
@ OPT_ARG_PREDIAL_CALLEE
@ OPT_ARG_CODECS
@ OPT_ARG_CALLER_NUM
@ OPT_ARG_PREDIAL_CALLER
@ OPT_ARG_ARRAY_SIZE

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 413 of file app_originate.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 413 of file app_originate.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 413 of file app_originate.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 404 of file app_originate.c.

405{
406 int res;
407
409
411}
static const char app_originate[]
Definition: app_originate.c:45
static int originate_exec(struct ast_channel *chan, const char *data)
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
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:640

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

◆ originate_exec()

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

Definition at line 176 of file app_originate.c.

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

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(), 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, pbx_builtin_setvar_helper(), priority, S_OR, ast_party_name::str, ast_party_number::str, strsep(), text, type, and var.

Referenced by load_module().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 399 of file app_originate.c.

400{
402}
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References app_originate, and ast_unregister_application().

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 413 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 413 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 174 of file app_originate.c.

Referenced by originate_exec().