[Asterisk-code-review] app_originate: Allow setting Caller ID and variables (asterisk[master])

George Joseph asteriskteam at digium.com
Fri Jun 11 11:30:15 CDT 2021


George Joseph has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/15951 )

Change subject: app_originate: Allow setting Caller ID and variables
......................................................................

app_originate: Allow setting Caller ID and variables

Caller ID can now be set on the called channel and
Variables can now be set on the destination
using the Originate application, just as
they can be currently using call files
or the Manager Action.

ASTERISK-29450

Change-Id: Ia64cfe97d2792bcbf4775b3126cad662922a8b66
---
M apps/app_originate.c
A doc/CHANGES-staging/app_originate_vars.txt
2 files changed, 83 insertions(+), 8 deletions(-)

Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved; Approved for Submit



diff --git a/apps/app_originate.c b/apps/app_originate.c
index 107be84..2af46e3 100644
--- a/apps/app_originate.c
+++ b/apps/app_originate.c
@@ -27,9 +27,6 @@
  *
  * \ingroup applications
  *
- * \todo Make a way to be able to set variables (and functions) on the outbound
- *       channel, similar to the Variable headers for the AMI Originate, and the
- *       Set options for call files.
  */
 
 /*** MODULEINFO
@@ -98,12 +95,26 @@
 						<argument name="argN" />
 					</argument>
 				</option>
+				<option name="c">
+					<para>The caller ID number to use for the called channel. Default is
+					the current channel's Caller ID number.</para>
+				</option>
+				<option name="n">
+					<para>The caller ID name to use for the called channel. Default is
+					the current channel's Caller ID name.</para>
+				</option>
+				<option name="v" argsep="^">
+					<para>A series of channel variables to set on the destination channel.</para>
+					<argument name="var1" multiple="true" argsep="=">
+						<argument name="name" required="true" />
+						<argument name="value" required="true" />
+					</argument>
+				</option>
 				</optionlist>
 			</parameter>
 		</syntax>
 		<description>
 		<para>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.</para>
-
 		<para>This application sets the following channel variable before exiting:</para>
 		<variablelist>
 			<variable name="ORIGINATE_STATUS">
@@ -128,11 +139,17 @@
 	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_VARIABLES =         (1 << 5),
 };
 
 enum {
 	OPT_ARG_PREDIAL_CALLEE,
 	OPT_ARG_PREDIAL_CALLER,
+	OPT_ARG_CALLER_NUM,
+	OPT_ARG_CALLER_NAME,
+	OPT_ARG_VARIABLES,
 	/* note: this entry _MUST_ be the last one in the enum */
 	OPT_ARG_ARRAY_SIZE,
 };
@@ -141,9 +158,11 @@
 	AST_APP_OPTION('a', OPT_ASYNC),
 	AST_APP_OPTION_ARG('b', OPT_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLEE),
 	AST_APP_OPTION_ARG('B', OPT_PREDIAL_CALLER, OPT_ARG_PREDIAL_CALLER),
+	AST_APP_OPTION_ARG('c', OPT_CALLER_NUM, OPT_ARG_CALLER_NUM),
+	AST_APP_OPTION_ARG('n', OPT_CALLER_NAME, OPT_ARG_CALLER_NAME),
+	AST_APP_OPTION_ARG('v', OPT_VARIABLES, OPT_ARG_VARIABLES),
 END_OPTIONS );
 
-
 static int originate_exec(struct ast_channel *chan, const char *data)
 {
 	AST_DECLARE_APP_ARGS(args,
@@ -158,7 +177,9 @@
 	struct ast_flags64 opts = { 0, };
 	char *opt_args[OPT_ARG_ARRAY_SIZE];
 	char *predial_callee = NULL;
-	char *parse;
+	char *parse, *cnum = NULL, *cname = NULL;
+	
+	struct ast_variable *vars = NULL;
 	char *chantech, *chandata;
 	int res = -1;
 	int continue_in_dialplan = 0;
@@ -236,7 +257,50 @@
 		goto return_cleanup;
 	}
 
+	if (ast_test_flag64(&opts, OPT_CALLER_NUM)) {
+		if (!ast_strlen_zero(opt_args[OPT_ARG_CALLER_NUM])) {
+			cnum = opt_args[OPT_ARG_CALLER_NUM];
+		} else if (ast_channel_caller(chan)->id.number.str) {
+			cnum = ast_channel_caller(chan)->id.number.str;
+		}
+	}
+
+	if (ast_test_flag64(&opts, OPT_CALLER_NAME)) {
+		if (!ast_strlen_zero(opt_args[OPT_ARG_CALLER_NAME])) {
+			cname = opt_args[OPT_ARG_CALLER_NAME];
+		} else if (ast_channel_caller(chan)->id.name.str) {
+			cname = ast_channel_caller(chan)->id.name.str;
+		}
+	}
+
+	/* Assign variables */
+	if (ast_test_flag64(&opts, OPT_VARIABLES)
+		&& !ast_strlen_zero(opt_args[OPT_ARG_VARIABLES])) {
+		char *vartext;
+		char *text = opt_args[OPT_ARG_VARIABLES];
+		while ((vartext = ast_strsep(&text, '^', 0))) {
+			struct ast_variable *var;
+			char *varname, *varvalue;
+			if (!(varname = ast_strsep(&vartext, '=', 0))) {
+				ast_log(LOG_ERROR, "Variable syntax error: %s\n", vartext);
+				goto return_cleanup;
+			}
+			if (!(varvalue = ast_strsep(&vartext, '=', 0))) {
+				varvalue = ""; /* empty values are allowed */
+			}
+			var = ast_variable_new(varname, varvalue, "");
+			if (!var) {
+				ast_log(LOG_ERROR, "Failed to allocate variable: %s\n", varname);
+				goto return_cleanup;
+			}
+			ast_debug(1, "Appending variable '%s' with value '%s'", varname, varvalue);
+			ast_variable_list_append(&vars, var);
+		}
+	}
+
 	if (!strcasecmp(args.type, "exten")) {
+		const char *cid_num = cnum;
+		const char *cid_name = cname;
 		int priority = 1; /* Initialized in case priority not specified */
 		const char *exten = args.arg2;
 
@@ -257,16 +321,18 @@
 		res = ast_pbx_outgoing_exten_predial(chantech, cap_slin, chandata,
 				timeout * 1000, args.arg1, exten, priority, &outgoing_status,
 				ast_test_flag64(&opts, OPT_ASYNC) ? AST_OUTGOING_NO_WAIT : AST_OUTGOING_WAIT,
-				NULL, NULL, NULL, NULL, NULL, 0, NULL,
+				cid_num, cid_name, vars, NULL, NULL, 0, NULL,
 				predial_callee);
 	} else {
+		const char *cid_num = cnum;
+		const char *cid_name = cname;
 		ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
 				chantech, chandata, args.arg1, S_OR(args.arg2, ""));
 
 		res = ast_pbx_outgoing_app_predial(chantech, cap_slin, chandata,
 				timeout * 1000, args.arg1, args.arg2, &outgoing_status,
 				ast_test_flag64(&opts, OPT_ASYNC) ? AST_OUTGOING_NO_WAIT : AST_OUTGOING_WAIT,
-				NULL, NULL, NULL, NULL, NULL, NULL,
+				cid_num, cid_name, vars, NULL, NULL, NULL,
 				predial_callee);
 	}
 
@@ -311,6 +377,9 @@
 			break;
 		}
 	}
+	if (vars) {
+		ast_variables_destroy(vars);
+	}
 	ao2_cleanup(cap_slin);
 	ast_autoservice_stop(chan);
 
diff --git a/doc/CHANGES-staging/app_originate_vars.txt b/doc/CHANGES-staging/app_originate_vars.txt
new file mode 100644
index 0000000..4e08ae6
--- /dev/null
+++ b/doc/CHANGES-staging/app_originate_vars.txt
@@ -0,0 +1,6 @@
+Subject: Add variable support to Originate
+
+The Originate application now allows
+variables to be set on the new channel
+through a new option.
+

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/15951
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Ia64cfe97d2792bcbf4775b3126cad662922a8b66
Gerrit-Change-Number: 15951
Gerrit-PatchSet: 9
Gerrit-Owner: N A <mail at interlinked.x10host.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at sangoma.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210611/3ee495e2/attachment-0001.html>


More information about the asterisk-code-review mailing list