Mon Mar 20 08:25:37 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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  * Requires transfer support from channel driver
00024  *
00025  * \ingroup applications
00026  */
00027 
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 
00033 #include "asterisk.h"
00034 
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00036 
00037 #include "asterisk/lock.h"
00038 #include "asterisk/file.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/channel.h"
00041 #include "asterisk/pbx.h"
00042 #include "asterisk/module.h"
00043 #include "asterisk/options.h"
00044 #include "asterisk/app.h"
00045 
00046 STANDARD_LOCAL_USER;
00047 
00048 LOCAL_USER_DECL;
00049 
00050 static const char *tdesc = "Transfer";
00051 
00052 static const char *app = "Transfer";
00053 
00054 static const char *synopsis = "Transfer caller to remote extension";
00055 
00056 static const char *descrip = 
00057 "  Transfer([Tech/]dest[|options]):  Requests the remote caller be transferred\n"
00058 "to a given destination. If TECH (SIP, IAX2, LOCAL etc) is used, only\n"
00059 "an incoming call with the same channel technology will be transfered.\n"
00060 "Note that for SIP, if you transfer before call is setup, a 302 redirect\n"
00061 "SIP message will be returned to the caller.\n"
00062 "\nThe result of the application will be reported in the TRANSFERSTATUS\n"
00063 "channel variable:\n"
00064 "       SUCCESS      Transfer succeeded\n"
00065 "       FAILURE      Transfer failed\n"
00066 "       UNSUPPORTED  Transfer unsupported by channel driver\n"
00067 "The option string many contain the following character:\n"
00068 "'j' -- jump to n+101 priority if the channel transfer attempt\n"
00069 "       fails\n";
00070 
00071 static int transfer_exec(struct ast_channel *chan, void *data)
00072 {
00073    int res;
00074    int len;
00075    struct localuser *u;
00076    char *slash;
00077    char *tech = NULL;
00078    char *dest = NULL;
00079    char *status;
00080    char *parse;
00081    int priority_jump = 0;
00082    AST_DECLARE_APP_ARGS(args,
00083       AST_APP_ARG(dest);
00084       AST_APP_ARG(options);
00085    );
00086 
00087    LOCAL_USER_ADD(u);
00088 
00089    if (ast_strlen_zero((char *)data)) {
00090       ast_log(LOG_WARNING, "Transfer requires an argument ([Tech/]destination[|options])\n");
00091       LOCAL_USER_REMOVE(u);
00092       pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
00093       return 0;
00094    } else {
00095       parse = ast_strdupa(data);
00096       if (!parse) {
00097          ast_log(LOG_ERROR, "Out of memory!\n");
00098          LOCAL_USER_REMOVE(u);
00099          return -1;
00100       }
00101    }
00102 
00103    AST_STANDARD_APP_ARGS(args, parse);
00104 
00105    if (args.options) {
00106       if (strchr(args.options, 'j'))
00107          priority_jump = 1;
00108    }
00109 
00110    dest = args.dest;
00111 
00112    if ((slash = strchr(dest, '/')) && (len = (slash - dest))) {
00113       tech = dest;
00114       dest = slash + 1;
00115       /* Allow execution only if the Tech/destination agrees with the type of the channel */
00116       if (strncasecmp(chan->type, tech, len)) {
00117          pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "FAILURE");
00118          LOCAL_USER_REMOVE(u);
00119          return 0;
00120       }
00121    }
00122 
00123    /* Check if the channel supports transfer before we try it */
00124    if (!chan->tech->transfer) {
00125       pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", "UNSUPPORTED");
00126       LOCAL_USER_REMOVE(u);
00127       return 0;
00128    }
00129 
00130    res = ast_transfer(chan, dest);
00131 
00132    if (res < 0) {
00133       status = "FAILURE";
00134       if (priority_jump || option_priority_jumping)
00135          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00136       res = 0;
00137    } else {
00138       status = "SUCCESS";
00139       res = 0;
00140    }
00141 
00142    pbx_builtin_setvar_helper(chan, "TRANSFERSTATUS", status);
00143 
00144    LOCAL_USER_REMOVE(u);
00145 
00146    return res;
00147 }
00148 
00149 int unload_module(void)
00150 {
00151    int res;
00152 
00153    res = ast_unregister_application(app);
00154 
00155    STANDARD_HANGUP_LOCALUSERS;
00156 
00157    return res; 
00158 }
00159 
00160 int load_module(void)
00161 {
00162    return ast_register_application(app, transfer_exec, synopsis, descrip);
00163 }
00164 
00165 char *description(void)
00166 {
00167    return (char *) tdesc;
00168 }
00169 
00170 int usecount(void)
00171 {
00172    int res;
00173 
00174    STANDARD_USECOUNT(res);
00175 
00176    return res;
00177 }
00178 
00179 char *key()
00180 {
00181    return ASTERISK_GPL_KEY;
00182 }

Generated on Mon Mar 20 08:25:37 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1