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 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <unistd.h>
00030
00031 #include "asterisk.h"
00032
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 17905 $")
00034
00035 #include "asterisk/file.h"
00036 #include "asterisk/logger.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/module.h"
00040 #include "asterisk/lock.h"
00041 #include "asterisk/app.h"
00042
00043 static const char *tdesc = "Directed Call Pickup Application";
00044 static const char *app = "Pickup";
00045 static const char *synopsis = "Directed Call Pickup";
00046 static const char *descrip =
00047 " Pickup(extension[@context]): This application can pickup any ringing channel\n"
00048 "that is calling the specified extension. If no context is specified, the current\n"
00049 "context will be used.\n";
00050
00051 STANDARD_LOCAL_USER;
00052
00053 LOCAL_USER_DECL;
00054
00055 static int pickup_exec(struct ast_channel *chan, void *data)
00056 {
00057 int res = 0;
00058 struct localuser *u = NULL;
00059 struct ast_channel *origin = NULL, *target = NULL;
00060 char *tmp = NULL, *exten = NULL, *context = NULL;
00061 char workspace[256] = "";
00062
00063 if (ast_strlen_zero(data)) {
00064 ast_log(LOG_WARNING, "Pickup requires an argument (extension) !\n");
00065 return -1;
00066 }
00067
00068 LOCAL_USER_ADD(u);
00069
00070
00071 exten = data;
00072 context = strchr(data, '@');
00073 if (context) {
00074 *context = '\0';
00075 context++;
00076 }
00077
00078
00079 origin = ast_get_channel_by_exten_locked(exten, context);
00080 if (origin && origin->cdr) {
00081 ast_cdr_getvar(origin->cdr, "dstchannel", &tmp, workspace,
00082 sizeof(workspace), 0);
00083 if (tmp) {
00084
00085 target = ast_get_channel_by_name_locked(tmp);
00086 } else {
00087 ast_log(LOG_DEBUG, "No target channel found.\n");
00088 res = -1;
00089 }
00090 ast_mutex_unlock(&origin->lock);
00091 } else {
00092 if (origin)
00093 ast_mutex_unlock(&origin->lock);
00094 ast_log(LOG_DEBUG, "No originating channel found.\n");
00095 }
00096
00097 if (res)
00098 goto out;
00099
00100 if (target && (!target->pbx) && ((target->_state == AST_STATE_RINGING) || (target->_state == AST_STATE_RING))) {
00101 ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n", target->name,
00102 chan->name);
00103 res = ast_answer(chan);
00104 if (res) {
00105 ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
00106 res = -1;
00107 goto out;
00108 }
00109 res = ast_queue_control(chan, AST_CONTROL_ANSWER);
00110 if (res) {
00111 ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n",
00112 chan->name);
00113 res = -1;
00114 goto out;
00115 }
00116 res = ast_channel_masquerade(target, chan);
00117 if (res) {
00118 ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
00119 res = -1;
00120 goto out;
00121 }
00122 } else {
00123 ast_log(LOG_DEBUG, "No call pickup possible...\n");
00124 res = -1;
00125 }
00126
00127 out:
00128 if (target)
00129 ast_mutex_unlock(&target->lock);
00130
00131 LOCAL_USER_REMOVE(u);
00132
00133 return res;
00134 }
00135
00136 int unload_module(void)
00137 {
00138 int res;
00139
00140 res = ast_unregister_application(app);
00141
00142 STANDARD_HANGUP_LOCALUSERS;
00143
00144 return res;
00145 }
00146
00147 int load_module(void)
00148 {
00149 return ast_register_application(app, pickup_exec, synopsis, descrip);
00150 }
00151
00152 char *description(void)
00153 {
00154 return (char *) tdesc;
00155 }
00156
00157 int usecount(void)
00158 {
00159 int res;
00160
00161 STANDARD_USECOUNT(res);
00162
00163 return res;
00164 }
00165
00166 char *key()
00167 {
00168 return ASTERISK_GPL_KEY;
00169 }