<p>Kristian Høgh has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/9180">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_queue: Add option for predial handlers on caller and callee channels<br><br>ASTERISK-27912: Add predial handler to app_queue<br>app_dial (ASTERISK-19548) and app_originate (ASTERISK-26587) have the<br>possibility to execute predial handlers on caller and callee channel.<br>This patch adds predial handler on app_queue and uses same options<br>as Dial and Originate (b and B).<br>Gosub is executed on originating channel when it gets first in line<br>and on each newly created outgoing channel.<br><br>Change-Id: I5acf5c32587ee008658d12e8a8049eb8fa4d0f24<br>---<br>M apps/app_queue.c<br>1 file changed, 52 insertions(+), 11 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/80/9180/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/apps/app_queue.c b/apps/app_queue.c<br>index 3047648..5c03e46 100644<br>--- a/apps/app_queue.c<br>+++ b/apps/app_queue.c<br>@@ -133,6 +133,27 @@<br>                       <parameter name="queuename" required="true" /><br>                      <parameter name="options"><br>                            <optionlist><br>+                                   <option name="b" argsep="^"><br>+                                               <para>Before initiating an outgoing call, <literal>Gosub</literal> to the specified<br>+                                                location using the newly created channel.  The <literal>Gosub</literal> will be<br>+                                          executed for each destination channel.</para><br>+                                          <argument name="context" required="false" /><br>+                                               <argument name="exten" required="false" /><br>+                                         <argument name="priority" required="true" hasparams="optional" argsep="^"><br>+                                                     <argument name="arg1" multiple="true" required="true" /><br>+                                                 <argument name="argN" /><br>+                                             </argument><br>+                                    </option><br>+                                      <option name="B" argsep="^"><br>+                                               <para>Before initiating the outgoing call(s), <literal>Gosub</literal> to the<br>+                                              specified location using the current channel.</para><br>+                                           <argument name="context" required="false" /><br>+                                               <argument name="exten" required="false" /><br>+                                         <argument name="priority" required="true" hasparams="optional" argsep="^"><br>+                                                     <argument name="arg1" multiple="true" required="true" /><br>+                                                 <argument name="argN" /><br>+                                             </argument><br>+                                    </option><br>                                       <option name="C"><br>                                             <para>Mark all calls as "answered elsewhere" when cancelled.</para><br>                                     </option><br>@@ -1325,15 +1346,21 @@<br>      OPT_CALLER_AUTOMIXMON =      (1 << 16),<br>         OPT_CALLEE_AUTOMON =         (1 << 17),<br>         OPT_CALLER_AUTOMON =         (1 << 18),<br>+        OPT_PREDIAL_CALLEE =         (1 << 19),<br>+        OPT_PREDIAL_CALLER =         (1 << 20),<br> };<br> <br> enum {<br>        OPT_ARG_CALLEE_GO_ON = 0,<br>+    OPT_ARG_PREDIAL_CALLEE,<br>+      OPT_ARG_PREDIAL_CALLER,<br>       /* note: this entry _MUST_ be the last one in the enum */<br>     OPT_ARG_ARRAY_SIZE<br> };<br> <br> AST_APP_OPTIONS(queue_exec_options, BEGIN_OPTIONS<br>+       AST_APP_OPTION_ARG('b', OPT_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLEE),<br>+ AST_APP_OPTION_ARG('B', OPT_PREDIAL_CALLER, OPT_ARG_PREDIAL_CALLER),<br>  AST_APP_OPTION('C', OPT_MARK_AS_ANSWERED),<br>    AST_APP_OPTION('c', OPT_GO_ON),<br>       AST_APP_OPTION('d', OPT_DATA_QUALITY),<br>@@ -4462,7 +4489,7 @@<br>  * \retval 1 on success to reach a free agent<br>  * \retval 0 on failure to get agent.<br>  */<br>-static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)<br>+static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies, struct ast_flags opts, char **opt_args)<br> {<br>       int res;<br>      int status;<br>@@ -4559,6 +4586,13 @@<br>   ast_channel_unlock(tmp->chan);<br>     ast_channel_unlock(qe->chan);<br> <br>+  /* PREDIAL: Run gosub on the callee's channel */<br>+ if (ast_test_flag(&opts, OPT_PREDIAL_CALLEE)<br>+             && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLEE])) {<br>+             ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);<br>+         ast_app_exec_sub(NULL, tmp->chan, opt_args[OPT_ARG_PREDIAL_CALLEE], 0);<br>+   }<br>+<br>  /* Place the call, but don't wait on the answer */<br>        if ((res = ast_call(tmp->chan, location, 0))) {<br>            /* Again, keep going even if there's an error */<br>@@ -4612,7 +4646,7 @@<br>  * \retval 1 if a member was called successfully<br>  * \retval 0 otherwise<br>  */<br>-static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)<br>+static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies, struct ast_flags opts, char **opt_args)<br> {<br>       int ret = 0;<br> <br>@@ -4628,13 +4662,13 @@<br>                      for (cur = outgoing; cur; cur = cur->q_next) {<br>                             if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {<br>                                    ast_debug(1, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);<br>-                                        ret |= ring_entry(qe, cur, busies);<br>+                                  ret |= ring_entry(qe, cur, busies, opts, opt_args);<br>                           }<br>                     }<br>             } else {<br>                      /* Ring just the best channel */<br>                      ast_debug(1, "Trying '%s' with metric %d\n", best->interface, best->metric);<br>-                 ret = ring_entry(qe, best, busies);<br>+                  ret = ring_entry(qe, best, busies, opts, opt_args);<br>           }<br> <br>          /* If we have timed out, break out */<br>@@ -4887,7 +4921,7 @@<br>  *<br>  * \todo eventually all call forward logic should be intergerated into and replaced by ast_call_forward()<br>  */<br>-static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)<br>+static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed, struct ast_flags opts, char **opt_args)<br> {<br>   const char *queue = qe->parent->name;<br>   struct callattempt *o, *start = NULL, *prev = NULL;<br>@@ -4947,7 +4981,7 @@<br>                    }<br>                     /* On "ringall" strategy we only move to the next penalty level<br>                        when *all* ringing phones are done in the current penalty level */<br>-                        ring_one(qe, outgoing, &numbusies);<br>+                      ring_one(qe, outgoing, &numbusies, opts, opt_args);<br>                       /* and retry... */<br>            }<br>             if (pos == 1 /* not found */) {<br>@@ -5208,7 +5242,7 @@<br>                                                                }<br>                                                             /* Have enough time for a queue member to answer? */<br>                                                          if (ast_remaining_ms(start_time_tv, orig) > 500) {<br>-                                                                        ring_one(qe, outgoing, &numbusies);<br>+                                                                      ring_one(qe, outgoing, &numbusies, opts, opt_args);<br>                                                                       starttime = (long) time(NULL);<br>                                                                }<br>                                                     }<br>@@ -5226,7 +5260,7 @@<br>                                                                      start_time_tv = ast_tvnow();<br>                                                          }<br>                                                             if (ast_remaining_ms(start_time_tv, orig) > 500) {<br>-                                                                        ring_one(qe, outgoing, &numbusies);<br>+                                                                      ring_one(qe, outgoing, &numbusies, opts, opt_args);<br>                                                                       starttime = (long) time(NULL);<br>                                                                }<br>                                                     }<br>@@ -5324,7 +5358,7 @@<br>                                                      start_time_tv = ast_tvnow();<br>                                          }<br>                                             if (ast_remaining_ms(start_time_tv, orig) > 500) {<br>-                                                        ring_one(qe, outgoing, &numbusies);<br>+                                                      ring_one(qe, outgoing, &numbusies, opts, opt_args);<br>                                                       starttime = (long) time(NULL);<br>                                                }<br>                                     }<br>@@ -6831,10 +6865,10 @@<br>    orig = to;<br>    ++qe->pending;<br>     ao2_unlock(qe->parent);<br>-   ring_one(qe, outgoing, &numbusies);<br>+      ring_one(qe, outgoing, &numbusies, opts, opt_args);<br>       lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies,<br>                 ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT),<br>-         forwardsallowed);<br>+            forwardsallowed, opts, opt_args);<br> <br>  ao2_lock(qe->parent);<br>      if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_RRORDERED) {<br>@@ -8287,6 +8321,13 @@<br> <br>     makeannouncement = qe.parent->announce_to_first_user;<br> <br>+  /* PREDIAL: Run gosub on the caller's channel */<br>+ if (ast_test_flag(&opts, OPT_PREDIAL_CALLER)<br>+             && !ast_strlen_zero(opt_args[OPT_ARG_PREDIAL_CALLER])) {<br>+             ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLER]);<br>+         ast_app_exec_sub(NULL, chan, opt_args[OPT_ARG_PREDIAL_CALLER], 0);<br>+   }<br>+<br>  for (;;) {<br>            /* This is the wait loop for the head caller*/<br>                /* To exit, they may get their call answered; */<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/9180">change 9180</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/9180"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I5acf5c32587ee008658d12e8a8049eb8fa4d0f24 </div>
<div style="display:none"> Gerrit-Change-Number: 9180 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Kristian Høgh <kfh@uni-tel.dk> </div>