[asterisk-commits] rmudgett: trunk r366507 - in /trunk: CHANGES apps/app_followme.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue May 15 11:53:17 CDT 2012


Author: rmudgett
Date: Tue May 15 11:53:09 2012
New Revision: 366507

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=366507
Log:
Add predial support to FollowMe.

Like the new predial feature for Dial.  This adds the same b/B options to
FollowMe.

Review: https://reviewboard.asterisk.org/r/1910/

Modified:
    trunk/CHANGES
    trunk/apps/app_followme.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=366507&r1=366506&r2=366507
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Tue May 15 11:53:09 2012
@@ -225,6 +225,8 @@
    connected line changes when they occur.  This is similar to app_dial
    and app_queue.
  * The 'N' option is now ignored if the call is already answered.
+ * Added 'b' and 'B' options to FollowMe that execute a Gosub on callee
+   and caller channels respectively before the callee channels are called.
 
 RTP changes
 -------------

Modified: trunk/apps/app_followme.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_followme.c?view=diff&rev=366507&r1=366506&r2=366507
==============================================================================
--- trunk/apps/app_followme.c (original)
+++ trunk/apps/app_followme.c Tue May 15 11:53:09 2012
@@ -70,6 +70,27 @@
 					<option name="a">
 						<para>Record the caller's name so it can be announced to the
 						callee on each step.</para>
+					</option>
+					<option name="B" argsep="^">
+						<para>Before initiating the outgoing call(s), Gosub to the specified
+						location using the current channel.</para>
+						<argument name="context" required="false" />
+						<argument name="exten" required="false" />
+						<argument name="priority" required="true" hasparams="optional" argsep="^">
+							<argument name="arg1" multiple="true" required="true" />
+							<argument name="argN" />
+						</argument>
+					</option>
+					<option name="b" argsep="^">
+						<para>Before initiating an outgoing call, Gosub to the specified
+						location using the newly created channel.  The Gosub will be
+						executed for each destination channel.</para>
+						<argument name="context" required="false" />
+						<argument name="exten" required="false" />
+						<argument name="priority" required="true" hasparams="optional" argsep="^">
+							<argument name="arg1" multiple="true" required="true" />
+							<argument name="argN" />
+						</argument>
 					</option>
 					<option name="d">
 						<para>Disable the 'Please hold while we try to connect your call' announcement.</para>
@@ -155,6 +176,8 @@
 struct fm_args {
 	char *mohclass;
 	AST_LIST_HEAD_NOLOCK(cnumbers, number) cnumbers;
+	/*! Gosub app arguments for outgoing calls.  NULL if not supplied. */
+	const char *predial_callee;
 	/*! Accumulated connected line information from inbound call. */
 	struct ast_party_connected_line connected_in;
 	/*! Accumulated connected line information from outbound call. */
@@ -205,10 +228,22 @@
 	FOLLOWMEFLAG_NOANSWER = (1 << 4),
 	FOLLOWMEFLAG_DISABLEOPTIMIZATION = (1 << 5),
 	FOLLOWMEFLAG_IGNORE_CONNECTEDLINE = (1 << 6),
+	FOLLOWMEFLAG_PREDIAL_CALLER = (1 << 7),
+	FOLLOWMEFLAG_PREDIAL_CALLEE = (1 << 8),
+};
+
+enum {
+	FOLLOWMEFLAG_ARG_PREDIAL_CALLER,
+	FOLLOWMEFLAG_ARG_PREDIAL_CALLEE,
+
+	/* note: this entry _MUST_ be the last one in the enum */
+	FOLLOWMEFLAG_ARG_ARRAY_SIZE
 };
 
 AST_APP_OPTIONS(followme_opts, {
 	AST_APP_OPTION('a', FOLLOWMEFLAG_RECORDNAME),
+	AST_APP_OPTION_ARG('B', FOLLOWMEFLAG_PREDIAL_CALLER, FOLLOWMEFLAG_ARG_PREDIAL_CALLER),
+	AST_APP_OPTION_ARG('b', FOLLOWMEFLAG_PREDIAL_CALLEE, FOLLOWMEFLAG_ARG_PREDIAL_CALLEE),
 	AST_APP_OPTION('d', FOLLOWMEFLAG_DISABLEHOLDPROMPT),
 	AST_APP_OPTION('I', FOLLOWMEFLAG_IGNORE_CONNECTEDLINE),
 	AST_APP_OPTION('l', FOLLOWMEFLAG_DISABLEOPTIMIZATION),
@@ -1044,6 +1079,48 @@
 			AST_LIST_INSERT_TAIL(&new_user_list, tmpuser, entry);
 		}
 
+		/*
+		 * PREDIAL: Run gosub on all of the new callee channels
+		 *
+		 * We run the callee predial before ast_call() in case the user
+		 * wishes to do something on the newly created channels before
+		 * the channel does anything important.
+		 */
+		if (tpargs->predial_callee && !AST_LIST_EMPTY(&new_user_list)) {
+			/* Put caller into autoservice. */
+			ast_autoservice_start(caller);
+
+			/* Run predial on all new outgoing calls. */
+			AST_LIST_TRAVERSE(&new_user_list, tmpuser, entry) {
+				ast_pre_call(tmpuser->ochan, tpargs->predial_callee);
+			}
+
+			/* Take caller out of autoservice. */
+			if (ast_autoservice_stop(caller)) {
+				/*
+				 * Caller hungup.
+				 *
+				 * Destoy all new outgoing calls.
+				 */
+				while ((tmpuser = AST_LIST_REMOVE_HEAD(&new_user_list, entry))) {
+					ast_channel_lock(tmpuser->ochan);
+					if (ast_channel_cdr(tmpuser->ochan)) {
+						ast_cdr_init(ast_channel_cdr(tmpuser->ochan), tmpuser->ochan);
+					}
+					ast_channel_unlock(tmpuser->ochan);
+					destroy_calling_node(tmpuser);
+				}
+
+				/* Take all active outgoing channels out of autoservice. */
+				AST_LIST_TRAVERSE(&findme_user_list, tmpuser, entry) {
+					if (tmpuser->ochan) {
+						ast_autoservice_stop(tmpuser->ochan);
+					}
+				}
+				break;
+			}
+		}
+
 		/* Start all new outgoing calls */
 		AST_LIST_TRAVERSE_SAFE_BEGIN(&new_user_list, tmpuser, entry) {
 			ast_verb(3, "calling Local/%s\n", tmpuser->dialarg);
@@ -1237,6 +1314,7 @@
 		AST_APP_ARG(followmeid);
 		AST_APP_ARG(options);
 	);
+	char *opt_args[FOLLOWMEFLAG_ARG_ARRAY_SIZE];
 
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "%s requires an argument (followmeid)\n", app);
@@ -1278,7 +1356,7 @@
 
 	/* XXX TODO: Reinsert the db check value to see whether or not follow-me is on or off */
 	if (args.options) {
-		ast_app_parse_options(followme_opts, &targs->followmeflags, NULL, args.options);
+		ast_app_parse_options(followme_opts, &targs->followmeflags, opt_args, args.options);
 	}
 
 	/* Lock the profile lock and copy out everything we need to run with before unlocking it again */
@@ -1304,6 +1382,20 @@
 	}
 	ast_mutex_unlock(&f->lock);
 
+	/* PREDIAL: Preprocess any callee gosub arguments. */
+	if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_PREDIAL_CALLEE)
+		&& !ast_strlen_zero(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLEE])) {
+		ast_replace_subargument_delimiter(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLEE]);
+		targs->predial_callee = opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLEE];
+	}
+
+	/* PREDIAL: Run gosub on the caller's channel */
+	if (ast_test_flag(&targs->followmeflags, FOLLOWMEFLAG_PREDIAL_CALLER)
+		&& !ast_strlen_zero(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLER])) {
+		ast_replace_subargument_delimiter(opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLER]);
+		ast_app_exec_sub(NULL, chan, opt_args[FOLLOWMEFLAG_ARG_PREDIAL_CALLER]);
+	}
+
 	/* Forget the 'N' option if the call is already up. */
 	if (ast_channel_state(chan) == AST_STATE_UP) {
 		ast_clear_flag(&targs->followmeflags, FOLLOWMEFLAG_NOANSWER);




More information about the asterisk-commits mailing list