<p>Alexei Gradinari has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/11399">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_attended_transfer: new application AttendedTransfer<br><br>AttendedTransfer queues up attended transfer to the given extension.<br><br>This application can be useful with Custom Dynamic Features.<br>For example to make attended transfer to a predefined number.<br><br>features.conf<br>;;;<br>[applicationmap]<br>my_atxfer => *7,self,GoSub,"my_atxfer,s,1",default<br>;;;<br><br>extensions.conf<br>;;;<br>[globals]<br>DYNAMIC_FEATURES=my_atxfer<br>TRANSFER_CONTEXT=my_transfer<br><br>[my_atxfer]<br>exten => s,1,AttendedTransfer(1234567890)<br>   same => n,Return()<br><br>[my_transfer]<br>include => default<br>;;;<br><br>This application also can be used to completly redefine Attended transfer<br>feature using dialplan. For example:<br><br>features.conf<br>;;;<br>[featuremap]<br>atxfer => *7<br><br>[applicationmap]<br>custom_atxfer => *2,self,GoSub,"custom_atxfer,s,1",default<br>;;;<br><br>extensions.conf<br>;;;<br>[globals]<br>DYNAMIC_FEATURES=custom_atxfer<br>TRANSFER_CONTEXT=my_transfer<br><br>[custom_atxfer]<br>exten => s,1,<br>   same => n,Playback(pbx-transfer)<br>   same => n,Read(dest,dial,10,i,3,3)<br>   same => n,AttendedTransfer(${dest})<br>   same => n,Return()<br><br>[my_transfer]<br>include => default<br>;;;<br><br>Change-Id: Ie5cfa455d0813cffd5c85a6fb117f07d8f0b903b<br>---<br>A apps/app_attended_transfer.c<br>A doc/CHANGES-staging/app_attended_transfer.txt<br>M menuselect/example_menuselect-tree<br>M menuselect/test/menuselect-tree<br>4 files changed, 147 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/99/11399/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_attended_transfer.c b/apps/app_attended_transfer.c</span><br><span>new file mode 100644</span><br><span>index 0000000..ce8173e</span><br><span>--- /dev/null</span><br><span>+++ b/apps/app_attended_transfer.c</span><br><span>@@ -0,0 +1,140 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2019, Alexei Gradinari</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alexei Gradinari <alex2grad@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(120, 100%, 40%);">+ * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(120, 100%, 40%);">+ * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(120, 100%, 40%);">+ * channels for your use.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software, distributed under the terms of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(120, 100%, 40%);">+ * at the top of the source tree.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Attended transfer by caller channel</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \author Alexei Gradinari <alex2grad@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \ingroup applications</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** MODULEINFO</span><br><span style="color: hsl(120, 100%, 40%);">+   <support_level>extended</support_level></span><br><span style="color: hsl(120, 100%, 40%);">+ ***/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/pbx.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/module.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/app.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/channel.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/bridge.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/features_config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** DOCUMENTATION</span><br><span style="color: hsl(120, 100%, 40%);">+     <application name="AttendedTransfer" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+              <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                      Attended transfer to the extension provided and TRANSFER_CONTEXT</span><br><span style="color: hsl(120, 100%, 40%);">+              </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+             <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+                        <parameter name="exten" required="true"></span><br><span style="color: hsl(120, 100%, 40%);">+                            <para>Specify extension.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                   </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+            </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+               <description></span><br><span style="color: hsl(120, 100%, 40%);">+                   <para>Queue up attended transfer to the specified extension in the <literal>TRANSFER_CONTEXT</literal>.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                        <para>The result of the application will be reported in the <variable>ATTENDEDTRANSFERSTATUS</variable></span><br><span style="color: hsl(120, 100%, 40%);">+                     channel variable:</para></span><br><span style="color: hsl(120, 100%, 40%);">+                        <variablelist></span><br><span style="color: hsl(120, 100%, 40%);">+                          <variable name="ATTENDEDTRANSFERSTATUS"></span><br><span style="color: hsl(120, 100%, 40%);">+                                      <value name="SUCCESS"></span><br><span style="color: hsl(120, 100%, 40%);">+                                                Transfer successfully queued.</span><br><span style="color: hsl(120, 100%, 40%);">+                                 </value></span><br><span style="color: hsl(120, 100%, 40%);">+                                        <value name="FAILURE"></span><br><span style="color: hsl(120, 100%, 40%);">+                                                Transfer failed.</span><br><span style="color: hsl(120, 100%, 40%);">+                                      </value></span><br><span style="color: hsl(120, 100%, 40%);">+                                        <value name="NOTPERMITTED"></span><br><span style="color: hsl(120, 100%, 40%);">+                                           Transfer not permitted.</span><br><span style="color: hsl(120, 100%, 40%);">+                                       </value></span><br><span style="color: hsl(120, 100%, 40%);">+                                </variable></span><br><span style="color: hsl(120, 100%, 40%);">+                     </variablelist></span><br><span style="color: hsl(120, 100%, 40%);">+         </description></span><br><span style="color: hsl(120, 100%, 40%);">+  </application></span><br><span style="color: hsl(120, 100%, 40%);">+ ***/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char * const app = "AttendedTransfer";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int attended_transfer_exec(struct ast_channel *chan, const char *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      char *exten = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   const char *context = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   char *parse;</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_DECLARE_APP_ARGS(args,</span><br><span style="color: hsl(120, 100%, 40%);">+            AST_APP_ARG(exten);</span><br><span style="color: hsl(120, 100%, 40%);">+   );</span><br><span style="color: hsl(120, 100%, 40%);">+    char feature_code[AST_FEATURE_MAX_LEN];</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *digit;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct ast_frame f = { .frametype = AST_FRAME_DTMF };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ast_strlen_zero((char *)data)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_log(LOG_WARNING, "%s requires an argument (exten)\n", app);</span><br><span style="color: hsl(120, 100%, 40%);">+             pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "FAILURE");</span><br><span style="color: hsl(120, 100%, 40%);">+             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   context = pbx_builtin_getvar_helper(chan, "TRANSFER_CONTEXT");</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ast_strlen_zero(context)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "NOTPERMITTED");</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_channel_lock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) ||</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_strlen_zero(feature_code)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "NOTPERMITTED");</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   parse = ast_strdupa(data);</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_STANDARD_APP_ARGS(args, parse);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ exten = args.exten;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (digit = feature_code; *digit; ++digit) {</span><br><span style="color: hsl(120, 100%, 40%);">+         f.subclass.integer = *digit;</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_queue_frame(chan, &f);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   for (digit = exten; *digit; ++digit) {</span><br><span style="color: hsl(120, 100%, 40%);">+                f.subclass.integer = *digit;</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_queue_frame(chan, &f);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   f.subclass.integer = '#';</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_queue_frame(chan, &f);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "SUCCESS");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int unload_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return ast_unregister_application(app);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int load_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return ast_register_application_xml(app, attended_transfer_exec);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Attended transfer to the given extension");</span><br><span>diff --git a/doc/CHANGES-staging/app_attended_transfer.txt b/doc/CHANGES-staging/app_attended_transfer.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..97929e4</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/app_attended_transfer.txt</span><br><span>@@ -0,0 +1,3 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: AttendedTransfer</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+A new application, this will queue up attended transfer to the given extension.</span><br><span>diff --git a/menuselect/example_menuselect-tree b/menuselect/example_menuselect-tree</span><br><span>index 6901b70..e944d67 100644</span><br><span>--- a/menuselect/example_menuselect-tree</span><br><span>+++ b/menuselect/example_menuselect-tree</span><br><span>@@ -8,6 +8,8 @@</span><br><span>          </member></span><br><span>              <member name="app_amd" displayname="Answering Machine Detection Application" remove_on_change="apps/app_amd.o apps/app_amd.so"></span><br><span>          </member></span><br><span style="color: hsl(120, 100%, 40%);">+               <member name="app_attended_transfer" displayname="Attended transfer to the given extension" remove_on_change="apps/app_attended_transfer.o apps/app_attended_transfer.so"></span><br><span style="color: hsl(120, 100%, 40%);">+                </member></span><br><span>              <member name="app_authenticate" displayname="Authentication Application" remove_on_change="apps/app_authenticate.o apps/app_authenticate.so"></span><br><span>            </member></span><br><span>              <member name="app_cdr" displayname="Tell Asterisk to not maintain a CDR for the current call" remove_on_change="apps/app_cdr.o apps/app_cdr.so"></span><br><span>diff --git a/menuselect/test/menuselect-tree b/menuselect/test/menuselect-tree</span><br><span>index 40c08b6..a8267a8 100644</span><br><span>--- a/menuselect/test/menuselect-tree</span><br><span>+++ b/menuselect/test/menuselect-tree</span><br><span>@@ -9,6 +9,8 @@</span><br><span> </member></span><br><span> <member name="app_amd" displayname="Answering Machine Detection Application" remove_on_change="apps/app_amd.o apps/app_amd.so"></span><br><span> </member></span><br><span style="color: hsl(120, 100%, 40%);">+<member name="app_attended_transfer" displayname="Attended transfer to the given extension" remove_on_change="apps/app_attended_transfer.o apps/app_attended_transfer.so"></span><br><span style="color: hsl(120, 100%, 40%);">+</member></span><br><span> <member name="app_authenticate" displayname="Authentication Application" remove_on_change="apps/app_authenticate.o apps/app_authenticate.so"></span><br><span> </member></span><br><span> <member name="app_cdr" displayname="Tell Asterisk to not maintain a CDR for the current call" remove_on_change="apps/app_cdr.o apps/app_cdr.so"></span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/11399">change 11399</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/+/11399"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: Ie5cfa455d0813cffd5c85a6fb117f07d8f0b903b </div>
<div style="display:none"> Gerrit-Change-Number: 11399 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Alexei Gradinari <alex2grad@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>