Sat Aug 6 00:39:21 2011

Asterisk developer's documentation


app_transfer.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Transfer a caller
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  * 
00025  * Requires transfer support from channel driver
00026  *
00027  * \ingroup applications
00028  */
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 40722 $")
00033 
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <unistd.h>
00038 
00039 #include "asterisk/lock.h"
00040 #include "asterisk/file.h"
00041 #include "asterisk/logger.h"
00042 #include "asterisk/channel.h"
00043 #include "asterisk/pbx.h"
00044 #include "asterisk/module.h"
00045 #include "asterisk/options.h"
00046 #include "asterisk/app.h"
00047 
00048 
00049 static const char *app = "Transfer";
00050 
00051 static const char *synopsis = "Transfer caller to remote extension";
00052 
00053 static const char *descrip = 
00054 "  Transfer([Tech/]dest[|options]):  Requests the remote caller be transferred\n"
00055 "to a given destination. If TECH (SIP, IAX2, LOCAL etc) is used, only\n"
00056 "an incoming call with the same channel technology will be transfered.\n"
00057 "Note that for SIP, if you transfer before call is setup, a 302 redirect\n"
00058 "SIP message will be returned to the caller.\n"
00059 "\nThe result of the application will be reported in the TRANSFERSTATUS\n"
00060 "channel variable:\n"
00061 "       SUCCESS      Transfer succeeded\n"
00062 "       FAILURE      Transfer failed\n"
00063 "       UNSUPPORTED  Transfer unsupported by channel driver\n"
00064 "The option string many contain the following character:\n"
00065 "'j' -- jump to n+101 priority if the channel transfer attempt\n"
00066 "       fails\n";
00067 
00068 static int transfer_exec(struct ast_channel *chan, void *data)
00069 {
00070    int res;
00071    int len;
00072    struct ast_module_user *u;
00073    char *slash;
00074    char *tech = NULL;
00075    char *dest = NULL;
00076    char *status;
00077    char *parse;
00078    int priority_jump = 0;
00079    AST_DECLARE_APP_ARGS(args,
00080       AST_APP_ARG(dest);
00081       AST_APP_ARG(options);
00082    );
00083 
00084    u = ast_module_user_add(chan);
00085 
00086    if (ast_strlen_zero((char *)data)) {
00087       ast_log(LOG_WARNING, "Transfer requires an argument ([Tech/]destination[|options])\n");
00088       ast_module_user_remove(u);
00089       pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
00090       return 0;
00091    } else
00092       parse = ast_strdupa(data);
00093 
00094    AST_STANDARD_APP_ARGS(args, parse);
00095 
00096    if (args.options) {
00097       if (strchr(args.options, 'j'))
00098          priority_jump = 1;
00099    }
00100 
00101    dest = args.dest;
00102 
00103    if ((slash = strchr(dest, '/')) && (len = (slash - dest))) {
00104       tech = dest;
00105       dest = slash + 1;
00106       /* Allow execution only if the Tech/destination agrees with the type of the channel */
00107       if (strncasecmp(chan->tech->type, tech, len)) {
00108          pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
00109          ast_module_user_remove(u);
00110          return 0;
00111       }
00112    }
00113 
00114    /* Check if the channel supports transfer before we try it */
00115    if (!chan->tech->transfer) {
00116       pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "UNSUPPORTED");
00117       ast_module_user_remove(u);
00118       return 0;
00119    }
00120 
00121    res = ast_transfer(chan, dest);
00122 
00123    if (res < 0) {
00124       status = "FAILURE";
00125       if (priority_jump || ast_opt_priority_jumping)
00126          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00127       res = 0;
00128    } else {
00129       status = "SUCCESS";
00130       res = 0;
00131    }
00132 
00133    pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", status);
00134 
00135    ast_module_user_remove(u);
00136 
00137    return res;
00138 }
00139 
00140 static int unload_module(void)
00141 {
00142    int res;
00143 
00144    res = ast_unregister_application(app);
00145 
00146    ast_module_user_hangup_all();
00147 
00148    return res; 
00149 }
00150 
00151 static int load_module(void)
00152 {
00153    return ast_register_application(app, transfer_exec, synopsis, descrip);
00154 }
00155 
00156 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Transfer");

Generated on Sat Aug 6 00:39:21 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7