mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-19 03:08:45 +00:00
add Pickup() application (issue #4865)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6622 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -28,7 +28,7 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\
|
|||||||
app_test.so app_forkcdr.so app_math.so app_realtime.so \
|
app_test.so app_forkcdr.so app_math.so app_realtime.so \
|
||||||
app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \
|
app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \
|
||||||
app_md5.so app_readfile.so app_chanspy.so app_settransfercapability.so \
|
app_md5.so app_readfile.so app_chanspy.so app_settransfercapability.so \
|
||||||
app_dictate.so app_externalivr.so
|
app_dictate.so app_externalivr.so app_directed_pickup.so
|
||||||
|
|
||||||
#
|
#
|
||||||
# Obsolete things...
|
# Obsolete things...
|
||||||
|
160
apps/app_directed_pickup.c
Executable file
160
apps/app_directed_pickup.c
Executable file
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* Asterisk -- An open source telephony toolkit.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005, Joshua Colp
|
||||||
|
*
|
||||||
|
* Joshua Colp <jcolp@asterlink.com>
|
||||||
|
*
|
||||||
|
* See http://www.asterisk.org for more information about
|
||||||
|
* the Asterisk project. Please do not directly contact
|
||||||
|
* any of the maintainers of this project for assistance;
|
||||||
|
* the project provides a web site, mailing lists and IRC
|
||||||
|
* channels for your use.
|
||||||
|
*
|
||||||
|
* This program is free software, distributed under the terms of
|
||||||
|
* the GNU General Public License Version 2. See the LICENSE file
|
||||||
|
* at the top of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Directed Call Pickup Support
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "asterisk.h"
|
||||||
|
|
||||||
|
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||||
|
|
||||||
|
#include "asterisk/file.h"
|
||||||
|
#include "asterisk/logger.h"
|
||||||
|
#include "asterisk/channel.h"
|
||||||
|
#include "asterisk/pbx.h"
|
||||||
|
#include "asterisk/module.h"
|
||||||
|
#include "asterisk/lock.h"
|
||||||
|
#include "asterisk/app.h"
|
||||||
|
|
||||||
|
static const char *tdesc = "Directed Call Pickup Application";
|
||||||
|
static const char *app = "Pickup";
|
||||||
|
static const char *synopsis = "Directed Call Pickup application.";
|
||||||
|
static const char *descrip =
|
||||||
|
" Pickup(extension@context):\n"
|
||||||
|
"Steals any calls to a specified extension that are in a ringing state and bridges them to the current channel. Context is an optional argument.\n";
|
||||||
|
|
||||||
|
STANDARD_LOCAL_USER;
|
||||||
|
|
||||||
|
LOCAL_USER_DECL;
|
||||||
|
|
||||||
|
static int pickup_exec(struct ast_channel *chan, void *data)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
struct localuser *u = NULL;
|
||||||
|
struct ast_channel *origin = NULL, *target = NULL;
|
||||||
|
char *tmp = NULL, *exten = NULL, *context = NULL;
|
||||||
|
char workspace[256] = "";
|
||||||
|
|
||||||
|
/* Get the extension and context if present */
|
||||||
|
exten = data;
|
||||||
|
context = strchr(data, '@');
|
||||||
|
if (context) {
|
||||||
|
*context = '\0';
|
||||||
|
context++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we atleast have an extension to work with */
|
||||||
|
if (!exten) {
|
||||||
|
ast_log(LOG_WARNING, "%s requires atleast one argument (extension)\n", app);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCAL_USER_ADD(u);
|
||||||
|
|
||||||
|
/* Find a channel to pickup */
|
||||||
|
origin = ast_get_channel_by_exten_locked(exten, context);
|
||||||
|
if (origin) {
|
||||||
|
ast_cdr_getvar(origin->cdr, "dstchannel", &tmp, workspace,
|
||||||
|
sizeof(workspace), 0);
|
||||||
|
if (tmp) {
|
||||||
|
/* We have a possible channel... now we need to find it! */
|
||||||
|
target = ast_get_channel_by_name_locked(tmp);
|
||||||
|
} else {
|
||||||
|
ast_log(LOG_DEBUG, "No target channel found.\n");
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&origin->lock);
|
||||||
|
} else {
|
||||||
|
ast_log(LOG_DEBUG, "No originating channel found.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (target && (!target->pbx) && ((target->_state == AST_STATE_RINGING) || (target->_state == AST_STATE_RING))) {
|
||||||
|
ast_log(LOG_DEBUG, "Call pickup on chan '%s' by '%s'\n", target->name,
|
||||||
|
chan->name);
|
||||||
|
res = ast_answer(chan);
|
||||||
|
if (res) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
|
||||||
|
res = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
res = ast_queue_control(chan, AST_CONTROL_ANSWER);
|
||||||
|
if (res) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n",
|
||||||
|
chan->name);
|
||||||
|
res = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
res = ast_channel_masquerade(target, chan);
|
||||||
|
if (res) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
|
||||||
|
res = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* Done */
|
||||||
|
ast_mutex_unlock(&target->lock);
|
||||||
|
} else {
|
||||||
|
ast_log(LOG_DEBUG, "No call pickup possible...\n");
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
LOCAL_USER_REMOVE(u);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unload_module(void)
|
||||||
|
{
|
||||||
|
STANDARD_HANGUP_LOCALUSERS;
|
||||||
|
|
||||||
|
return ast_unregister_application(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_module(void)
|
||||||
|
{
|
||||||
|
return ast_register_application(app, pickup_exec, synopsis, descrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *description(void)
|
||||||
|
{
|
||||||
|
return (char *) tdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usecount(void)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
STANDARD_USECOUNT(res);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key()
|
||||||
|
{
|
||||||
|
return ASTERISK_GPL_KEY;
|
||||||
|
}
|
Reference in New Issue
Block a user