00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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 }