45 static const char app_originate[] =
"Originate";
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),
153 OPT_ARG_PREDIAL_CALLEE,
154 OPT_ARG_PREDIAL_CALLER,
173 static int originate_exec(
struct ast_channel *chan,
const char *data)
185 char *opt_args[OPT_ARG_ARRAY_SIZE];
186 char *predial_callee = NULL;
187 char *parse, *cnum = NULL, *cname = NULL;
190 char *chantech, *chandata;
192 int continue_in_dialplan = 0;
193 int outgoing_status = 0;
194 unsigned int timeout = 30;
195 static const char default_exten[] =
"s";
206 if (ast_strlen_zero(data)) {
207 ast_log(LOG_ERROR,
"Originate() requires arguments\n");
216 ast_log(LOG_ERROR,
"Incorrect number of arguments\n");
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);
228 chantech = strsep(&chandata,
"/");
230 if (ast_strlen_zero(chandata) || ast_strlen_zero(chantech)) {
231 ast_log(LOG_ERROR,
"Channel Tech/Data invalid: '%s'\n", args.tech_data);
235 if (!ast_strlen_zero(args.options) &&
237 ast_log(LOG_ERROR,
"Invalid options: '%s'\n", args.options);
242 if (ast_test_flag64(&opts, OPT_PREDIAL_CALLER)
243 && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
248 if (ast_test_flag64(&opts, OPT_PREDIAL_CALLEE)
249 && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLEE])) {
251 predial_callee = opt_args[OPT_ARG_PREDIAL_CALLEE];
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",
260 if (ast_test_flag64(&opts, OPT_CODECS)) {
261 if (!ast_strlen_zero(opt_args[OPT_ARG_CODECS])) {
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) {
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;
284 if (ast_test_flag64(&opts, OPT_VARIABLES)
285 && !ast_strlen_zero(opt_args[OPT_ARG_VARIABLES])) {
287 char *text = opt_args[OPT_ARG_VARIABLES];
288 while ((vartext =
ast_strsep(&text,
'^', 0))) {
290 char *varname, *varvalue;
291 if (!(varname =
ast_strsep(&vartext,
'=', 0))) {
292 ast_log(LOG_ERROR,
"Variable syntax error: %s\n", vartext);
295 if (!(varvalue =
ast_strsep(&vartext,
'=', 0))) {
298 var = ast_variable_new(varname, varvalue,
"");
300 ast_log(LOG_ERROR,
"Failed to allocate variable: %s\n", varname);
303 ast_debug(1,
"Appending variable '%s' with value '%s'", varname, varvalue);
304 ast_variable_list_append(&vars, var);
308 if (!strcasecmp(args.type,
"exten")) {
309 const char *cid_num = cnum;
310 const char *cid_name = cname;
312 const char *exten = args.arg2;
314 if (args.argc == 5) {
316 if (sscanf(args.arg3,
"%30d", &priority) != 1) {
317 ast_log(LOG_ERROR,
"Invalid priority: '%s'\n", args.arg3);
320 }
else if (args.argc == 3) {
322 exten = default_exten;
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);
329 timeout * 1000, args.arg1, exten, priority, &outgoing_status,
331 cid_num, cid_name, vars, NULL, NULL, 0, NULL,
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,
""));
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,
352 if (res && outgoing_status) {
357 continue_in_dialplan = 1;
363 switch (outgoing_status) {
381 ast_log(LOG_WARNING,
"Unknown originate status result of '%d'\n",
390 ao2_cleanup(capabilities);
393 return continue_in_dialplan ? 0 : -1;
396 static int unload_module(
void)
401 static int load_module(
void)
Main Channel structure associated with a channel.
char * str
Subscriber phone number (Malloced)
Asterisk main include file. File version handling, generic pbx functions.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
struct ast_party_name name
Subscriber name.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
Structure for variables, used for configurations and for channel variables.
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)
char * str
Subscriber name (Malloced)
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
Structure used to handle a large number of boolean flags == used only in app_dial?
int ast_unregister_application(const char *app)
Unregister an application.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
struct ast_party_id id
Caller party ID.
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
General Asterisk PBX channel definitions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
#define ast_debug(level,...)
Log a DEBUG message.
Core PBX routines and definitions.
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.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
Module has failed to load, may be in an inconsistent state.
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 S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
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.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
#define AST_APP_ARG(name)
Define an application argument.
struct ast_party_number number
Subscriber phone number.