Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:47 2009

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