]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Run predial routine on local;2 channel where you would expect.
authorRichard Mudgett <rmudgett@digium.com>
Thu, 10 May 2012 21:29:41 +0000 (21:29 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 10 May 2012 21:29:41 +0000 (21:29 +0000)
Before this patch, the predial routine executes on the ;1 channel of a
local channel pair.  Executing predial on the ;1 channel of a local
channel pair is of limited utility.  Any channel variables set by the
predial routine executing on the ;1 channel will not be available when the
local channel executes dialplan on the ;2 channel.

* Create ast_pre_call() and an associated pre_call() technology callback
to handle running the predial routine.  If a channel technology does not
provide the callback, the predial routine is simply run on the channel.

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

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@366183 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_dial.c
channels/chan_local.c
include/asterisk/channel.h
main/channel.c

index 72a38ce9cf9f799d6454e621522b18b05cad492b..ceca20f120d42ac3b4844d34723870e3c0f4dc94 100644 (file)
@@ -2478,7 +2478,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                ast_autoservice_start(chan);
                ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
                AST_LIST_TRAVERSE(&out_chans, tmp, node) {
-                       ast_app_exec_sub(NULL, tmp->chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
+                       ast_pre_call(tmp->chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
                }
                ast_autoservice_stop(chan);
        }
index a7e83bcfa20489c65d188bf9542f0997878b8a0a..a37a4a4ed870f1232e75ec29b3a6fd19ac24c293 100644 (file)
@@ -95,6 +95,7 @@ static struct ast_jb_conf g_jb_conf = {
 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
 static int local_digit_begin(struct ast_channel *ast, char digit);
 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
+static int local_pre_call(struct ast_channel *ast, const char *sub_args);
 static int local_call(struct ast_channel *ast, const char *dest, int timeout);
 static int local_hangup(struct ast_channel *ast);
 static int local_answer(struct ast_channel *ast);
@@ -116,6 +117,7 @@ static struct ast_channel_tech local_tech = {
        .requester = local_request,
        .send_digit_begin = local_digit_begin,
        .send_digit_end = local_digit_end,
+       .pre_call = local_pre_call,
        .call = local_call,
        .hangup = local_hangup,
        .answer = local_answer,
@@ -1257,6 +1259,34 @@ static struct ast_channel *local_request(const char *type, struct ast_format_cap
        return chan;
 }
 
+static int local_pre_call(struct ast_channel *ast, const char *sub_args)
+{
+       struct local_pvt *p = ast_channel_tech_pvt(ast);
+       struct ast_channel *chan;
+       int res;
+
+       ao2_lock(p);
+       chan = p->chan;
+       if (chan) {
+               ast_channel_ref(chan);
+       }
+       ao2_unlock(p);
+       if (!chan) {
+               return -1;
+       }
+
+       /*
+        * Execute the predial routine on the ;2 channel so any channel
+        * variables set by the predial will be available to the local
+        * channel PBX.
+        */
+       ast_channel_unlock(ast);
+       res = ast_app_exec_sub(NULL, chan, sub_args);
+       ast_channel_unref(chan);
+       ast_channel_lock(ast);
+       return res;
+}
+
 /*! \brief CLI command "local show channels" */
 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
index ab6c736ed0ddddb877c37f80994c4797469886e9..d71b7e5121844e353c1aead46e184cd50565d13f 100644 (file)
@@ -676,6 +676,20 @@ struct ast_channel_tech {
         * parameters as a parameter.
         */
        int (* cc_callback)(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
+
+       /*!
+        * \brief Execute a Gosub call on the channel in a technology specific way before a call is placed.
+        * \since 11.0
+        *
+        * \param chan Channel to execute Gosub in a tech specific way.
+        * \param sub_args Gosub application parameter string.
+        *
+        * \note The chan is locked before calling.
+        *
+        * \retval 0 on success.
+        * \retval -1 on error.
+        */
+       int (*pre_call)(struct ast_channel *chan, const char *sub_args);
 };
 
 /*! Kill the channel channel driver technology descriptor. */
@@ -1526,6 +1540,24 @@ int ast_raw_answer(struct ast_channel *chan, int cdr_answer);
  */
 int __ast_answer(struct ast_channel *chan, unsigned int delay, int cdr_answer);
 
+/*!
+ * \brief Execute a Gosub call on the channel before a call is placed.
+ * \since 11.0
+ *
+ * \details
+ * This is called between ast_request() and ast_call() to
+ * execute a predial routine on the newly created channel.
+ *
+ * \param chan Channel to execute Gosub.
+ * \param sub_args Gosub application parameter string.
+ *
+ * \note Absolutely _NO_ channel locks should be held before calling this function.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_pre_call(struct ast_channel *chan, const char *sub_args);
+
 /*!
  * \brief Make a call
  * \note Absolutely _NO_ channel locks should be held before calling this function.
index 3d8e223026a0cc7c7143d11e89bc15f88732d316..c00ffb536622ea16f84f163ef6ef012d1f40b14a 100644 (file)
@@ -5671,6 +5671,23 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
        return NULL;
 }
 
+int ast_pre_call(struct ast_channel *chan, const char *sub_args)
+{
+       int (*pre_call)(struct ast_channel *chan, const char *sub_args);
+
+       ast_channel_lock(chan);
+       pre_call = ast_channel_tech(chan)->pre_call;
+       if (pre_call) {
+               int res;
+
+               res = pre_call(chan, sub_args);
+               ast_channel_unlock(chan);
+               return res;
+       }
+       ast_channel_unlock(chan);
+       return ast_app_exec_sub(NULL, chan, sub_args);
+}
+
 int ast_call(struct ast_channel *chan, const char *addr, int timeout)
 {
        /* Place an outgoing call, but don't wait any longer than timeout ms before returning.