Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:49 2009

## 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  * 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 }