diff -Naur asterisk-11.24.1-orig/apps/app_originate.c asterisk-11.24.1/apps/app_originate.c
--- asterisk-11.24.1-orig/apps/app_originate.c 2016-10-27 14:34:34.000000000 -0400
+++ asterisk-11.24.1/apps/app_originate.c 2016-11-14 14:16:01.984764472 -0500
@@ -73,6 +73,30 @@
Timeout in seconds. Default is 30 seconds.
+
+
+
+
+
+
This application originates an outbound call and connects it to a specified extension or application. This application will block until the outgoing call fails or gets answered. At that point, this application will exit with the status variable set and dialplan processing will continue.
@@ -96,6 +120,25 @@
***/
+
+enum {
+ OPT_PREDIAL_CALLEE = (1 << 0),
+ OPT_PREDIAL_CALLER = (1 << 1),
+};
+
+enum {
+ OPT_ARG_PREDIAL_CALLEE,
+ OPT_ARG_PREDIAL_CALLER,
+ /* note: this entry _MUST_ be the last one in the enum */
+ OPT_ARG_ARRAY_SIZE,
+};
+
+AST_APP_OPTIONS(originate_exec_options, BEGIN_OPTIONS
+ AST_APP_OPTION_ARG('b', OPT_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLEE),
+ AST_APP_OPTION_ARG('B', OPT_PREDIAL_CALLER, OPT_ARG_PREDIAL_CALLER),
+END_OPTIONS );
+
+
static int originate_exec(struct ast_channel *chan, const char *data)
{
AST_DECLARE_APP_ARGS(args,
@@ -105,7 +148,11 @@
AST_APP_ARG(arg2);
AST_APP_ARG(arg3);
AST_APP_ARG(timeout);
+ AST_APP_ARG(options);
);
+ struct ast_flags64 opts = { 0, };
+ char *opt_args[OPT_ARG_ARRAY_SIZE];
+ char *predial_callee = NULL;
char *parse;
char *chantech, *chandata;
int res = -1;
@@ -158,6 +205,27 @@
goto return_cleanup;
}
+ if (!ast_strlen_zero(args.options) &&
+ ast_app_parse_options64(originate_exec_options, &opts, opt_args, args.options)) {
+ ast_log(LOG_ERROR, "Invalid options: '%s'\n", args.options);
+ goto return_cleanup;
+ }
+
+ /* PREDIAL: Run gosub on the caller's channel */
+ if (ast_test_flag64(&opts, OPT_PREDIAL_CALLER)
+ && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {
+ ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLER]);
+ ast_debug(1, "Predial caller '%s' \n",opt_args[OPT_ARG_PREDIAL_CALLER]);
+ ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);
+ }
+
+ if (ast_test_flag64(&opts, OPT_PREDIAL_CALLEE)
+ && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLEE])) {
+ ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
+ predial_callee = opt_args[OPT_ARG_PREDIAL_CALLEE];
+ ast_debug(1, "Predial callee '%s'\n",predial_callee);
+ }
+
if (!strcasecmp(args.type, "exten")) {
int priority = 1; /* Initialized in case priority not specified */
const char *exten = args.arg2;
@@ -176,16 +244,16 @@
ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
chantech, chandata, args.arg1, exten, priority);
- ast_pbx_outgoing_exten(chantech, cap_slin, chandata,
+ __ast_pbx_outgoing_exten(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
- NULL, NULL, NULL, NULL, 0);
+ NULL, NULL, NULL, NULL, 0, predial_callee);
} else if (!strcasecmp(args.type, "app")) {
ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
chantech, chandata, args.arg1, S_OR(args.arg2, ""));
- ast_pbx_outgoing_app(chantech, cap_slin, chandata,
+ __ast_pbx_outgoing_app(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, predial_callee);
} else {
ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
args.type);
diff -Naur asterisk-11.24.1-orig/include/asterisk/channel.h asterisk-11.24.1/include/asterisk/channel.h
--- asterisk-11.24.1-orig/include/asterisk/channel.h 2016-10-27 14:34:34.000000000 -0400
+++ asterisk-11.24.1/include/asterisk/channel.h 2016-11-12 16:36:07.803453519 -0500
@@ -955,6 +955,7 @@
const char *account;
struct ast_variable *vars;
struct ast_channel *parent_channel;
+ const char *predial_callee;
};
enum {
diff -Naur asterisk-11.24.1-orig/include/asterisk/pbx.h asterisk-11.24.1/include/asterisk/pbx.h
--- asterisk-11.24.1-orig/include/asterisk/pbx.h 2016-10-27 14:34:34.000000000 -0400
+++ asterisk-11.24.1/include/asterisk/pbx.h 2016-11-14 15:24:05.613941244 -0500
@@ -1098,11 +1098,29 @@
/*! Synchronously or asynchronously make an outbound call and send it to a
particular extension */
-int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media);
-
+int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr,
+ int timeout, const char *context, const char *exten, int priority, int *reason,
+ int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars,
+ const char *account, struct ast_channel **locked_channel, int early_media);
+
+int __ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr,
+ int timeout, const char *context, const char *exten, int priority, int *reason,
+ int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars,
+ const char *account, struct ast_channel **locked_channel, int early_media,
+ const char *predial_callee);
+
/*! Synchronously or asynchronously make an outbound call and send it to a
particular application with given extension */
-int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
+int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr,
+ int timeout, const char *app, const char *appdata, int *reason, int sync,
+ const char *cid_num, const char *cid_name, struct ast_variable *vars,
+ const char *account, struct ast_channel **locked_channel);
+
+int __ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr,
+ int timeout, const char *app, const char *appdata, int *reason, int sync,
+ const char *cid_num, const char *cid_name, struct ast_variable *vars,
+ const char *account, struct ast_channel **locked_channel,
+ const char *predial_callee);
/*!
* \brief Evaluate a condition
diff -Naur asterisk-11.24.1-orig/main/channel.c asterisk-11.24.1/main/channel.c
--- asterisk-11.24.1-orig/main/channel.c 2016-10-27 14:34:34.000000000 -0400
+++ asterisk-11.24.1/main/channel.c 2016-11-13 14:15:14.312680878 -0500
@@ -5679,6 +5679,8 @@
int res = 0;
int last_subclass = 0;
struct ast_party_connected_line connected;
+ char tmp_cid_name[128];
+ char tmp_cid_num[128];
if (outstate)
*outstate = 0;
@@ -5717,6 +5719,27 @@
ast_cdr_setaccount(chan, oh->account);
ast_channel_unlock(chan);
}
+ if (oh->predial_callee) {
+ const char *predial_callee = NULL;
+ predial_callee = ast_app_expand_sub_args(chan, oh->predial_callee);
+ if (predial_callee) {
+ char *tmp;
+ ast_pre_call(chan, predial_callee);
+ ast_free((char *) predial_callee);
+
+ /* the predial sub routine may have set callerid */
+ tmp = S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL);
+ if (tmp) {
+ ast_copy_string(tmp_cid_num, tmp, sizeof(tmp_cid_num));
+ cid_num = tmp_cid_num;
+ }
+ tmp = S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL);
+ if (tmp) {
+ ast_copy_string(tmp_cid_name, tmp, sizeof(tmp_cid_name));
+ cid_name = tmp_cid_name;
+ }
+ }
+ }
}
/*
diff -Naur asterisk-11.24.1-orig/main/pbx.c asterisk-11.24.1/main/pbx.c
--- asterisk-11.24.1-orig/main/pbx.c 2016-10-27 14:34:34.000000000 -0400
+++ asterisk-11.24.1/main/pbx.c 2016-11-14 20:38:15.257418999 -0500
@@ -10710,6 +10710,12 @@
int ast_pbx_outgoing_exten(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 **channel, int early_media)
{
+ return __ast_pbx_outgoing_exten(type, cap, addr, timeout, context, exten, priority, reason,
+ synchronous, cid_num, cid_name, vars, account, channel, early_media, NULL);
+}
+
+int __ast_pbx_outgoing_exten(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 **channel, int early_media, const char *predial_callee)
+{
struct ast_channel *chan;
struct async_stat *as;
struct ast_callid *callid;
@@ -10717,7 +10723,9 @@
int res = -1, cdr_res = -1;
struct outgoing_helper oh;
+ memset(&oh, 0, sizeof(oh));
oh.connect_on_early_media = early_media;
+ oh.predial_callee = predial_callee;
callid_created = ast_callid_threadstorage_auto(&callid);
@@ -10832,7 +10840,7 @@
res = -1;
goto outgoing_exten_cleanup;
}
- chan = ast_request_and_dial(type, cap, NULL, addr, timeout, reason, cid_num, cid_name);
+ chan = __ast_request_and_dial(type, cap, NULL, addr, timeout, reason, cid_num, cid_name, &oh);
if (channel) {
*channel = chan;
if (chan)
@@ -10909,6 +10917,12 @@
int ast_pbx_outgoing_app(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)
{
+ return __ast_pbx_outgoing_app(type, cap, addr, timeout, app, appdata, reason,
+ synchronous, cid_num, cid_name, vars, account, locked_channel, NULL);
+}
+
+int __ast_pbx_outgoing_app(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 char *predial_callee)
+{
struct ast_channel *chan;
struct app_tmp *tmp;
struct ast_callid *callid;
@@ -10922,6 +10936,7 @@
memset(&oh, 0, sizeof(oh));
oh.vars = vars;
oh.account = account;
+ oh.predial_callee = predial_callee;
if (locked_channel)
*locked_channel = NULL;