Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 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};
@ 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 152 of file app_originate.c.

152 {
159 /* note: this entry _MUST_ be the last one in the enum */
161};
@ 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 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.

402{
403 int res;
404
406
408}
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 173 of file app_originate.c.

174{
176 AST_APP_ARG(tech_data);
178 AST_APP_ARG(arg1);
179 AST_APP_ARG(arg2);
180 AST_APP_ARG(arg3);
181 AST_APP_ARG(timeout);
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
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
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 */
245 ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
246 }
247
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])) {
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 */
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);
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
359return_cleanup:
360 if (res) {
361 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "FAILED");
362 } else {
363 switch (outgoing_status) {
364 case 0:
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;
375 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "HANGUP");
376 break;
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) {
389 }
390 ao2_cleanup(capabilities);
392
393 return continue_in_dialplan ? 0 : -1;
394}
static const struct ast_app_option originate_exec_options[128]
char * text
Definition: app_queue.c:1668
#define var
Definition: ast_expr2f.c:605
#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
char * strsep(char **str, const char *delims)
#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:7926
@ AST_OUTGOING_NO_WAIT
Definition: pbx.h:1140
@ AST_OUTGOING_WAIT
Definition: pbx.h:1141
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:7990
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:154
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 396 of file app_originate.c.

397{
399}
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 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().