mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-21 04:46:29 +00:00
Run predial routine on local;2 channel where you would expect.
Before this patch, the predial routine executes on the ;1 channel of a local channel pair. Executing predial on the ;1 channel of a local channel pair is of limited utility. Any channel variables set by the predial routine executing on the ;1 channel will not be available when the local channel executes dialplan on the ;2 channel. * Create ast_pre_call() and an associated pre_call() technology callback to handle running the predial routine. If a channel technology does not provide the callback, the predial routine is simply run on the channel. Review: https://reviewboard.asterisk.org/r/1903/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@366183 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -2478,7 +2478,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
|
|||||||
ast_autoservice_start(chan);
|
ast_autoservice_start(chan);
|
||||||
ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
|
ast_replace_subargument_delimiter(opt_args[OPT_ARG_PREDIAL_CALLEE]);
|
||||||
AST_LIST_TRAVERSE(&out_chans, tmp, node) {
|
AST_LIST_TRAVERSE(&out_chans, tmp, node) {
|
||||||
ast_app_exec_sub(NULL, tmp->chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
|
ast_pre_call(tmp->chan, opt_args[OPT_ARG_PREDIAL_CALLEE]);
|
||||||
}
|
}
|
||||||
ast_autoservice_stop(chan);
|
ast_autoservice_stop(chan);
|
||||||
}
|
}
|
||||||
|
@@ -95,6 +95,7 @@ static struct ast_jb_conf g_jb_conf = {
|
|||||||
static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
|
static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
|
||||||
static int local_digit_begin(struct ast_channel *ast, char digit);
|
static int local_digit_begin(struct ast_channel *ast, char digit);
|
||||||
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
|
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
|
||||||
|
static int local_pre_call(struct ast_channel *ast, const char *sub_args);
|
||||||
static int local_call(struct ast_channel *ast, const char *dest, int timeout);
|
static int local_call(struct ast_channel *ast, const char *dest, int timeout);
|
||||||
static int local_hangup(struct ast_channel *ast);
|
static int local_hangup(struct ast_channel *ast);
|
||||||
static int local_answer(struct ast_channel *ast);
|
static int local_answer(struct ast_channel *ast);
|
||||||
@@ -116,6 +117,7 @@ static struct ast_channel_tech local_tech = {
|
|||||||
.requester = local_request,
|
.requester = local_request,
|
||||||
.send_digit_begin = local_digit_begin,
|
.send_digit_begin = local_digit_begin,
|
||||||
.send_digit_end = local_digit_end,
|
.send_digit_end = local_digit_end,
|
||||||
|
.pre_call = local_pre_call,
|
||||||
.call = local_call,
|
.call = local_call,
|
||||||
.hangup = local_hangup,
|
.hangup = local_hangup,
|
||||||
.answer = local_answer,
|
.answer = local_answer,
|
||||||
@@ -1257,6 +1259,34 @@ static struct ast_channel *local_request(const char *type, struct ast_format_cap
|
|||||||
return chan;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int local_pre_call(struct ast_channel *ast, const char *sub_args)
|
||||||
|
{
|
||||||
|
struct local_pvt *p = ast_channel_tech_pvt(ast);
|
||||||
|
struct ast_channel *chan;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
ao2_lock(p);
|
||||||
|
chan = p->chan;
|
||||||
|
if (chan) {
|
||||||
|
ast_channel_ref(chan);
|
||||||
|
}
|
||||||
|
ao2_unlock(p);
|
||||||
|
if (!chan) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute the predial routine on the ;2 channel so any channel
|
||||||
|
* variables set by the predial will be available to the local
|
||||||
|
* channel PBX.
|
||||||
|
*/
|
||||||
|
ast_channel_unlock(ast);
|
||||||
|
res = ast_app_exec_sub(NULL, chan, sub_args);
|
||||||
|
ast_channel_unref(chan);
|
||||||
|
ast_channel_lock(ast);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief CLI command "local show channels" */
|
/*! \brief CLI command "local show channels" */
|
||||||
static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||||
{
|
{
|
||||||
|
@@ -676,6 +676,20 @@ struct ast_channel_tech {
|
|||||||
* parameters as a parameter.
|
* parameters as a parameter.
|
||||||
*/
|
*/
|
||||||
int (* cc_callback)(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
|
int (* cc_callback)(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Execute a Gosub call on the channel in a technology specific way before a call is placed.
|
||||||
|
* \since 11.0
|
||||||
|
*
|
||||||
|
* \param chan Channel to execute Gosub in a tech specific way.
|
||||||
|
* \param sub_args Gosub application parameter string.
|
||||||
|
*
|
||||||
|
* \note The chan is locked before calling.
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
|
int (*pre_call)(struct ast_channel *chan, const char *sub_args);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Kill the channel channel driver technology descriptor. */
|
/*! Kill the channel channel driver technology descriptor. */
|
||||||
@@ -1526,6 +1540,24 @@ int ast_raw_answer(struct ast_channel *chan, int cdr_answer);
|
|||||||
*/
|
*/
|
||||||
int __ast_answer(struct ast_channel *chan, unsigned int delay, int cdr_answer);
|
int __ast_answer(struct ast_channel *chan, unsigned int delay, int cdr_answer);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Execute a Gosub call on the channel before a call is placed.
|
||||||
|
* \since 11.0
|
||||||
|
*
|
||||||
|
* \details
|
||||||
|
* This is called between ast_request() and ast_call() to
|
||||||
|
* execute a predial routine on the newly created channel.
|
||||||
|
*
|
||||||
|
* \param chan Channel to execute Gosub.
|
||||||
|
* \param sub_args Gosub application parameter string.
|
||||||
|
*
|
||||||
|
* \note Absolutely _NO_ channel locks should be held before calling this function.
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
|
int ast_pre_call(struct ast_channel *chan, const char *sub_args);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Make a call
|
* \brief Make a call
|
||||||
* \note Absolutely _NO_ channel locks should be held before calling this function.
|
* \note Absolutely _NO_ channel locks should be held before calling this function.
|
||||||
|
@@ -5671,6 +5671,23 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
|
||||||
|
{
|
||||||
|
int (*pre_call)(struct ast_channel *chan, const char *sub_args);
|
||||||
|
|
||||||
|
ast_channel_lock(chan);
|
||||||
|
pre_call = ast_channel_tech(chan)->pre_call;
|
||||||
|
if (pre_call) {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = pre_call(chan, sub_args);
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
return ast_app_exec_sub(NULL, chan, sub_args);
|
||||||
|
}
|
||||||
|
|
||||||
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
|
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
|
||||||
{
|
{
|
||||||
/* Place an outgoing call, but don't wait any longer than timeout ms before returning.
|
/* Place an outgoing call, but don't wait any longer than timeout ms before returning.
|
||||||
|
Reference in New Issue
Block a user