Fri Sep 29 11:12:23 2006

Asterisk developer's documentation


app_directed_pickup.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2005, Joshua Colp
00005  *
00006  * Joshua Colp <jcolp@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 Directed Call Pickup Support
00022  *
00023  * \ingroup applications
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    /* Get the extension and context if present */
00071    exten = data;
00072    context = strchr(data, '@');
00073    if (context) {
00074       *context = '\0';
00075       context++;
00076    }
00077 
00078    /* Find a channel to pickup */
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          /* We have a possible channel... now we need to find it! */
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    /* Done */
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 }

Generated on Fri Sep 29 11:12:23 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7