<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/9180">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved; Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_queue: Add option for predial handlers on caller and callee channels<br><br>Add predial handler support to app_queue.  app_dial (ASTERISK_19548) and<br>app_originate (ASTERISK_26587) have the ability to execute predial<br>handlers on caller and callee channels.  This patch adds predial handlers<br>to app_queue and uses the same options as Dial and Originate (b and B).<br>The caller routine gets executed when the caller first enters the queue.<br>The callee routine gets executed for each queue member when they are about<br>to be called.<br><br>ASTERISK-27912<br><br>Change-Id: I5acf5c32587ee008658d12e8a8049eb8fa4d0f24<br>---<br>M CHANGES<br>M apps/app_queue.c<br>2 files changed, 76 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/CHANGES b/CHANGES<br>index e969d85..5cfad79 100644<br>--- a/CHANGES<br>+++ b/CHANGES<br>@@ -67,6 +67,10 @@<br>    When set the wrapuptime on the member is used instead of the wrapuptime<br>    defined for the queue itself.<br> <br>+ * Added predial handler support for caller and callee channels with the<br>+   B and b options respectively.  This is similar to the predial support<br>+   in app_dial.<br>+<br> res_config_sqlite<br> ------------------<br>  * The res_config_sqlite module is now deprecated, users should migrate to the<br>diff --git a/apps/app_queue.c b/apps/app_queue.c<br>index 3047648..052d528 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>@@ -1545,6 +1572,7 @@<br>         char announce[PATH_MAX];               /*!< Announcement to play for member when call is answered */<br>       char context[AST_MAX_CONTEXT];         /*!< Context when user exits queue */<br>       char digits[AST_MAX_EXTENSION];        /*!< Digits entered while in queue */<br>+      const char *predial_callee;            /*!< Gosub app arguments for outgoing calls.  NULL if not supplied. */<br>      int valid_digits;                      /*!< Digits entered correspond to valid extension. Exited */<br>        int pos;                               /*!< Where we are in the queue */<br>   int prio;                              /*!< Our priority */<br>@@ -4559,6 +4587,11 @@<br>        ast_channel_unlock(tmp->chan);<br>     ast_channel_unlock(qe->chan);<br> <br>+  /* PREDIAL: Run gosub on the callee's channel */<br>+ if (qe->predial_callee) {<br>+         ast_pre_call(tmp->chan, qe->predial_callee);<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>@@ -4615,6 +4648,16 @@<br> static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)<br> {<br>       int ret = 0;<br>+ struct callattempt *cur;<br>+<br>+  if (qe->predial_callee) {<br>+         ast_autoservice_start(qe->chan);<br>+          for (cur = outgoing; cur; cur = cur->q_next) {<br>+                    if (cur->stillgoing && cur->chan) {<br>+                            ast_autoservice_start(cur->chan);<br>+                 }<br>+            }<br>+    }<br> <br>  while (ret == 0) {<br>            struct callattempt *best = find_best(outgoing);<br>@@ -4623,18 +4666,23 @@<br>                      break;<br>                }<br>             if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {<br>-                  struct callattempt *cur;<br>                      /* Ring everyone who shares this best metric (for ringall) */<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>+                                  if (qe->predial_callee && cur->chan) {<br>+                                         ast_autoservice_start(cur->chan);<br>+                                 }<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>+                  if (qe->predial_callee && cur->chan) {<br>+                         ast_autoservice_start(best->chan);<br>+                        }<br>             }<br> <br>          /* If we have timed out, break out */<br>@@ -4643,6 +4691,14 @@<br>                         ret = 0;<br>                      break;<br>                }<br>+    }<br>+    if (qe->predial_callee) {<br>+         for (cur = outgoing; cur; cur = cur->q_next) {<br>+                    if (cur->stillgoing && cur->chan) {<br>+                            ast_autoservice_stop(cur->chan);<br>+                  }<br>+            }<br>+            ast_autoservice_stop(qe->chan);<br>    }<br> <br>  return ret;<br>@@ -8270,6 +8326,21 @@<br>           S_OR(args.url, ""),<br>                 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""),<br>                qe.opos);<br>+<br>+ /* PREDIAL: Preprocess any callee gosub arguments. */<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>+         qe.predial_callee = opt_args[OPT_ARG_PREDIAL_CALLEE];<br>+        }<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>  copy_rules(&qe, args.rule);<br>       qe.pr = AST_LIST_FIRST(&qe.qe_rules);<br> check_turns:<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: merged </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: 4 </div>
<div style="display:none"> Gerrit-Owner: Kristian Høgh <kfh@uni-tel.dk> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>