[asterisk-commits] file: branch file/dialing_api r50214 - in /team/file/dialing_api: include/ast...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Jan 9 14:06:55 MST 2007


Author: file
Date: Tue Jan  9 15:06:54 2007
New Revision: 50214

URL: http://svn.digium.com/view/asterisk?view=rev&rev=50214
Log:
Add option to execute an application upon a dialed channel picking up. Next step is converting app_page to use all this.

Modified:
    team/file/dialing_api/include/asterisk/dial.h
    team/file/dialing_api/main/dial.c

Modified: team/file/dialing_api/include/asterisk/dial.h
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/include/asterisk/dial.h?view=diff&rev=50214&r1=50213&r2=50214
==============================================================================
--- team/file/dialing_api/include/asterisk/dial.h (original)
+++ team/file/dialing_api/include/asterisk/dial.h Tue Jan  9 15:06:54 2007
@@ -35,8 +35,9 @@
 
 /*! \brief List of options that are applicable either globally or per dialed channel */
 enum ast_dial_option {
-	AST_DIAL_OPTION_RINGING,   /*! Always indicate ringing to caller */
-	AST_DIAL_OPTION_MAX,       /*! End terminator -- must always remain last */
+	AST_DIAL_OPTION_RINGING,     /*! Always indicate ringing to caller */
+	AST_DIAL_OPTION_ANSWER_EXEC, /*! Execute application upon answer in async mode */
+	AST_DIAL_OPTION_MAX,         /*! End terminator -- must always remain last */
 };
 
 /*! \brief List of return codes for dial run API calls */

Modified: team/file/dialing_api/main/dial.c
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/main/dial.c?view=diff&rev=50214&r1=50213&r2=50214
==============================================================================
--- team/file/dialing_api/main/dial.c (original)
+++ team/file/dialing_api/main/dial.c Tue Jan  9 15:06:54 2007
@@ -42,6 +42,7 @@
 #include "asterisk/lock.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/dial.h"
+#include "asterisk/pbx.h"
 
 /*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */
 struct ast_dial {
@@ -69,14 +70,81 @@
 /*! \brief Typedef for dial option disable */
 typedef int (*ast_dial_option_cb_disable)(void *data);
 
+/* Structure for 'ANSWER_EXEC' option */
+struct answer_exec_struct {
+	char app[AST_MAX_APP]; /* Application name */
+	char *args;            /* Application arguments */
+};
+
+/* Enable function for 'ANSWER_EXEC' option */
+static void *answer_exec_enable(void *data)
+{
+	struct answer_exec_struct *answer_exec = NULL;
+	char *app = ast_strdupa((char*)data), *args = NULL;
+
+	/* Not giving any data to this option is bad, mmmk? */
+	if (ast_strlen_zero(app))
+		return NULL;
+
+	/* Create new data structure */
+	if (!(answer_exec = ast_calloc(1, sizeof(*answer_exec))))
+		return NULL;
+	
+	/* Parse out application and arguments */
+	if ((args = strchr(app, '|'))) {
+		*args++ = '\0';
+		answer_exec->args = ast_strdup(args);
+	}
+
+	/* Copy application name */
+	ast_copy_string(answer_exec->app, app, sizeof(answer_exec->app));
+
+	return answer_exec;
+}
+
+/* Disable function for 'ANSWER_EXEC' option */
+static int answer_exec_disable(void *data)
+{
+	struct answer_exec_struct *answer_exec = data;
+
+	/* Make sure we have a value */
+	if (!answer_exec)
+		return -1;
+
+	/* If arguments are present, free them too */
+	if (answer_exec->args)
+		free(answer_exec->args);
+
+	/* This is simple - just free the structure */
+	free(answer_exec);
+
+	return 0;
+}
+
+/* Application execution function for 'ANSWER_EXEC' option */
+static void answer_exec_run(struct ast_channel *chan, char *app, char *args)
+{
+	struct ast_app *ast_app = pbx_findapp(app);
+
+	/* If the application was not found, return immediately */
+	if (!ast_app)
+		return;
+
+	/* All is well... execute the application */
+	pbx_exec(chan, ast_app, args);
+
+	return;
+}
+
 /*! \brief Options structure - maps options to respective handlers (enable/disable). This list MUST be perfectly kept in order, or else madness will happen. */
 static const struct ast_option_types {
 	enum ast_dial_option option;
 	ast_dial_option_cb_enable enable;
 	ast_dial_option_cb_disable disable;
 } option_types[] = {
-	{ AST_DIAL_OPTION_RINGING, NULL, NULL }, /*! Always indicate ringing to caller */
-	{ AST_DIAL_OPTION_MAX, NULL, NULL },     /*! Terminator of list */
+	{ AST_DIAL_OPTION_RINGING, NULL, NULL },                                  /*! Always indicate ringing to caller */
+	{ AST_DIAL_OPTION_ANSWER_EXEC, answer_exec_enable, answer_exec_disable }, /*! Execute application upon answer in async mode */
+	{ AST_DIAL_OPTION_MAX, NULL, NULL },                                      /*! Terminator of list */
 };
 
 /* free the buffer if allocated, and set the pointer to the second arg */
@@ -340,6 +408,7 @@
 	int timeout = -1, count = 0;
 	struct ast_channel *cs[AST_MAX_WATCHERS], *who = NULL;
 	struct ast_dial_channel *channel = NULL;
+	struct answer_exec_struct *answer_exec = NULL;
 
 	/* Switch dialing status to trying */
 	dial->status = AST_DIAL_RESULT_TRYING;
@@ -425,6 +494,9 @@
 			ast_hangup(channel->owner);
 			channel->owner = NULL;
 		}
+		/* If ANSWER_EXEC is enabled as an option, execute application on answered channel */
+		if ((answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC)))
+			answer_exec_run(AST_LIST_FIRST(&dial->channels)->owner, answer_exec->app, answer_exec->args);
 	} else if (dial->status == AST_DIAL_RESULT_HANGUP) {
 		/* Hangup everything */
 		AST_LIST_TRAVERSE(&dial->channels, channel, list) {



More information about the asterisk-commits mailing list