manager: Restore Originate failure behavior from Asterisk 11
In Asterisk 11, if the 'Originate' AMI command failed to connect the provided
Channel while in extension mode, a 'failed' extension would be looked up and
run. This was, I believe, unintentionally removed in 51b6c49
. This patch
restores that behavior.
This also adds an enum for the various 'synchronous' modes in an attempt to
make them meaningful.
ASTERISK-26115 #close
Reported by: Nasir Iqbal
Change-Id: I8afbd06725e99610e02adb529137d4800c05345d
This commit is contained in:
parent
648d181d2f
commit
0910773077
|
@ -242,15 +242,17 @@ static int originate_exec(struct ast_channel *chan, const char *data)
|
||||||
chantech, chandata, args.arg1, exten, priority);
|
chantech, chandata, args.arg1, exten, priority);
|
||||||
|
|
||||||
ast_pbx_outgoing_exten_predial(chantech, cap_slin, chandata,
|
ast_pbx_outgoing_exten_predial(chantech, cap_slin, chandata,
|
||||||
timeout * 1000, args.arg1, exten, priority, &outgoing_status, 1, NULL,
|
timeout * 1000, args.arg1, exten, priority, &outgoing_status,
|
||||||
NULL, NULL, NULL, NULL, 0, NULL, predial_callee);
|
AST_OUTGOING_WAIT, NULL, NULL, NULL, NULL, NULL, 0, NULL,
|
||||||
|
predial_callee);
|
||||||
} else if (!strcasecmp(args.type, "app")) {
|
} else if (!strcasecmp(args.type, "app")) {
|
||||||
ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
|
ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
|
||||||
chantech, chandata, args.arg1, S_OR(args.arg2, ""));
|
chantech, chandata, args.arg1, S_OR(args.arg2, ""));
|
||||||
|
|
||||||
ast_pbx_outgoing_app_predial(chantech, cap_slin, chandata,
|
ast_pbx_outgoing_app_predial(chantech, cap_slin, chandata,
|
||||||
timeout * 1000, args.arg1, args.arg2, &outgoing_status, 1, NULL,
|
timeout * 1000, args.arg1, args.arg2, &outgoing_status,
|
||||||
NULL, NULL, NULL, NULL, NULL, predial_callee);
|
AST_OUTGOING_WAIT, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
predial_callee);
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
|
ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
|
||||||
args.type);
|
args.type);
|
||||||
|
|
|
@ -181,8 +181,8 @@ static void *hook_launch_thread(void *data)
|
||||||
};
|
};
|
||||||
|
|
||||||
ast_pbx_outgoing_exten("Local", NULL, full_exten_name, 60,
|
ast_pbx_outgoing_exten("Local", NULL, full_exten_name, 60,
|
||||||
arg->context, arg->exten, 1, NULL, 0, NULL, NULL, &chan_name_var,
|
arg->context, arg->exten, 1, NULL, AST_OUTGOING_NO_WAIT,
|
||||||
NULL, NULL, 1, NULL);
|
NULL, NULL, &chan_name_var, NULL, NULL, 1, NULL);
|
||||||
|
|
||||||
hook_thread_arg_destroy(arg);
|
hook_thread_arg_destroy(arg);
|
||||||
|
|
||||||
|
|
|
@ -1144,6 +1144,12 @@ int ast_async_goto(struct ast_channel *chan, const char *context, const char *ex
|
||||||
*/
|
*/
|
||||||
int ast_async_goto_by_name(const char *chan, const char *context, const char *exten, int priority);
|
int ast_async_goto_by_name(const char *chan, const char *context, const char *exten, int priority);
|
||||||
|
|
||||||
|
enum ast_pbx_outgoing_sync {
|
||||||
|
AST_OUTGOING_NO_WAIT = 0, /*!< Don't wait for originated call to answer */
|
||||||
|
AST_OUTGOING_WAIT = 1, /*!< Wait for originated call to answer */
|
||||||
|
AST_OUTGOING_WAIT_COMPLETE = 2, /*!< Wait for originated call to answer and hangup */
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Synchronously or asynchronously make an outbound call and send it to a
|
* \brief Synchronously or asynchronously make an outbound call and send it to a
|
||||||
* particular extension
|
* particular extension
|
||||||
|
@ -1157,11 +1163,15 @@ int ast_async_goto_by_name(const char *chan, const char *context, const char *ex
|
||||||
* \param priority The destination priority for the outbound channel
|
* \param priority The destination priority for the outbound channel
|
||||||
* \param reason Optional. If provided, the dialed status of the outgoing channel.
|
* \param reason Optional. If provided, the dialed status of the outgoing channel.
|
||||||
* Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
|
* Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
|
||||||
* \param synchronous If zero then don't wait for anything.
|
* \param synchronous defined by the ast_pbx_outgoing_sync enum.
|
||||||
* If one then block until the outbound channel answers or the call fails.
|
* If \c AST_OUTGOING_NO_WAIT then don't wait for anything.
|
||||||
* If greater than one then wait for the call to complete or if the call doesn't
|
* If \c AST_OUTGOING_WAIT then block until the outbound channel answers or
|
||||||
* answer and failed@context exists then run a channel named OutgoingSpoolFailed
|
* the call fails.
|
||||||
* at failed@context.
|
* If \c AST_OUTGOING_WAIT_COMPLETE then wait for the call to complete or
|
||||||
|
* fail.
|
||||||
|
* If \c AST_OUTGOING_WAIT or \c AST_OUTGOING_WAIT_COMPLETE is specified,
|
||||||
|
* the call doesn't answer, and \c failed@context exists then run a channel
|
||||||
|
* named \c OutgoingSpoolFailed at \c failed@context.
|
||||||
* \param cid_num The caller ID number to set on the outbound channel
|
* \param cid_num The caller ID number to set on the outbound channel
|
||||||
* \param cid_name The caller ID name to set on the outbound channel
|
* \param cid_name The caller ID name to set on the outbound channel
|
||||||
* \param vars Variables to set on the outbound channel
|
* \param vars Variables to set on the outbound channel
|
||||||
|
@ -1201,9 +1211,12 @@ int ast_pbx_outgoing_exten_predial(const char *type, struct ast_format_cap *cap,
|
||||||
* \param appdata Data to pass to the application
|
* \param appdata Data to pass to the application
|
||||||
* \param reason Optional. If provided, the dialed status of the outgoing channel.
|
* \param reason Optional. If provided, the dialed status of the outgoing channel.
|
||||||
* Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
|
* Codes are AST_CONTROL_xxx values. Valid only if synchronous is non-zero.
|
||||||
* \param synchronous If zero then don't wait for anything.
|
* \param synchronous defined by the ast_pbx_outgoing_sync enum.
|
||||||
* If one then block until the outbound channel answers or the call fails.
|
* If \c AST_OUTGOING_NO_WAIT then don't wait for anything.
|
||||||
* If greater than one then wait for the call to complete.
|
* If \c AST_OUTGOING_WAIT then block until the outbound channel answers or
|
||||||
|
* the call fails.
|
||||||
|
* If \c AST_OUTGOING_WAIT_COMPLETE then wait for the call to complete or
|
||||||
|
* fail.
|
||||||
* \param cid_num The caller ID number to set on the outbound channel
|
* \param cid_num The caller ID number to set on the outbound channel
|
||||||
* \param cid_name The caller ID name to set on the outbound channel
|
* \param cid_name The caller ID name to set on the outbound channel
|
||||||
* \param vars Variables to set on the outbound channel
|
* \param vars Variables to set on the outbound channel
|
||||||
|
|
|
@ -5130,13 +5130,15 @@ static void *fast_originate(void *data)
|
||||||
|
|
||||||
if (!ast_strlen_zero(in->app)) {
|
if (!ast_strlen_zero(in->app)) {
|
||||||
res = ast_pbx_outgoing_app(in->tech, in->cap, in->data,
|
res = ast_pbx_outgoing_app(in->tech, in->cap, in->data,
|
||||||
in->timeout, in->app, in->appdata, &reason, 1,
|
in->timeout, in->app, in->appdata, &reason,
|
||||||
|
AST_OUTGOING_WAIT,
|
||||||
S_OR(in->cid_num, NULL),
|
S_OR(in->cid_num, NULL),
|
||||||
S_OR(in->cid_name, NULL),
|
S_OR(in->cid_name, NULL),
|
||||||
in->vars, in->account, &chan, &assignedids);
|
in->vars, in->account, &chan, &assignedids);
|
||||||
} else {
|
} else {
|
||||||
res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data,
|
res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data,
|
||||||
in->timeout, in->context, in->exten, in->priority, &reason, 1,
|
in->timeout, in->context, in->exten, in->priority, &reason,
|
||||||
|
AST_OUTGOING_WAIT,
|
||||||
S_OR(in->cid_num, NULL),
|
S_OR(in->cid_num, NULL),
|
||||||
S_OR(in->cid_name, NULL),
|
S_OR(in->cid_name, NULL),
|
||||||
in->vars, in->account, &chan, in->early_media, &assignedids);
|
in->vars, in->account, &chan, in->early_media, &assignedids);
|
||||||
|
@ -5607,11 +5609,16 @@ static int action_originate(struct mansession *s, const struct message *m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!ast_strlen_zero(app)) {
|
} else if (!ast_strlen_zero(app)) {
|
||||||
res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL, assignedids.uniqueid ? &assignedids : NULL);
|
res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason,
|
||||||
|
AST_OUTGOING_WAIT, l, n, vars, account, NULL,
|
||||||
|
assignedids.uniqueid ? &assignedids : NULL);
|
||||||
ast_variables_destroy(vars);
|
ast_variables_destroy(vars);
|
||||||
} else {
|
} else {
|
||||||
if (exten && context && pi) {
|
if (exten && context && pi) {
|
||||||
res = ast_pbx_outgoing_exten(tech, cap, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL, bridge_early, assignedids.uniqueid ? &assignedids : NULL);
|
res = ast_pbx_outgoing_exten(tech, cap, data, to,
|
||||||
|
context, exten, pi, &reason, AST_OUTGOING_WAIT,
|
||||||
|
l, n, vars, account, NULL, bridge_early,
|
||||||
|
assignedids.uniqueid ? &assignedids : NULL);
|
||||||
ast_variables_destroy(vars);
|
ast_variables_destroy(vars);
|
||||||
} else {
|
} else {
|
||||||
astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
|
astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
|
||||||
|
|
|
@ -7876,7 +7876,7 @@ int ast_pbx_outgoing_exten_predial(const char *type, struct ast_format_cap *cap,
|
||||||
early_media, assignedids, predial_callee);
|
early_media, assignedids, predial_callee);
|
||||||
|
|
||||||
if (res < 0 /* Call failed to get connected for some reason. */
|
if (res < 0 /* Call failed to get connected for some reason. */
|
||||||
&& 1 < synchronous
|
&& 0 < synchronous
|
||||||
&& ast_exists_extension(NULL, context, "failed", 1, NULL)) {
|
&& ast_exists_extension(NULL, context, "failed", 1, NULL)) {
|
||||||
struct ast_channel *failed;
|
struct ast_channel *failed;
|
||||||
|
|
||||||
|
|
|
@ -397,15 +397,17 @@ static void *attempt_thread(void *data)
|
||||||
int res, reason;
|
int res, reason;
|
||||||
if (!ast_strlen_zero(o->app)) {
|
if (!ast_strlen_zero(o->app)) {
|
||||||
ast_verb(3, "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries);
|
ast_verb(3, "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries);
|
||||||
res = ast_pbx_outgoing_app(o->tech, o->capabilities, o->dest, o->waittime * 1000,
|
res = ast_pbx_outgoing_app(o->tech, o->capabilities, o->dest,
|
||||||
o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name,
|
o->waittime * 1000, o->app, o->data, &reason,
|
||||||
|
AST_OUTGOING_WAIT_COMPLETE, o->cid_num, o->cid_name,
|
||||||
o->vars, o->account, NULL, NULL);
|
o->vars, o->account, NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
ast_verb(3, "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries);
|
ast_verb(3, "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries);
|
||||||
res = ast_pbx_outgoing_exten(o->tech, o->capabilities, o->dest,
|
res = ast_pbx_outgoing_exten(o->tech, o->capabilities, o->dest,
|
||||||
o->waittime * 1000, o->context, o->exten, o->priority, &reason,
|
o->waittime * 1000, o->context, o->exten, o->priority, &reason,
|
||||||
2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL,
|
AST_OUTGOING_WAIT_COMPLETE, o->cid_num, o->cid_name,
|
||||||
ast_test_flag(&o->options, SPOOL_FLAG_EARLY_MEDIA), NULL);
|
o->vars, o->account, NULL, ast_test_flag(&o->options, SPOOL_FLAG_EARLY_MEDIA),
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
ast_log(LOG_NOTICE, "Call failed to go through, reason (%d) %s\n", reason, ast_channel_reason2str(reason));
|
ast_log(LOG_NOTICE, "Call failed to go through, reason (%d) %s\n", reason, ast_channel_reason2str(reason));
|
||||||
|
|
|
@ -72,7 +72,9 @@ static char *orig_app(int fd, const char *chan, const char *app, const char *app
|
||||||
return CLI_FAILURE;
|
return CLI_FAILURE;
|
||||||
}
|
}
|
||||||
ast_format_cap_append(cap, ast_format_slin, 0);
|
ast_format_cap_append(cap, ast_format_slin, 0);
|
||||||
ast_pbx_outgoing_app(chantech, cap, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL, NULL);
|
ast_pbx_outgoing_app(chantech, cap, chandata, TIMEOUT * 1000, app, appdata,
|
||||||
|
&reason, AST_OUTGOING_NO_WAIT, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
ao2_ref(cap, -1);
|
ao2_ref(cap, -1);
|
||||||
|
|
||||||
return CLI_SUCCESS;
|
return CLI_SUCCESS;
|
||||||
|
@ -116,7 +118,9 @@ static char *orig_exten(int fd, const char *chan, const char *data)
|
||||||
return CLI_FAILURE;
|
return CLI_FAILURE;
|
||||||
}
|
}
|
||||||
ast_format_cap_append(cap, ast_format_slin, 0);
|
ast_format_cap_append(cap, ast_format_slin, 0);
|
||||||
ast_pbx_outgoing_exten(chantech, cap, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL);
|
ast_pbx_outgoing_exten(chantech, cap, chandata, TIMEOUT * 1000, context,
|
||||||
|
exten, 1, &reason, AST_OUTGOING_NO_WAIT, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, 0, NULL);
|
||||||
ao2_ref(cap, -1);
|
ao2_ref(cap, -1);
|
||||||
|
|
||||||
return CLI_SUCCESS;
|
return CLI_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue