Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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 = ASTERISK_GPL_KEY , .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[]
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:1772
#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[]
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
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.
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:1260
@ 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:7951
@ AST_OUTGOING_NO_WAIT
Definition pbx.h:1143
@ AST_OUTGOING_WAIT
Definition pbx.h:1144
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:8015
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.
static struct @519 args
#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:1871
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition utils.h:225
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.
static struct test_options options
#define ast_test_flag64(p, flag)
Definition utils.h:140
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
Definition utils.c:2379

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 = ASTERISK_GPL_KEY , .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().