From 3eaeb3e6c45122326e3ef4ea8bdc99d202a9fdd7 Mon Sep 17 00:00:00 2001 From: Alexei Gradinari Date: Tue, 21 May 2019 15:12:55 -0400 Subject: [PATCH] app_attended_transfer: new application AttendedTransfer AttendedTransfer queues up attended transfer to the given extension. This application can be useful with Custom Dynamic Features. For example to make attended transfer to a predefined number. features.conf ;;; [applicationmap] my_atxfer => *7,self,GoSub,"my_atxfer,s,1",default ;;; extensions.conf ;;; [globals] DYNAMIC_FEATURES=my_atxfer TRANSFER_CONTEXT=my_transfer [my_atxfer] exten => s,1,AttendedTransfer(1234567890) same => n,Return() [my_transfer] include => default ;;; This application also can be used to completly redefine Attended transfer feature using dialplan. For example: features.conf ;;; [featuremap] atxfer => *7 [applicationmap] custom_atxfer => *2,self,GoSub,"custom_atxfer,s,1",default ;;; extensions.conf ;;; [globals] DYNAMIC_FEATURES=custom_atxfer TRANSFER_CONTEXT=my_transfer [custom_atxfer] exten => s,1, same => n,Playback(pbx-transfer) same => n,Read(dest,dial,10,i,3,3) same => n,AttendedTransfer(${dest}) same => n,Return() [my_transfer] include => default ;;; Change-Id: Ie5cfa455d0813cffd5c85a6fb117f07d8f0b903b --- apps/app_attended_transfer.c | 143 ++++++++++++++++++ doc/CHANGES-staging/app_attended_transfer.txt | 3 + menuselect/example_menuselect-tree | 2 + menuselect/test/menuselect-tree | 2 + 4 files changed, 150 insertions(+) create mode 100644 apps/app_attended_transfer.c create mode 100644 doc/CHANGES-staging/app_attended_transfer.txt diff --git a/apps/app_attended_transfer.c b/apps/app_attended_transfer.c new file mode 100644 index 0000000000..df8d83cd9b --- /dev/null +++ b/apps/app_attended_transfer.c @@ -0,0 +1,143 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2019, Alexei Gradinari + * + * Alexei Gradinari + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Attended transfer by caller channel + * + * \author Alexei Gradinari + * + * \ingroup applications + */ + +/*** MODULEINFO + extended + ***/ + +#include "asterisk.h" + +#include "asterisk/pbx.h" +#include "asterisk/module.h" +#include "asterisk/app.h" +#include "asterisk/channel.h" +#include "asterisk/bridge.h" +#include "asterisk/features_config.h" + +/*** DOCUMENTATION + + + Attended transfer to the extension provided and TRANSFER_CONTEXT + + + + Specify extension. + + + + Queue up attended transfer to the specified extension in the TRANSFER_CONTEXT. + Note that the attended transfer only work when two channels have answered and are bridged together. + Make sure to set Attended Transfer DTMF feature atxfer + and attended transfer is permitted. + The result of the application will be reported in the ATTENDEDTRANSFERSTATUS + channel variable: + + + + Transfer successfully queued. + + + Transfer failed. + + + Transfer not permitted. + + + + + + ***/ + +static const char * const app = "AttendedTransfer"; + +static int attended_transfer_exec(struct ast_channel *chan, const char *data) +{ + char *exten = NULL; + const char *context = NULL; + char *parse; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(exten); + ); + char feature_code[AST_FEATURE_MAX_LEN]; + const char *digit; + struct ast_frame f = { .frametype = AST_FRAME_DTMF }; + + if (ast_strlen_zero((char *)data)) { + ast_log(LOG_WARNING, "%s requires an argument (exten)\n", app); + pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "FAILURE"); + return 0; + } + + context = pbx_builtin_getvar_helper(chan, "TRANSFER_CONTEXT"); + if (ast_strlen_zero(context)) { + pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "NOTPERMITTED"); + return 0; + } + + ast_channel_lock(chan); + if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) || + ast_strlen_zero(feature_code)) { + pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "NOTPERMITTED"); + ast_channel_unlock(chan); + return 0; + } + ast_channel_unlock(chan); + + parse = ast_strdupa(data); + AST_STANDARD_APP_ARGS(args, parse); + + exten = args.exten; + + for (digit = feature_code; *digit; ++digit) { + f.subclass.integer = *digit; + ast_queue_frame(chan, &f); + } + + for (digit = exten; *digit; ++digit) { + f.subclass.integer = *digit; + ast_queue_frame(chan, &f); + } + + f.subclass.integer = '#'; + ast_queue_frame(chan, &f); + + pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFERSTATUS", "SUCCESS"); + + return 0; +} + +static int unload_module(void) +{ + return ast_unregister_application(app); +} + +static int load_module(void) +{ + return ast_register_application_xml(app, attended_transfer_exec); +} + +AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Attended transfer to the given extension"); diff --git a/doc/CHANGES-staging/app_attended_transfer.txt b/doc/CHANGES-staging/app_attended_transfer.txt new file mode 100644 index 0000000000..97929e4b08 --- /dev/null +++ b/doc/CHANGES-staging/app_attended_transfer.txt @@ -0,0 +1,3 @@ +Subject: AttendedTransfer + +A new application, this will queue up attended transfer to the given extension. diff --git a/menuselect/example_menuselect-tree b/menuselect/example_menuselect-tree index 6901b709f4..e944d67da1 100644 --- a/menuselect/example_menuselect-tree +++ b/menuselect/example_menuselect-tree @@ -8,6 +8,8 @@ + + diff --git a/menuselect/test/menuselect-tree b/menuselect/test/menuselect-tree index 40c08b69f1..a8267a84e4 100644 --- a/menuselect/test/menuselect-tree +++ b/menuselect/test/menuselect-tree @@ -9,6 +9,8 @@ + +