Skip to content
Snippets Groups Projects
Commit 2aaffe48 authored by Matt O'Gorman's avatar Matt O'Gorman
Browse files

allow app_directed_pickup to try to pickup

multiple channels at the same time. however it
does not work in cases where dial was called
with multiple devices.  bug 5694.


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@8057 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 34ba77e7
No related branches found
No related tags found
No related merge requests found
...@@ -46,7 +46,7 @@ static const char *tdesc = "Directed Call Pickup Application"; ...@@ -46,7 +46,7 @@ static const char *tdesc = "Directed Call Pickup Application";
static const char *app = "Pickup"; static const char *app = "Pickup";
static const char *synopsis = "Directed Call Pickup"; static const char *synopsis = "Directed Call Pickup";
static const char *descrip = static const char *descrip =
" Pickup(extension[@context]): This application can pickup any ringing channel\n" " Pickup(extension[@context][&extension2@context...]): This application can pickup any ringing channel\n"
"that is calling the specified extension. If no context is specified, the current\n" "that is calling the specified extension. If no context is specified, the current\n"
"context will be used.\n"; "context will be used.\n";
...@@ -59,7 +59,7 @@ static int pickup_exec(struct ast_channel *chan, void *data) ...@@ -59,7 +59,7 @@ static int pickup_exec(struct ast_channel *chan, void *data)
int res = 0; int res = 0;
struct localuser *u = NULL; struct localuser *u = NULL;
struct ast_channel *origin = NULL, *target = NULL; struct ast_channel *origin = NULL, *target = NULL;
char *tmp = NULL, *exten = NULL, *context = NULL; char *tmp = NULL, *exten = NULL, *context = NULL, *rest=data;
char workspace[256] = ""; char workspace[256] = "";
if (ast_strlen_zero(data)) { if (ast_strlen_zero(data)) {
...@@ -69,64 +69,65 @@ static int pickup_exec(struct ast_channel *chan, void *data) ...@@ -69,64 +69,65 @@ static int pickup_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD(u); LOCAL_USER_ADD(u);
/* Get the extension and context if present */ while (!target && (exten = rest) ) {
exten = data; res = 0;
context = strchr(data, '@'); rest = strchr(exten, '&');
if (context) { if (rest)
*context = '\0'; *rest++ = 0;
context++;
} /* Get the extension and context if present */
context = strchr(exten, '@');
if (context)
*context++ = '\0';
/* 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_NOTICE, "No target channel found for %s.\n", exten);
res = -1;
}
ast_mutex_unlock(&origin->lock);
/* Find a channel to pickup */
origin = ast_get_channel_by_exten_locked(exten, context);
if (origin && origin->cdr) {
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 { } else {
ast_log(LOG_DEBUG, "No target channel found.\n"); ast_log(LOG_DEBUG, "No originating channel found.\n");
res = -1;
}
ast_mutex_unlock(&origin->lock);
} else {
if (origin)
ast_mutex_unlock(&origin->lock);
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) { if (res)
ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name); continue;
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;
break;
}
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;
break;
}
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;
break;
}
} else {
ast_log(LOG_NOTICE, "No call pickup possible for %s...\n", exten);
res = -1; res = -1;
goto out;
} }
} else {
ast_log(LOG_DEBUG, "No call pickup possible...\n");
res = -1;
} }
/* Done */
out:
if (target) if (target)
ast_mutex_unlock(&target->lock); ast_mutex_unlock(&target->lock);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment