mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-24 06:53:41 +00:00
Revert the pre-dial addition.
The code may be just fine, but it had not received a "ship it!" on review board yet. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@359857 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -131,12 +131,6 @@ Applications
|
|||||||
manually specify timezone and format) There are other beneftis eg. format can
|
manually specify timezone and format) There are other beneftis eg. format can
|
||||||
now be used without specifying time zone as well.
|
now be used without specifying time zone as well.
|
||||||
|
|
||||||
* Added 'b' and 'B' options to Dial. These options will allow you to run
|
|
||||||
last-minute dialplan on the caller and callee channels while the Dial
|
|
||||||
application is executing, but before the call is started. For example you
|
|
||||||
can use the 'b' option to run dialplan on the callee channel to get the name
|
|
||||||
of the newly created channel right away.
|
|
||||||
|
|
||||||
Parking
|
Parking
|
||||||
------------
|
------------
|
||||||
* New per parking lot options: comebackcontext and comebackdialtime. See
|
* New per parking lot options: comebackcontext and comebackdialtime. See
|
||||||
|
@@ -108,21 +108,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
channel before doing anything on the called channel. You will rarely need to use
|
channel before doing anything on the called channel. You will rarely need to use
|
||||||
this option, the default behavior is adequate in most cases.</para>
|
this option, the default behavior is adequate in most cases.</para>
|
||||||
</option>
|
</option>
|
||||||
<option name="b" argsep=",">
|
|
||||||
<para>Before initiating the actual call, Gosub to the specified
|
|
||||||
context,exten,priority using the newly created channel(s).</para>
|
|
||||||
<para>The Gosub will be executed for each destination channel</para>
|
|
||||||
<argument name="context" required="true"/>
|
|
||||||
<argument name="exten" required="true"/>
|
|
||||||
<argument name="priority" required="true"/>
|
|
||||||
</option>
|
|
||||||
<option name="B" argsep=",">
|
|
||||||
<para>Before initiating the actual call, Gosub to the specified
|
|
||||||
context,exten,priority using the current channel</para>
|
|
||||||
<argument name="context" required="true"/>
|
|
||||||
<argument name="exten" required="true"/>
|
|
||||||
<argument name="priority" required="true"/>
|
|
||||||
</option>
|
|
||||||
<option name="C">
|
<option name="C">
|
||||||
<para>Reset the call detail record (CDR) for this call.</para>
|
<para>Reset the call detail record (CDR) for this call.</para>
|
||||||
</option>
|
</option>
|
||||||
@@ -605,8 +590,6 @@ enum {
|
|||||||
#define OPT_FORCE_CID_TAG (1LLU << 38)
|
#define OPT_FORCE_CID_TAG (1LLU << 38)
|
||||||
#define OPT_FORCE_CID_PRES (1LLU << 39)
|
#define OPT_FORCE_CID_PRES (1LLU << 39)
|
||||||
#define OPT_CALLER_ANSWER (1LLU << 40)
|
#define OPT_CALLER_ANSWER (1LLU << 40)
|
||||||
#define OPT_PREDIAL_CALLEE_GOSUB (1LLU << 41)
|
|
||||||
#define OPT_PREDIAL_CALLER_GOSUB (1LLU << 42)
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_ARG_ANNOUNCE = 0,
|
OPT_ARG_ANNOUNCE = 0,
|
||||||
@@ -626,8 +609,6 @@ enum {
|
|||||||
OPT_ARG_FORCECLID,
|
OPT_ARG_FORCECLID,
|
||||||
OPT_ARG_FORCE_CID_TAG,
|
OPT_ARG_FORCE_CID_TAG,
|
||||||
OPT_ARG_FORCE_CID_PRES,
|
OPT_ARG_FORCE_CID_PRES,
|
||||||
OPT_ARG_PREDIAL_CALLER_GOSUB,
|
|
||||||
OPT_ARG_PREDIAL_CALLEE_GOSUB,
|
|
||||||
/* note: this entry _MUST_ be the last one in the enum */
|
/* note: this entry _MUST_ be the last one in the enum */
|
||||||
OPT_ARG_ARRAY_SIZE,
|
OPT_ARG_ARRAY_SIZE,
|
||||||
};
|
};
|
||||||
@@ -671,14 +652,12 @@ AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
|
|||||||
AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
|
AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
|
||||||
AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
|
AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
|
||||||
AST_APP_OPTION('z', OPT_CANCEL_TIMEOUT),
|
AST_APP_OPTION('z', OPT_CANCEL_TIMEOUT),
|
||||||
AST_APP_OPTION_ARG('b', OPT_PREDIAL_CALLEE_GOSUB, OPT_ARG_PREDIAL_CALLEE_GOSUB),
|
|
||||||
AST_APP_OPTION_ARG('B', OPT_PREDIAL_CALLER_GOSUB, OPT_ARG_PREDIAL_CALLER_GOSUB),
|
|
||||||
END_OPTIONS );
|
END_OPTIONS );
|
||||||
|
|
||||||
#define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
|
#define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
|
||||||
OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
|
OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
|
||||||
OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | \
|
OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | \
|
||||||
OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB | OPT_PREDIAL_CALLER_GOSUB | OPT_PREDIAL_CALLEE_GOSUB) && \
|
OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB) && \
|
||||||
!ast_channel_audiohooks(chan) && !ast_channel_audiohooks(peer) && \
|
!ast_channel_audiohooks(chan) && !ast_channel_audiohooks(peer) && \
|
||||||
ast_framehook_list_is_empty(ast_channel_framehooks(chan)) && ast_framehook_list_is_empty(ast_channel_framehooks(peer)))
|
ast_framehook_list_is_empty(ast_channel_framehooks(chan)) && ast_framehook_list_is_empty(ast_channel_framehooks(peer)))
|
||||||
|
|
||||||
@@ -2190,22 +2169,14 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
|
|||||||
|
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
|
if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
|
||||||
outbound_group = ast_strdupa(outbound_group);
|
outbound_group = ast_strdupa(outbound_group);
|
||||||
pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
|
pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
|
||||||
} else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
|
} else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
|
||||||
outbound_group = ast_strdupa(outbound_group);
|
outbound_group = ast_strdupa(outbound_group);
|
||||||
}
|
}
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_IGNORE_CONNECTEDLINE |
|
ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_IGNORE_CONNECTEDLINE |
|
||||||
OPT_CANCEL_TIMEOUT | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB | OPT_FORCECLID | OPT_PREDIAL_CALLER_GOSUB | OPT_PREDIAL_CALLEE_GOSUB);
|
OPT_CANCEL_TIMEOUT | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB | OPT_FORCECLID);
|
||||||
|
|
||||||
/* PREDIAL: Run gosub on the caller's channel */
|
|
||||||
if (ast_test_flag64(&opts, OPT_PREDIAL_CALLER_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER_GOSUB])) {
|
|
||||||
struct ast_channel *c = chan;
|
|
||||||
const char *goto_target = opt_args[OPT_ARG_PREDIAL_CALLER_GOSUB];
|
|
||||||
|
|
||||||
ast_pbx_exten_run_parseargs(c, goto_target, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* loop through the list of dial destinations */
|
/* loop through the list of dial destinations */
|
||||||
rest = args.peers;
|
rest = args.peers;
|
||||||
@@ -2435,22 +2406,6 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
|
|||||||
|
|
||||||
ast_channel_unlock(tc);
|
ast_channel_unlock(tc);
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
|
|
||||||
/* PREDIAL: Run gosub on the callee's channel
|
|
||||||
* We run the callee predial before ast_call() in case the user wishes to do something on the newly created channel
|
|
||||||
* before the channel does anything important
|
|
||||||
*
|
|
||||||
* Inside the target gosub we will be able to do something with the newly created channel name
|
|
||||||
* ie: now the calling channel can know what channel will be used to call the destination
|
|
||||||
* ex: now we will know that SIP/abc-123 is calling SIP/def-124
|
|
||||||
*/
|
|
||||||
if (ast_test_flag64(&opts, OPT_PREDIAL_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLEE_GOSUB])) {
|
|
||||||
struct ast_channel *c = tc;
|
|
||||||
const char *goto_target = opt_args[OPT_ARG_PREDIAL_CALLEE_GOSUB];
|
|
||||||
|
|
||||||
ast_pbx_exten_run_parseargs(c, goto_target, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
|
res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
|
|
||||||
|
@@ -331,8 +331,6 @@ struct ast_pbx_args {
|
|||||||
struct {
|
struct {
|
||||||
/*! Do not hangup the channel when the PBX is complete. */
|
/*! Do not hangup the channel when the PBX is complete. */
|
||||||
unsigned int no_hangup_chan:1;
|
unsigned int no_hangup_chan:1;
|
||||||
/*! Reuse existing pbx on the channel (used for arbitrarily jumping into dialplan) */
|
|
||||||
unsigned int use_existing_pbx:1;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1113,23 +1111,6 @@ void pbx_set_overrideswitch(const char *newval);
|
|||||||
*/
|
*/
|
||||||
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority);
|
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority);
|
||||||
|
|
||||||
/*!
|
|
||||||
* \note This function will check the validity of a goto target, see
|
|
||||||
* if it's reachable given the current channel state, and save the
|
|
||||||
* parsed tokens to the given buffers.
|
|
||||||
*/
|
|
||||||
int ast_pbx_exten_parse(struct ast_channel *chan, const char *goto_target, struct ast_str *context, struct ast_str *exten, struct ast_str *priority, struct varshead *varshead);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \note This function will run dialplan on a channel at context,exten,priority
|
|
||||||
*/
|
|
||||||
enum ast_pbx_result ast_pbx_exten_run_parseargs(struct ast_channel *chan, const char *gosub_args, int restore_dialplan_location);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \note This function will run dialplan on a channel at context,exten,priority and set also ARG
|
|
||||||
*/
|
|
||||||
enum ast_pbx_result ast_pbx_exten_run(struct ast_channel *chan, const char *context, const char *exten, int priority, struct varshead *varshead, int restore_dialplan_location);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \note This function will handle locking the channel as needed.
|
* \note This function will handle locking the channel as needed.
|
||||||
*/
|
*/
|
||||||
|
269
main/pbx.c
269
main/pbx.c
@@ -5105,21 +5105,19 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
|
|||||||
int error = 0; /* set an error conditions */
|
int error = 0; /* set an error conditions */
|
||||||
struct ast_pbx *pbx;
|
struct ast_pbx *pbx;
|
||||||
|
|
||||||
if (!args || !args->use_existing_pbx) {
|
/* A little initial setup here */
|
||||||
/* A little initial setup here */
|
if (ast_channel_pbx(c)) {
|
||||||
if (ast_channel_pbx(c)) {
|
ast_log(LOG_WARNING, "%s already has PBX structure??\n", ast_channel_name(c));
|
||||||
ast_log(LOG_WARNING, "%s already has PBX structure??\n", ast_channel_name(c));
|
/* XXX and now what ? */
|
||||||
/* XXX and now what ? */
|
ast_free(ast_channel_pbx(c));
|
||||||
ast_free(ast_channel_pbx(c));
|
}
|
||||||
}
|
if (!(pbx = ast_calloc(1, sizeof(*pbx)))) {
|
||||||
if (!(pbx = ast_calloc(1, sizeof(*pbx)))) {
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
ast_channel_pbx_set(c, pbx);
|
||||||
ast_channel_pbx_set(c, pbx);
|
/* Set reasonable defaults */
|
||||||
/* Set reasonable defaults */
|
ast_channel_pbx(c)->rtimeoutms = 10000;
|
||||||
ast_channel_pbx(c)->rtimeoutms = 10000;
|
ast_channel_pbx(c)->dtimeoutms = 5000;
|
||||||
ast_channel_pbx(c)->dtimeoutms = 5000;
|
|
||||||
}
|
|
||||||
|
|
||||||
autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
|
autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
|
||||||
ast_set_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP);
|
ast_set_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP);
|
||||||
@@ -5392,11 +5390,8 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
|
|||||||
}
|
}
|
||||||
ast_set2_flag(ast_channel_flags(c), autoloopflag, AST_FLAG_IN_AUTOLOOP);
|
ast_set2_flag(ast_channel_flags(c), autoloopflag, AST_FLAG_IN_AUTOLOOP);
|
||||||
ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
|
ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
|
||||||
|
pbx_destroy(ast_channel_pbx(c));
|
||||||
if (!args || !args->use_existing_pbx) {
|
ast_channel_pbx_set(c, NULL);
|
||||||
pbx_destroy(ast_channel_pbx(c));
|
|
||||||
ast_channel_pbx_set(c, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args || !args->no_hangup_chan) {
|
if (!args || !args->no_hangup_chan) {
|
||||||
ast_hangup(c);
|
ast_hangup(c);
|
||||||
@@ -10849,237 +10844,3 @@ int ast_pbx_init(void)
|
|||||||
|
|
||||||
return (hints && hintdevices && statecbs) ? 0 : -1;
|
return (hints && hintdevices && statecbs) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief return the pieces of a goto style target if it's valid.
|
|
||||||
*
|
|
||||||
* \param chan Channel on which to test target validity
|
|
||||||
* \param goto_target Goto target string. ([[context,]extension,]priority) see below for examples
|
|
||||||
* \param context Parsed context (ast_str must be pre created)
|
|
||||||
* \param exten Parsed exten (ast_str must be pre created)
|
|
||||||
* \param priority Parsed priority (ast_str must be pre created) (can be null if not needed)
|
|
||||||
* \param varshead Parsed variables from the gosub (can be null if not needed)
|
|
||||||
*
|
|
||||||
* \return -1 on failure
|
|
||||||
* \return parsed priority integer on success (> 0)
|
|
||||||
*
|
|
||||||
* \note lock channel before calling
|
|
||||||
*
|
|
||||||
* \example goto_target valid format: priority
|
|
||||||
* \example goto_target valid format: label
|
|
||||||
* \example goto_target valid format: exten,priority
|
|
||||||
* \example goto_target valid format: exten,label
|
|
||||||
* \example goto_target valid format: context,exten,priority
|
|
||||||
* \example goto_target valid format: context,exten,label
|
|
||||||
* \example goto_target <valid_format>(args)
|
|
||||||
*/
|
|
||||||
int ast_pbx_exten_parse(struct ast_channel *chan, const char *goto_target, struct ast_str *context, struct ast_str *exten, struct ast_str *priority, struct varshead *varshead)
|
|
||||||
{
|
|
||||||
int parse_args = 0;
|
|
||||||
char *target = ast_strdupa(goto_target); /* Target must be writable for AST_STANDARD_RAW_ARGS */
|
|
||||||
char *start_args = target;
|
|
||||||
int ipriority;
|
|
||||||
AST_DECLARE_APP_ARGS(args,
|
|
||||||
AST_APP_ARG(context);
|
|
||||||
AST_APP_ARG(exten);
|
|
||||||
AST_APP_ARG(priority);
|
|
||||||
);
|
|
||||||
AST_DECLARE_APP_ARGS(args2,
|
|
||||||
AST_APP_ARG(argval)[100];
|
|
||||||
);
|
|
||||||
|
|
||||||
ast_str_truncate(context, 0);
|
|
||||||
ast_str_truncate(exten, 0);
|
|
||||||
|
|
||||||
/* Find the args (if any) */
|
|
||||||
if (varshead && ((start_args = strchr(start_args, '(')) != NULL)) {
|
|
||||||
char *end_args;
|
|
||||||
|
|
||||||
parse_args = 1;
|
|
||||||
*start_args = 0;
|
|
||||||
start_args++;
|
|
||||||
|
|
||||||
if ((end_args = strchr(start_args, ')')) != NULL) {
|
|
||||||
*end_args = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ast_log(LOG_WARNING, "Ouch. No closing paren for Gosub parameters: '%s'?\n", goto_target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AST_STANDARD_RAW_ARGS(args, target);
|
|
||||||
|
|
||||||
if (priority) {
|
|
||||||
ast_str_truncate(priority, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ast_strlen_zero(goto_target)) {
|
|
||||||
ast_log(LOG_WARNING, "goto_target cannot be empty ([[context,]extension,]priority)\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ast_strlen_zero(args.exten)) {
|
|
||||||
/* Only a priority in this one */
|
|
||||||
args.priority = args.context;
|
|
||||||
args.exten = (char *) ast_channel_exten(chan);
|
|
||||||
args.context = (char *) ast_channel_context(chan);
|
|
||||||
} else if (ast_strlen_zero(args.priority)) {
|
|
||||||
/* Only an extension and priority in this one */
|
|
||||||
args.priority = args.exten;
|
|
||||||
args.exten = args.context;
|
|
||||||
args.context = (char *) ast_channel_context(chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sscanf(args.priority, "%d", &ipriority) > 0) {
|
|
||||||
if (!ast_exists_extension(chan, args.context, args.exten, ipriority, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
|
|
||||||
ast_log(LOG_WARNING, "priority based goto target not found: %s\n", goto_target);
|
|
||||||
ipriority = 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!(ipriority = ast_findlabel_extension(chan, args.context, args.exten, args.priority, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)))) {
|
|
||||||
ast_log(LOG_WARNING, "label based goto target not found: %s\n", goto_target);
|
|
||||||
ipriority = 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ast_str_set(&context, 0, "%s", args.context);
|
|
||||||
ast_str_set(&exten, 0, "%s", args.exten);
|
|
||||||
|
|
||||||
if (priority) {
|
|
||||||
ast_str_set(&priority, 0, "%s", args.priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parse_args) {
|
|
||||||
int i;
|
|
||||||
struct ast_str *argument_name = ast_str_create(64);
|
|
||||||
struct ast_var_t *variable;
|
|
||||||
int argument_num = 1;
|
|
||||||
|
|
||||||
AST_STANDARD_RAW_ARGS(args2, start_args);
|
|
||||||
|
|
||||||
for (i = 0; i < args2.argc; i++) {
|
|
||||||
ast_str_truncate(argument_name, 0);
|
|
||||||
ast_str_append(&argument_name, 0, "ARG%d", argument_num);
|
|
||||||
|
|
||||||
variable = ast_var_assign(ast_str_buffer(argument_name), args2.argval[i]);
|
|
||||||
AST_LIST_INSERT_TAIL(varshead, variable, entries);
|
|
||||||
argument_num++;
|
|
||||||
|
|
||||||
ast_log(LOG_WARNING, "Setting '%s' to '%s' %p\n", ast_str_buffer(argument_name), args2.argval[i], variable);
|
|
||||||
ast_debug(1, "Setting '%s' to '%s'\n", ast_str_buffer(argument_name), args2.argval[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast_free(argument_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ipriority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief run dialplan on a channel, optionally restoring the channel to the previous dialplan location
|
|
||||||
*
|
|
||||||
* \param chan Channel on which to run dialplan
|
|
||||||
* \param args Gosub style args in the form of context,exten,priority(arg1,arg2,argn,...)
|
|
||||||
* \param restore_dialplan_location 1/0 whether to restore the channel's dialplan location to where it was before we were called
|
|
||||||
*
|
|
||||||
* \retval AST_PBX_SUCCESS on success
|
|
||||||
* \retval AST_PBX_ERROR on error
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
enum ast_pbx_result ast_pbx_exten_run_parseargs(struct ast_channel *chan, const char *gosub_args, int restore_dialplan_location) {
|
|
||||||
struct varshead varshead;
|
|
||||||
struct ast_var_t *variable;
|
|
||||||
struct ast_str *context = ast_str_create(64);
|
|
||||||
struct ast_str *exten = ast_str_create(64);
|
|
||||||
int ipriority;
|
|
||||||
enum ast_pbx_result res = AST_PBX_ERROR;
|
|
||||||
|
|
||||||
memset(&varshead, 0, sizeof(varshead));
|
|
||||||
|
|
||||||
if ((ipriority = ast_pbx_exten_parse(chan, gosub_args, context, exten, NULL, &varshead)) > 0) {
|
|
||||||
res = ast_pbx_exten_run(chan, ast_str_buffer(context), ast_str_buffer(exten), ipriority, &varshead, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
AST_LIST_TRAVERSE_SAFE_BEGIN(&varshead, variable, entries) {
|
|
||||||
AST_LIST_REMOVE_CURRENT(entries);
|
|
||||||
ast_var_delete(variable);
|
|
||||||
}
|
|
||||||
AST_LIST_TRAVERSE_SAFE_END;
|
|
||||||
|
|
||||||
ast_free(context);
|
|
||||||
ast_free(exten);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief run dialplan on a channel, optionally restoring the channel to the previous dialplan location
|
|
||||||
*
|
|
||||||
* \param chan Channel on which to run dialplan
|
|
||||||
* \param context Context in which to execute
|
|
||||||
* \param exten Exten within the context
|
|
||||||
* \param priority Priority within the exten
|
|
||||||
* \param varshead Array of arguments to pass to destination. Args will be set in the form of ARG1,ARG2,ARGn,...
|
|
||||||
* \param restore_dialplan_location 1/0 whether to restore the channel's dialplan location to where it was before we were called
|
|
||||||
*
|
|
||||||
* \retval AST_PBX_HANGUP on error
|
|
||||||
* \retval AST_PBX_OK on success
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
enum ast_pbx_result ast_pbx_exten_run(struct ast_channel *chan, const char *context, const char *exten, int priority, struct varshead *varshead, int restore_dialplan_location)
|
|
||||||
{
|
|
||||||
struct ast_str *backup_context;
|
|
||||||
struct ast_str *backup_exten;
|
|
||||||
int backup_priority = 0;
|
|
||||||
enum ast_pbx_result res;
|
|
||||||
struct ast_pbx_args run_args;
|
|
||||||
struct ast_var_t *variable;
|
|
||||||
|
|
||||||
/* Back up current dialplan location */
|
|
||||||
if (restore_dialplan_location) {
|
|
||||||
backup_context = ast_str_create(64);
|
|
||||||
backup_exten = ast_str_create(64);
|
|
||||||
|
|
||||||
ast_str_set(&backup_context, 0, "%s", ast_channel_context(chan));
|
|
||||||
ast_str_set(&backup_exten, 0, "%s", ast_channel_exten(chan));
|
|
||||||
backup_priority = ast_channel_priority(chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New dialplan location */
|
|
||||||
ast_channel_context_set(chan, context);
|
|
||||||
ast_channel_exten_set(chan, exten);
|
|
||||||
ast_channel_priority_set(chan, priority);
|
|
||||||
|
|
||||||
/* set args, if any */
|
|
||||||
if (varshead) {
|
|
||||||
AST_LIST_TRAVERSE(varshead, variable, entries) {
|
|
||||||
pbx_builtin_pushvar_helper(chan, ast_var_name(variable), ast_var_value(variable));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&run_args, 0, sizeof(run_args));
|
|
||||||
if (ast_channel_pbx(chan)) {
|
|
||||||
run_args.use_existing_pbx = 1;
|
|
||||||
}
|
|
||||||
run_args.no_hangup_chan = 1;
|
|
||||||
res = __ast_pbx_run(chan, &run_args);
|
|
||||||
|
|
||||||
/* Allow use of previously set variables. Ie: if there was previously ARG1,ARG2,etc set on the channel
|
|
||||||
we want access to those old values since the dialplan we ran is now finished */
|
|
||||||
if (varshead) {
|
|
||||||
AST_LIST_TRAVERSE(varshead, variable, entries) {
|
|
||||||
pbx_builtin_setvar_helper(chan, ast_var_name(variable), NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (restore_dialplan_location) {
|
|
||||||
/* Restore current dialplan location */
|
|
||||||
ast_channel_context_set(chan, ast_str_buffer(backup_context));
|
|
||||||
ast_channel_exten_set(chan, ast_str_buffer(backup_exten));
|
|
||||||
ast_channel_priority_set(chan, backup_priority);
|
|
||||||
|
|
||||||
ast_free(backup_context);
|
|
||||||
ast_free(backup_exten);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user