Adds support for a core attended transfer function plus adds some hiding of masquerades.

The attended transfer API call can complete the attended transfer in a number of ways
depending on the current bridged states of the channels involved.

The hiding of masquerades is done in some bridging-related functions, such as the manager
Bridge action and the Bridge dialplan application. In addition, call pickup was edited
to "move" a channel rather than masquerade it.

Review: https://reviewboard.asterisk.org/r/2511

(closes issue ASTERISK-21334)
Reported by Matt Jordan

(closes issue Asterisk-21336)
Reported by Matt Jordan



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389848 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Michelson
2013-05-28 14:45:31 +00:00
parent 2d2a47fae3
commit fac3839e68
11 changed files with 1015 additions and 449 deletions

View File

@@ -11261,3 +11261,58 @@ struct ast_bridge_channel *ast_channel_get_bridge_channel(struct ast_channel *ch
}
return bridge_channel;
}
struct ast_channel *ast_channel_yank(struct ast_channel *yankee)
{
struct ast_channel *yanked_chan;
struct {
char *accountcode;
char *exten;
char *context;
char *linkedid;
char *name;
int amaflags;
struct ast_format readformat;
struct ast_format writeformat;
} my_vars = { 0, };
ast_channel_lock(yankee);
my_vars.accountcode = ast_strdupa(ast_channel_accountcode(yankee));
my_vars.exten = ast_strdupa(ast_channel_exten(yankee));
my_vars.context = ast_strdupa(ast_channel_context(yankee));
my_vars.linkedid = ast_strdupa(ast_channel_linkedid(yankee));
my_vars.name = ast_strdupa(ast_channel_name(yankee));
my_vars.amaflags = ast_channel_amaflags(yankee);
ast_format_copy(&my_vars.writeformat, ast_channel_writeformat(yankee));
ast_format_copy(&my_vars.readformat, ast_channel_readformat(yankee));
ast_channel_unlock(yankee);
/* Do not hold any channel locks while calling channel_alloc() since the function
* locks the channel container when linking the new channel in. */
if (!(yanked_chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, my_vars.accountcode,
my_vars.exten, my_vars.context, my_vars.linkedid, my_vars.amaflags,
"Surrogate/%s", my_vars.name))) {
return NULL;
}
/* Make formats okay */
ast_format_copy(ast_channel_readformat(yanked_chan), &my_vars.readformat);
ast_format_copy(ast_channel_writeformat(yanked_chan), &my_vars.writeformat);
if (ast_channel_move(yanked_chan, yankee)) {
ast_hangup(yanked_chan);
return NULL;
}
return yanked_chan;
}
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
{
if (ast_channel_masquerade(dest, source)) {
return -1;
}
ast_do_masquerade(dest);
return 0;
}