mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-06 21:09:47 +00:00
app_page: Add predial handlers for app_page.
(closes issue AFS-14) Review: https://reviewboard.asterisk.org/r/3045/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
10
CHANGES
10
CHANGES
@@ -12,6 +12,9 @@
|
|||||||
--- Functionality changes from Asterisk 12 to Asterisk 13 --------------------
|
--- Functionality changes from Asterisk 12 to Asterisk 13 --------------------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Applications
|
||||||
|
--------------------------
|
||||||
|
|
||||||
ConfBridge
|
ConfBridge
|
||||||
--------------------------
|
--------------------------
|
||||||
* CONFBRIDGE dialplan function is now capable of creating/modifying dynamic
|
* CONFBRIDGE dialplan function is now capable of creating/modifying dynamic
|
||||||
@@ -42,9 +45,14 @@ Directory
|
|||||||
USEREXIT user pressed '#' from the selection prompt to exit
|
USEREXIT user pressed '#' from the selection prompt to exit
|
||||||
FAILED directory failed in a way that wasn't accounted for. Dang.
|
FAILED directory failed in a way that wasn't accounted for. Dang.
|
||||||
|
|
||||||
|
Page
|
||||||
|
--------------------------
|
||||||
|
* Added options 'b' and 'B' to apply predial handlers for outgoing calls
|
||||||
|
and for the channel executing Page respectively.
|
||||||
|
|
||||||
PickupChan
|
PickupChan
|
||||||
--------------------------
|
--------------------------
|
||||||
* PickupChan now accepts channel uniqueids of channels to pickup.
|
* PickupChan now accepts channel uniqueids of channels to pickup.
|
||||||
|
|
||||||
Say
|
Say
|
||||||
--------------------------
|
--------------------------
|
||||||
|
@@ -65,6 +65,27 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="options">
|
<parameter name="options">
|
||||||
<optionlist>
|
<optionlist>
|
||||||
|
<option name="b" argsep="^">
|
||||||
|
<para>Before initiating an outgoing call, Gosub to the specified
|
||||||
|
location using the newly created channel. The Gosub will be
|
||||||
|
executed for each destination channel.</para>
|
||||||
|
<argument name="context" required="false" />
|
||||||
|
<argument name="exten" required="false" />
|
||||||
|
<argument name="priority" required="true" hasparams="optional" argsep="^">
|
||||||
|
<argument name="arg1" multiple="true" required="true" />
|
||||||
|
<argument name="argN" />
|
||||||
|
</argument>
|
||||||
|
</option>
|
||||||
|
<option name="B" argsep="^">
|
||||||
|
<para>Before initiating the outgoing call(s), Gosub to the specified
|
||||||
|
location using the current channel.</para>
|
||||||
|
<argument name="context" required="false" />
|
||||||
|
<argument name="exten" required="false" />
|
||||||
|
<argument name="priority" required="true" hasparams="optional" argsep="^">
|
||||||
|
<argument name="arg1" multiple="true" required="true" />
|
||||||
|
<argument name="argN" />
|
||||||
|
</argument>
|
||||||
|
</option>
|
||||||
<option name="d">
|
<option name="d">
|
||||||
<para>Full duplex audio</para>
|
<para>Full duplex audio</para>
|
||||||
</option>
|
</option>
|
||||||
@@ -118,14 +139,20 @@ enum page_opt_flags {
|
|||||||
PAGE_IGNORE_FORWARDS = (1 << 4),
|
PAGE_IGNORE_FORWARDS = (1 << 4),
|
||||||
PAGE_ANNOUNCE = (1 << 5),
|
PAGE_ANNOUNCE = (1 << 5),
|
||||||
PAGE_NOCALLERANNOUNCE = (1 << 6),
|
PAGE_NOCALLERANNOUNCE = (1 << 6),
|
||||||
|
PAGE_PREDIAL_CALLEE = (1 << 7),
|
||||||
|
PAGE_PREDIAL_CALLER = (1 << 8),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_ARG_ANNOUNCE = 0,
|
OPT_ARG_ANNOUNCE = 0,
|
||||||
OPT_ARG_ARRAY_SIZE = 1,
|
OPT_ARG_PREDIAL_CALLEE = 1,
|
||||||
|
OPT_ARG_PREDIAL_CALLER = 2,
|
||||||
|
OPT_ARG_ARRAY_SIZE = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
AST_APP_OPTIONS(page_opts, {
|
AST_APP_OPTIONS(page_opts, {
|
||||||
|
AST_APP_OPTION_ARG('b', PAGE_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLEE),
|
||||||
|
AST_APP_OPTION_ARG('B', PAGE_PREDIAL_CALLER, OPT_ARG_PREDIAL_CALLER),
|
||||||
AST_APP_OPTION('d', PAGE_DUPLEX),
|
AST_APP_OPTION('d', PAGE_DUPLEX),
|
||||||
AST_APP_OPTION('q', PAGE_QUIET),
|
AST_APP_OPTION('q', PAGE_QUIET),
|
||||||
AST_APP_OPTION('r', PAGE_RECORD),
|
AST_APP_OPTION('r', PAGE_RECORD),
|
||||||
@@ -283,6 +310,12 @@ static int page_exec(struct ast_channel *chan, const char *data)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLER)
|
||||||
|
&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLER])) {
|
||||||
|
ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLER]);
|
||||||
|
ast_app_exec_sub(NULL, chan, options.opts[OPT_ARG_PREDIAL_CALLER], 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Go through parsing/calling each device */
|
/* Go through parsing/calling each device */
|
||||||
while ((tech = strsep(&args.devices, "&"))) {
|
while ((tech = strsep(&args.devices, "&"))) {
|
||||||
int state = 0;
|
int state = 0;
|
||||||
@@ -327,6 +360,11 @@ static int page_exec(struct ast_channel *chan, const char *data)
|
|||||||
/* Set ANSWER_EXEC as global option */
|
/* Set ANSWER_EXEC as global option */
|
||||||
ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, confbridgeopts);
|
ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, confbridgeopts);
|
||||||
|
|
||||||
|
if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE)
|
||||||
|
&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) {
|
||||||
|
ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, options.opts[OPT_ARG_PREDIAL_CALLEE]);
|
||||||
|
}
|
||||||
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
ast_dial_set_global_timeout(dial, timeout * 1000);
|
ast_dial_set_global_timeout(dial, timeout * 1000);
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,7 @@ enum ast_dial_option {
|
|||||||
AST_DIAL_OPTION_ANSWER_EXEC, /*!< Execute application upon answer in async mode */
|
AST_DIAL_OPTION_ANSWER_EXEC, /*!< Execute application upon answer in async mode */
|
||||||
AST_DIAL_OPTION_MUSIC, /*!< Play music on hold instead of ringing to the calling channel */
|
AST_DIAL_OPTION_MUSIC, /*!< Play music on hold instead of ringing to the calling channel */
|
||||||
AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, /*!< Disable call forwarding on channels */
|
AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, /*!< Disable call forwarding on channels */
|
||||||
|
AST_DIAL_OPTION_PREDIAL, /*!< Execute a predial subroutine before dialing */
|
||||||
AST_DIAL_OPTION_MAX, /*!< End terminator -- must always remain last */
|
AST_DIAL_OPTION_MAX, /*!< End terminator -- must always remain last */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
55
main/dial.c
55
main/dial.c
@@ -145,6 +145,22 @@ static int music_disable(void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *predial_enable(void *data)
|
||||||
|
{
|
||||||
|
return ast_strdup(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int predial_disable(void *data)
|
||||||
|
{
|
||||||
|
if (!data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_free(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Application execution function for 'ANSWER_EXEC' option */
|
/*! \brief Application execution function for 'ANSWER_EXEC' option */
|
||||||
static void answer_exec_run(struct ast_dial *dial, struct ast_dial_channel *dial_channel, char *app, char *args)
|
static void answer_exec_run(struct ast_dial *dial, struct ast_dial_channel *dial_channel, char *app, char *args)
|
||||||
{
|
{
|
||||||
@@ -186,6 +202,7 @@ static const struct ast_option_types option_types[] = {
|
|||||||
{ AST_DIAL_OPTION_ANSWER_EXEC, answer_exec_enable, answer_exec_disable }, /*!< Execute application upon answer in async mode */
|
{ AST_DIAL_OPTION_ANSWER_EXEC, answer_exec_enable, answer_exec_disable }, /*!< Execute application upon answer in async mode */
|
||||||
{ AST_DIAL_OPTION_MUSIC, music_enable, music_disable }, /*!< Play music to the caller instead of ringing */
|
{ AST_DIAL_OPTION_MUSIC, music_enable, music_disable }, /*!< Play music to the caller instead of ringing */
|
||||||
{ AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL, NULL }, /*!< Disable call forwarding on channels */
|
{ AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL, NULL }, /*!< Disable call forwarding on channels */
|
||||||
|
{ AST_DIAL_OPTION_PREDIAL, predial_enable, predial_disable }, /*!< Execute a subroutine on the outbound channels prior to dialing */
|
||||||
{ AST_DIAL_OPTION_MAX, NULL, NULL }, /*!< Terminator of list */
|
{ AST_DIAL_OPTION_MAX, NULL, NULL }, /*!< Terminator of list */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -259,7 +276,7 @@ int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Helper function that requests all channels */
|
/*! \brief Helper function that requests all channels */
|
||||||
static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channel *chan, struct ast_format_cap *cap)
|
static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channel *chan, struct ast_format_cap *cap, const char *predial_string)
|
||||||
{
|
{
|
||||||
char numsubst[AST_MAX_EXTENSION];
|
char numsubst[AST_MAX_EXTENSION];
|
||||||
struct ast_format_cap *cap_all_audio = NULL;
|
struct ast_format_cap *cap_all_audio = NULL;
|
||||||
@@ -316,6 +333,17 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
|
|||||||
|
|
||||||
ast_channel_stage_snapshot_done(channel->owner);
|
ast_channel_stage_snapshot_done(channel->owner);
|
||||||
|
|
||||||
|
if (!ast_strlen_zero(predial_string)) {
|
||||||
|
const char *predial_callee = ast_app_expand_sub_args(chan, predial_string);
|
||||||
|
if (!predial_callee) {
|
||||||
|
ast_log(LOG_ERROR, "Could not expand subroutine arguments in predial request '%s'\n", predial_string);
|
||||||
|
}
|
||||||
|
ast_autoservice_start(chan);
|
||||||
|
ast_pre_call(channel->owner, predial_callee);
|
||||||
|
ast_autoservice_stop(chan);
|
||||||
|
ast_free((char *) predial_callee);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,10 +351,15 @@ int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_
|
|||||||
{
|
{
|
||||||
struct ast_dial_channel *channel;
|
struct ast_dial_channel *channel;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
|
||||||
|
|
||||||
|
if (!ast_strlen_zero(predial_string)) {
|
||||||
|
ast_replace_subargument_delimiter(predial_string);
|
||||||
|
}
|
||||||
|
|
||||||
AST_LIST_LOCK(&dial->channels);
|
AST_LIST_LOCK(&dial->channels);
|
||||||
AST_LIST_TRAVERSE(&dial->channels, channel, list) {
|
AST_LIST_TRAVERSE(&dial->channels, channel, list) {
|
||||||
if ((res = begin_dial_prerun(channel, chan, cap))) {
|
if ((res = begin_dial_prerun(channel, chan, cap, predial_string))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,13 +369,13 @@ int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Helper function that does the beginning dialing per-appended channel */
|
/*! \brief Helper function that does the beginning dialing per-appended channel */
|
||||||
static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan, int async)
|
static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan, int async, const char *predial_string)
|
||||||
{
|
{
|
||||||
char numsubst[AST_MAX_EXTENSION];
|
char numsubst[AST_MAX_EXTENSION];
|
||||||
int res = 1;
|
int res = 1;
|
||||||
|
|
||||||
/* If no owner channel exists yet execute pre-run */
|
/* If no owner channel exists yet execute pre-run */
|
||||||
if (!channel->owner && begin_dial_prerun(channel, chan, NULL)) {
|
if (!channel->owner && begin_dial_prerun(channel, chan, NULL, predial_string)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,11 +404,16 @@ static int begin_dial(struct ast_dial *dial, struct ast_channel *chan, int async
|
|||||||
{
|
{
|
||||||
struct ast_dial_channel *channel = NULL;
|
struct ast_dial_channel *channel = NULL;
|
||||||
int success = 0;
|
int success = 0;
|
||||||
|
char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
|
||||||
|
|
||||||
|
if (!ast_strlen_zero(predial_string)) {
|
||||||
|
ast_replace_subargument_delimiter(predial_string);
|
||||||
|
}
|
||||||
|
|
||||||
/* Iterate through channel list, requesting and calling each one */
|
/* Iterate through channel list, requesting and calling each one */
|
||||||
AST_LIST_LOCK(&dial->channels);
|
AST_LIST_LOCK(&dial->channels);
|
||||||
AST_LIST_TRAVERSE(&dial->channels, channel, list) {
|
AST_LIST_TRAVERSE(&dial->channels, channel, list) {
|
||||||
success += begin_dial_channel(channel, chan, async);
|
success += begin_dial_channel(channel, chan, async, predial_string);
|
||||||
}
|
}
|
||||||
AST_LIST_UNLOCK(&dial->channels);
|
AST_LIST_UNLOCK(&dial->channels);
|
||||||
|
|
||||||
@@ -389,6 +427,11 @@ static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *c
|
|||||||
struct ast_channel *original = channel->owner;
|
struct ast_channel *original = channel->owner;
|
||||||
char *tmp = ast_strdupa(ast_channel_call_forward(channel->owner));
|
char *tmp = ast_strdupa(ast_channel_call_forward(channel->owner));
|
||||||
char *tech = "Local", *device = tmp, *stuff;
|
char *tech = "Local", *device = tmp, *stuff;
|
||||||
|
char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
|
||||||
|
|
||||||
|
if (!ast_strlen_zero(predial_string)) {
|
||||||
|
ast_replace_subargument_delimiter(predial_string);
|
||||||
|
}
|
||||||
|
|
||||||
/* If call forwarding is disabled just drop the original channel and don't attempt to dial the new one */
|
/* If call forwarding is disabled just drop the original channel and don't attempt to dial the new one */
|
||||||
if (FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING)) {
|
if (FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING)) {
|
||||||
@@ -428,7 +471,7 @@ static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *c
|
|||||||
channel->owner = NULL;
|
channel->owner = NULL;
|
||||||
|
|
||||||
/* Finally give it a go... send it out into the world */
|
/* Finally give it a go... send it out into the world */
|
||||||
begin_dial_channel(channel, chan, chan ? 0 : 1);
|
begin_dial_channel(channel, chan, chan ? 0 : 1, predial_string);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user