<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/14696">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">followme: allow disabling callee prompt<br><br>Add the option 'enable_callee_prompt' to followme.conf. Enabled by<br>default. If disabled, a callee is not prompted to accept or reject<br>the forwarded call.<br><br>ASTERISK-29010 #close<br><br>Change-Id: Ic15a2bac4f16d0fce7a1b5e7b375f9bafee37aa4<br>Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com><br>---<br>M apps/app_followme.c<br>M configs/samples/followme.conf.sample<br>2 files changed, 68 insertions(+), 30 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_followme.c b/apps/app_followme.c</span><br><span>index 21b9a19..1ceb6b5 100644</span><br><span>--- a/apps/app_followme.c</span><br><span>+++ b/apps/app_followme.c</span><br><span>@@ -168,6 +168,8 @@</span><br><span>       char context[AST_MAX_CONTEXT];  /*!< Context to dial from */</span><br><span>      unsigned int active;            /*!< Profile is active (1), or disabled (0). */</span><br><span>   int realtime;           /*!< Cached from realtime */</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! Allow callees to accept/reject the forwarded call */</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int enable_callee_prompt:1;</span><br><span>         char takecall[MAX_YN_STRING];   /*!< Digit mapping to take a call */</span><br><span>      char nextindp[MAX_YN_STRING];   /*!< Digit mapping to decline a call */</span><br><span>   char callfromprompt[PATH_MAX];  /*!< Sound prompt name and path */</span><br><span>@@ -199,6 +201,8 @@</span><br><span>  unsigned int pending_out_connected_update:1;</span><br><span>         /*! TRUE if caller has a pending hold request for the winning call. */</span><br><span>       unsigned int pending_hold:1;</span><br><span style="color: hsl(120, 100%, 40%);">+  /*! TRUE if callees will be prompted to answer */</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int enable_callee_prompt:1;</span><br><span>         /*! Music On Hold Class suggested by caller hold for winning call. */</span><br><span>        char suggested_moh[MAX_MUSICCLASS];</span><br><span>  char context[AST_MAX_CONTEXT];</span><br><span>@@ -270,6 +274,7 @@</span><br><span> </span><br><span> static char takecall[MAX_YN_STRING] = "1";</span><br><span> static char nextindp[MAX_YN_STRING] = "2";</span><br><span style="color: hsl(120, 100%, 40%);">+static int enable_callee_prompt = 1;</span><br><span> static char callfromprompt[PATH_MAX] = "followme/call-from";</span><br><span> static char norecordingprompt[PATH_MAX] = "followme/no-recording";</span><br><span> static char optionsprompt[PATH_MAX] = "followme/options";</span><br><span>@@ -314,6 +319,7 @@</span><br><span> </span><br><span>    ast_mutex_init(&f->lock);</span><br><span>     ast_copy_string(f->name, fmname, sizeof(f->name));</span><br><span style="color: hsl(120, 100%, 40%);">+      f->enable_callee_prompt = enable_callee_prompt;</span><br><span>   AST_LIST_HEAD_INIT_NOLOCK(&f->numbers);</span><br><span>       AST_LIST_HEAD_INIT_NOLOCK(&f->blnumbers);</span><br><span>     AST_LIST_HEAD_INIT_NOLOCK(&f->wlnumbers);</span><br><span>@@ -348,6 +354,8 @@</span><br><span>               ast_copy_string(f->moh, val, sizeof(f->moh));</span><br><span>  else if (!strcasecmp(param, "context"))</span><br><span>            ast_copy_string(f->context, val, sizeof(f->context));</span><br><span style="color: hsl(120, 100%, 40%);">+   else if (!strcasecmp(param, "enable_callee_prompt"))</span><br><span style="color: hsl(120, 100%, 40%);">+                f->enable_callee_prompt = ast_true(val);</span><br><span>  else if (!strcasecmp(param, "takecall"))</span><br><span>           ast_copy_string(f->takecall, val, sizeof(f->takecall));</span><br><span>        else if (!strcasecmp(param, "declinecall"))</span><br><span>@@ -404,6 +412,7 @@</span><br><span>  struct number *cur, *nm;</span><br><span>     int timeout;</span><br><span>         int numorder;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char* enable_callee_prompt_str;</span><br><span>        const char *takecallstr;</span><br><span>     const char *declinecallstr;</span><br><span>  const char *tmpstr;</span><br><span>@@ -436,6 +445,12 @@</span><br><span>                   featuredigittimeout = 5000;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if ((enable_callee_prompt_str = ast_variable_retrieve(cfg, "general",</span><br><span style="color: hsl(120, 100%, 40%);">+                                       "enable_callee_prompt")) &&</span><br><span style="color: hsl(120, 100%, 40%);">+                 !ast_strlen_zero(enable_callee_prompt_str)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         enable_callee_prompt = ast_true(enable_callee_prompt_str);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if ((takecallstr = ast_variable_retrieve(cfg, "general", "takecall")) && !ast_strlen_zero(takecallstr)) {</span><br><span>                ast_copy_string(takecall, takecallstr, sizeof(takecall));</span><br><span>    }</span><br><span>@@ -667,26 +682,30 @@</span><br><span>                    if (tmpuser->digts && (tmpuser->digts > featuredigittimeout)) {</span><br><span>                             ast_verb(3, "<%s> We've been waiting for digits longer than we should have.\n",</span><br><span>                                  ast_channel_name(tmpuser->ochan));</span><br><span style="color: hsl(0, 100%, 40%);">-                           if (!ast_strlen_zero(tpargs->namerecloc)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  tmpuser->state = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                                  tmpuser->digts = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                                  if (!ast_streamfile(tmpuser->ochan, callfromname, ast_channel_language(tmpuser->ochan))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                                ast_sched_runq(ast_channel_sched(tmpuser->ochan));</span><br><span style="color: hsl(120, 100%, 40%);">+                         if (tpargs->enable_callee_prompt) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                        if (!ast_strlen_zero(tpargs->namerecloc)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                tmpuser->state = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                tmpuser->digts = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                if (!ast_streamfile(tmpuser->ochan, callfromname, ast_channel_language(tmpuser->ochan))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      ast_sched_runq(ast_channel_sched(tmpuser->ochan));</span><br><span style="color: hsl(120, 100%, 40%);">+                                         } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     clear_caller(tmpuser);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                                             }</span><br><span>                                    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                                ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);</span><br><span style="color: hsl(0, 100%, 40%);">-                                               clear_caller(tmpuser);</span><br><span style="color: hsl(0, 100%, 40%);">-                                          continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                                             tmpuser->state = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                tmpuser->digts = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, ast_channel_language(tmpuser->ochan)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        ast_sched_runq(ast_channel_sched(tmpuser->ochan));</span><br><span style="color: hsl(120, 100%, 40%);">+                                         else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        ast_log(LOG_WARNING, "Unable to playback %s.\n", tpargs->norecordingprompt);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     clear_caller(tmpuser);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                                             }</span><br><span>                                    }</span><br><span>                            } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        tmpuser->state = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-                                  tmpuser->digts = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                                  if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, ast_channel_language(tmpuser->ochan)))</span><br><span style="color: hsl(0, 100%, 40%);">-                                          ast_sched_runq(ast_channel_sched(tmpuser->ochan));</span><br><span style="color: hsl(0, 100%, 40%);">-                                   else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                          ast_log(LOG_WARNING, "Unable to playback %s.\n", tpargs->norecordingprompt);</span><br><span style="color: hsl(0, 100%, 40%);">-                                               clear_caller(tmpuser);</span><br><span style="color: hsl(0, 100%, 40%);">-                                          continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                                       }</span><br><span style="color: hsl(120, 100%, 40%);">+                                     tmpuser->state = 3;</span><br><span>                               }</span><br><span>                    }</span><br><span>                    if (ast_channel_stream(tmpuser->ochan)) {</span><br><span>@@ -799,23 +818,28 @@</span><br><span>                                                 /* If call has been answered, then the eventual hangup is likely to be normal hangup */</span><br><span>                                              ast_channel_hangupcause_set(winner, AST_CAUSE_NORMAL_CLEARING);</span><br><span>                                              ast_channel_hangupcause_set(caller, AST_CAUSE_NORMAL_CLEARING);</span><br><span style="color: hsl(0, 100%, 40%);">-                                         ast_verb(3, "Starting playback of %s\n", callfromname);</span><br><span style="color: hsl(0, 100%, 40%);">-                                               if (!ast_strlen_zero(tpargs->namerecloc)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                                  if (!ast_streamfile(winner, callfromname, ast_channel_language(winner))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                                              ast_sched_runq(ast_channel_sched(winner));</span><br><span style="color: hsl(0, 100%, 40%);">-                                                              tmpuser->state = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                if (tpargs->enable_callee_prompt) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        ast_verb(3, "Starting playback of %s\n", callfromname);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     if (!ast_strlen_zero(tpargs->namerecloc)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                if (!ast_streamfile(winner, callfromname, ast_channel_language(winner))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                    ast_sched_runq(ast_channel_sched(winner));</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                    tmpuser->state = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                      ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                     clear_caller(tmpuser);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                }</span><br><span>                                                    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                                                ast_log(LOG_WARNING, "Unable to playback %s.\n", callfromname);</span><br><span style="color: hsl(0, 100%, 40%);">-                                                               clear_caller(tmpuser);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                tmpuser->state = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, ast_channel_language(tmpuser->ochan)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                        ast_sched_runq(ast_channel_sched(tmpuser->ochan));</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                        ast_log(LOG_WARNING, "Unable to playback %s.\n", tpargs->norecordingprompt);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                     clear_caller(tmpuser);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                }</span><br><span>                                                    }</span><br><span>                                            } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      ast_verb(3, "Skip playback of caller name / norecording\n");</span><br><span>                                                       tmpuser->state = 2;</span><br><span style="color: hsl(0, 100%, 40%);">-                                                  if (!ast_streamfile(tmpuser->ochan, tpargs->norecordingprompt, ast_channel_language(tmpuser->ochan)))</span><br><span style="color: hsl(0, 100%, 40%);">-                                                          ast_sched_runq(ast_channel_sched(tmpuser->ochan));</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                                          ast_log(LOG_WARNING, "Unable to playback %s.\n", tpargs->norecordingprompt);</span><br><span style="color: hsl(0, 100%, 40%);">-                                                               clear_caller(tmpuser);</span><br><span style="color: hsl(0, 100%, 40%);">-                                                  }</span><br><span>                                            }</span><br><span>                                            break;</span><br><span>                                       case AST_CONTROL_BUSY:</span><br><span>@@ -939,6 +963,11 @@</span><br><span>                                                break;</span><br><span>                                       }</span><br><span>                            }</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (!tpargs->enable_callee_prompt && tmpuser) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                    ast_debug(1, "Taking call with no prompt\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                       ast_frfree(f);</span><br><span style="color: hsl(120, 100%, 40%);">+                                        return tmpuser->ochan;</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span>                            if (tmpuser && tmpuser->state == 3 && f->frametype == AST_FRAME_DTMF) {</span><br><span>                                        int cmp_len;</span><br><span> </span><br><span>@@ -1378,6 +1407,7 @@</span><br><span> </span><br><span>         /* Lock the profile lock and copy out everything we need to run with before unlocking it again */</span><br><span>    ast_mutex_lock(&f->lock);</span><br><span style="color: hsl(120, 100%, 40%);">+      targs->enable_callee_prompt = f->enable_callee_prompt;</span><br><span>         targs->mohclass = ast_strdupa(f->moh);</span><br><span>         ast_copy_string(targs->context, f->context, sizeof(targs->context));</span><br><span>        ast_copy_string(targs->takecall, f->takecall, sizeof(targs->takecall));</span><br><span>diff --git a/configs/samples/followme.conf.sample b/configs/samples/followme.conf.sample</span><br><span>index eb12cbd..25421e6 100644</span><br><span>--- a/configs/samples/followme.conf.sample</span><br><span>+++ b/configs/samples/followme.conf.sample</span><br><span>@@ -5,6 +5,11 @@</span><br><span> ; The number of ms to wait for a digit input for the callee on whether to take the call or</span><br><span> ; not before we consider them "done" entering digits.</span><br><span> ;</span><br><span style="color: hsl(120, 100%, 40%);">+enable_callee_prompt=>true</span><br><span style="color: hsl(120, 100%, 40%);">+; Enable prompting a callee to either accept or reject the forwarded call.</span><br><span style="color: hsl(120, 100%, 40%);">+; If disabled, the optional prompting for caller name (option 'a') is</span><br><span style="color: hsl(120, 100%, 40%);">+; likewise disabled. Enabled by default.</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span> takecall=>1</span><br><span> ; The global default keypress for the callee to take taking the current call. This can be</span><br><span> ; a single digit or multiple digits. Default is "1".</span><br><span>@@ -58,6 +63,9 @@</span><br><span> ; step to make a choice on whether to take the call or not.  That being the case,</span><br><span> ; you may want to make the timeout on the last step longer to give enough time to</span><br><span> ; make the choice to accept or not.</span><br><span style="color: hsl(120, 100%, 40%);">+enable_callee_prompt=>true</span><br><span style="color: hsl(120, 100%, 40%);">+; Enable prompting the callee to accept the forwarded call. The default</span><br><span style="color: hsl(120, 100%, 40%);">+; is the global value.</span><br><span> takecall=>1</span><br><span> ; The keypress for the callee to take taking the current call. This can be</span><br><span> ; a single digit or multiple digits. Default is the global default.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/14696">change 14696</a>. To unsubscribe, or for help writing mail filters, 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/c/asterisk/+/14696"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-Change-Id: Ic15a2bac4f16d0fce7a1b5e7b375f9bafee37aa4 </div>
<div style="display:none"> Gerrit-Change-Number: 14696 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Dennis <dennis.buteyn@xorcom.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Tzafrir Cohen <tzafrir.cohen@xorcom.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>