app_macro: Remove deprecated module.

For most modules that interacted with app_macro, this change is limited
to no longer looking for the current context from the macrocontext when
set.  Additionally, the following modules are impacted:

app_dial - no longer supports M^ connected/redirecting macro
app_minivm - samples written using macro will no longer work.
The sample needs a re-write

app_queue - can no longer a macro on the called party's channel.
Use gosub which is currently supported

ccss - no callback macro, gosub only

app_voicemail - no macro support

channel  - remove macrocontext and priority, no connected line or
redirection macro options
options - stdexten is deprecated to gosub as the default and only
pbx - removed macrolock
pbx_dundi - no longer look for macro

snmp - removed macro context, exten, and priority

ASTERISK-30304

Change-Id: I830daab293117179b8d61bd4df0d971a1b3d07f6
This commit is contained in:
Mike Bradeen 2022-12-12 10:12:57 -07:00 committed by Friendly Automation
parent 6ecec51e6a
commit e8f548c155
52 changed files with 143 additions and 1615 deletions

View File

@ -5047,7 +5047,7 @@ struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
p->faxdetected = 1;
ooRequestChangeMode(p->callToken, 1);
} else if ((dfr->subclass.integer == 'f') && !p->faxdetected) {
const char *target_context = S_OR(ast_channel_macrocontext(p->owner), ast_channel_context(p->owner));
const char *target_context = ast_channel_context(p->owner);
if ((strcmp(ast_channel_exten(p->owner), "fax")) &&
(ast_exists_extension(p->owner, target_context, "fax", 1,
S_COR(ast_channel_caller(p->owner)->id.number.valid, ast_channel_caller(p->owner)->id.number.str, NULL)))) {
@ -5123,7 +5123,7 @@ void onModeChanged(ooCallData *call, int t38mode) {
if ((p->faxdetect & FAXDETECT_T38) && !p->faxdetected) {
const char *target_context;
ast_debug(1, "* Detected T.38 Request\n");
target_context = S_OR(ast_channel_macrocontext(p->owner), ast_channel_context(p->owner));
target_context = ast_channel_context(p->owner);
if ((strcmp(ast_channel_exten(p->owner), "fax")) &&
(ast_exists_extension(p->owner, target_context, "fax", 1,
S_COR(ast_channel_caller(p->owner)->id.number.valid, ast_channel_caller(p->owner)->id.number.str, NULL)))) {

View File

@ -907,8 +907,6 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
ast_channel_lock(chan);
if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT"))) {
ast_copy_string(exitcontext, c, sizeof(exitcontext));
} else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
ast_copy_string(exitcontext, ast_channel_macrocontext(chan), sizeof(exitcontext));
} else {
ast_copy_string(exitcontext, ast_channel_context(chan), sizeof(exitcontext));
}

View File

@ -208,7 +208,7 @@
and <emphasis>start</emphasis> execution at that location.</para>
<para>NOTE: Any channel variables you want the called channel to inherit from the caller channel must be
prefixed with one or two underbars ('_').</para>
<para>NOTE: Using this option from a Macro() or GoSub() might not make sense as there would be no return points.</para>
<para>NOTE: Using this option from a GoSub() might not make sense as there would be no return points.</para>
</option>
<option name="g">
<para>Proceed with dialplan execution at the next priority in the current extension if the
@ -297,47 +297,6 @@
channel answers. A specific music on hold <replaceable>class</replaceable>
(as defined in <filename>musiconhold.conf</filename>) can be specified.</para>
</option>
<option name="M" argsep="^">
<argument name="macro" required="true">
<para>Name of the macro that should be executed.</para>
</argument>
<argument name="arg" multiple="true">
<para>Macro arguments</para>
</argument>
<para>Execute the specified <replaceable>macro</replaceable> for the <emphasis>called</emphasis> channel
before connecting to the calling channel. Arguments can be specified to the Macro
using <literal>^</literal> as a delimiter. The macro can set the variable
<variable>MACRO_RESULT</variable> to specify the following actions after the macro is
finished executing:</para>
<variablelist>
<variable name="MACRO_RESULT">
<para>If set, this action will be taken after the macro finished executing.</para>
<value name="ABORT">
Hangup both legs of the call
</value>
<value name="CONGESTION">
Behave as if line congestion was encountered
</value>
<value name="BUSY">
Behave as if a busy signal was encountered
</value>
<value name="CONTINUE">
Hangup the called party and allow the calling party to continue dialplan execution at the next priority
</value>
<value name="GOTO:[[&lt;context&gt;^]&lt;exten&gt;^]&lt;priority&gt;">
Transfer the call to the specified destination.
</value>
</variable>
</variablelist>
<para>NOTE: You cannot use any additional action post answer options in conjunction
with this option. Also, pbx services are run on the peer (called) channel,
so you will not be able to set timeouts via the <literal>TIMEOUT()</literal> function in this macro.</para>
<para>WARNING: Be aware of the limitations that macros have, specifically with regards to use of
the <literal>WaitExten</literal> application. For more information, see the documentation for
<literal>Macro()</literal>.</para>
<para>NOTE: Macros are deprecated, GoSub should be used instead,
see the <literal>U</literal> option.</para>
</option>
<option name="n">
<argument name="delete">
<para>With <replaceable>delete</replaceable> either not specified or set to <literal>0</literal>,
@ -655,7 +614,6 @@
<ref type="application">RetryDial</ref>
<ref type="application">SendDTMF</ref>
<ref type="application">Gosub</ref>
<ref type="application">Macro</ref>
</see-also>
</application>
<application name="RetryDial" language="en_US">
@ -710,7 +668,6 @@ enum {
OPT_ORIGINAL_CLID = (1 << 8),
OPT_DURATION_LIMIT = (1 << 9),
OPT_MUSICBACK = (1 << 10),
OPT_CALLEE_MACRO = (1 << 11),
OPT_SCREEN_NOINTRO = (1 << 12),
OPT_SCREEN_NOCALLERID = (1 << 13),
OPT_IGNORE_CONNECTEDLINE = (1 << 14),
@ -755,7 +712,6 @@ enum {
OPT_ARG_GOTO,
OPT_ARG_DURATION_LIMIT,
OPT_ARG_MUSICBACK,
OPT_ARG_CALLEE_MACRO,
OPT_ARG_RINGBACK,
OPT_ARG_CALLEE_GOSUB,
OPT_ARG_CALLEE_GO_ON,
@ -797,7 +753,6 @@ AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
AST_APP_OPTION('K', OPT_CALLER_PARK),
AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
AST_APP_OPTION_ARG('n', OPT_SCREEN_NOINTRO, OPT_ARG_SCREEN_NOINTRO),
AST_APP_OPTION('N', OPT_SCREEN_NOCALLERID),
AST_APP_OPTION_ARG('o', OPT_ORIGINAL_CLID, OPT_ARG_ORIGINAL_CLID),
@ -823,7 +778,7 @@ END_OPTIONS );
#define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | \
OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB) && \
OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_GOSUB) && \
!ast_channel_audiohooks(chan) && !ast_channel_audiohooks(peer) && \
ast_framehook_list_is_empty(ast_channel_framehooks(chan)) && ast_framehook_list_is_empty(ast_channel_framehooks(peer)))
@ -925,10 +880,6 @@ static int onedigit_goto(struct ast_channel *chan, const char *context, char ext
} else {
if (!ast_goto_if_exists(chan, ast_channel_context(chan), rexten, pri))
return 1;
else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
if (!ast_goto_if_exists(chan, ast_channel_macrocontext(chan), rexten, pri))
return 1;
}
}
return 0;
}
@ -940,8 +891,8 @@ static const char *get_cid_name(char *name, int namelen, struct ast_channel *cha
const char *exten;
ast_channel_lock(chan);
context = ast_strdupa(S_OR(ast_channel_macrocontext(chan), ast_channel_context(chan)));
exten = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
context = ast_strdupa(ast_channel_context(chan));
exten = ast_strdupa(ast_channel_exten(chan));
ast_channel_unlock(chan);
return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
@ -1076,7 +1027,7 @@ static void do_forward(struct chanlist *o, struct cause_args *num,
ast_party_number_init(&ast_channel_redirecting(c)->from.number);
ast_channel_redirecting(c)->from.number.valid = 1;
ast_channel_redirecting(c)->from.number.str =
ast_strdup(S_OR(ast_channel_macroexten(in), ast_channel_exten(in)));
ast_strdup(ast_channel_exten(in));
}
ast_channel_dialed(c)->transit_network_select = ast_channel_dialed(in)->transit_network_select;
@ -1125,17 +1076,12 @@ static void do_forward(struct chanlist *o, struct cause_args *num,
* Redirecting updates to the caller make sense only on single
* calls.
*
* We must unlock c before calling
* ast_channel_redirecting_macro, because we put c into
* autoservice there. That is pretty much a guaranteed
* deadlock. This is why the handling of c's lock may seem a
* bit unusual here.
* Need to re-evalute if unlocking is still required here as macro is gone
*/
ast_party_redirecting_init(&redirecting);
ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(c));
ast_channel_unlock(c);
if (ast_channel_redirecting_sub(c, in, &redirecting, 0) &&
ast_channel_redirecting_macro(c, in, &redirecting, 1, 0)) {
if (ast_channel_redirecting_sub(c, in, &redirecting, 0)) {
ast_channel_update_redirecting(in, &redirecting, NULL);
}
ast_party_redirecting_free(&redirecting);
@ -1211,8 +1157,7 @@ static void update_connected_line_from_peer(struct ast_channel *chan, struct ast
ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(peer));
ast_channel_unlock(peer);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)
&& ast_channel_connected_line_macro(peer, chan, &connected_caller, is_caller, 0)) {
if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)) {
ast_channel_update_connected_line(chan, &connected_caller, NULL);
}
ast_party_connected_line_free(&connected_caller);
@ -1344,8 +1289,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
update_connected_line_from_peer(in, c, 1);
} else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
if (ast_channel_connected_line_sub(c, in, &o->connected, 0)) {
ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
@ -1443,8 +1387,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
update_connected_line_from_peer(in, c, 1);
} else if (!single && !ast_test_flag64(o, OPT_IGNORE_CONNECTEDLINE)) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_sub(c, in, &o->connected, 0) &&
ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
if (ast_channel_connected_line_sub(c, in, &o->connected, 0)) {
ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!ast_test_flag64(o, DIAL_CALLERID_ABSENT)) {
@ -1676,8 +1619,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
o->pending_connected_update = 1;
break;
}
if (ast_channel_connected_line_sub(c, in, f, 1) &&
ast_channel_connected_line_macro(c, in, f, 1, 1)) {
if (ast_channel_connected_line_sub(c, in, f, 1)) {
ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
}
break;
@ -1706,8 +1648,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
}
ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
ast_channel_name(c), ast_channel_name(in));
if (ast_channel_redirecting_sub(c, in, f, 1) &&
ast_channel_redirecting_macro(c, in, f, 1, 1)) {
if (ast_channel_redirecting_sub(c, in, f, 1)) {
ast_indicate_data(in, AST_CONTROL_REDIRECTING, f->data.ptr, f->datalen);
}
pa->sentringing = 0;
@ -1915,8 +1856,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(o->chan));
break;
}
if (ast_channel_connected_line_sub(in, o->chan, f, 1) &&
ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
if (ast_channel_connected_line_sub(in, o->chan, f, 1)) {
ast_indicate_data(o->chan, f->subclass.integer, f->data.ptr, f->datalen);
}
break;
@ -1925,8 +1865,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
break;
}
if (ast_channel_redirecting_sub(in, o->chan, f, 1) &&
ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
if (ast_channel_redirecting_sub(in, o->chan, f, 1)) {
ast_indicate_data(o->chan, f->subclass.integer, f->data.ptr, f->datalen);
}
break;
@ -2483,7 +2422,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
if (ast_test_flag64(&opts, OPT_FORCECLID)) {
if (ast_strlen_zero(opt_args[OPT_ARG_FORCECLID])) {
ast_channel_lock(chan);
forced_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
forced_clid.number.str = ast_strdupa(ast_channel_exten(chan));
ast_channel_unlock(chan);
forced_clid_name[0] = '\0';
forced_clid.name.str = (char *) get_cid_name(forced_clid_name,
@ -2560,7 +2499,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
stored_clid.name.valid = 1;
}
ast_channel_lock(chan);
stored_clid.number.str = ast_strdupa(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)));
stored_clid.number.str = ast_strdupa(ast_channel_exten(chan));
stored_clid.number.valid = 1;
ast_channel_unlock(chan);
}
@ -2595,7 +2534,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
/* Set per dial instance flags. These flags are also passed back to RetryDial. */
ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID
| OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_CANCEL_TIMEOUT
| OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB | OPT_FORCECLID);
| OPT_ANNOUNCE | OPT_CALLEE_GOSUB | OPT_FORCECLID);
/* PREDIAL: Run gosub on the caller's channel */
if (ast_test_flag64(&opts, OPT_PREDIAL_CALLER)
@ -2821,11 +2760,8 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
/* Inherit context and extension */
ast_channel_dialcontext_set(tc, ast_strlen_zero(ast_channel_macrocontext(chan)) ? ast_channel_context(chan) : ast_channel_macrocontext(chan));
if (!ast_strlen_zero(ast_channel_macroexten(chan)))
ast_channel_exten_set(tc, ast_channel_macroexten(chan));
else
ast_channel_exten_set(tc, ast_channel_exten(chan));
ast_channel_dialcontext_set(tc, ast_channel_context(chan));
ast_channel_exten_set(tc, ast_channel_exten(chan));
ast_channel_stage_snapshot_done(tc);
@ -3148,9 +3084,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
} else {
other_chan = chan;
}
if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)
&& ast_channel_connected_line_macro(active_chan,
other_chan, fr, other_chan == chan, 1)) {
if (ast_channel_connected_line_sub(active_chan, other_chan, fr, 1)) {
ast_indicate_data(other_chan, fr->subclass.integer,
fr->data.ptr, fr->datalen);
}
@ -3197,66 +3131,6 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
goto done;
}
if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
const char *macro_result_peer;
int macro_res;
/* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
ast_channel_lock_both(chan, peer);
ast_channel_context_set(peer, ast_channel_context(chan));
ast_channel_exten_set(peer, ast_channel_exten(chan));
ast_channel_unlock(peer);
ast_channel_unlock(chan);
ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
macro_res = ast_app_exec_macro(chan, peer, opt_args[OPT_ARG_CALLEE_MACRO]);
ast_channel_lock(peer);
if (!macro_res && (macro_result_peer = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
char *macro_result = ast_strdupa(macro_result_peer);
char *macro_transfer_dest;
ast_channel_unlock(peer);
if (!strcasecmp(macro_result, "BUSY")) {
ast_copy_string(pa.status, macro_result, sizeof(pa.status));
ast_set_flag64(peerflags, OPT_GO_ON);
macro_res = -1;
} else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
ast_copy_string(pa.status, macro_result, sizeof(pa.status));
ast_set_flag64(peerflags, OPT_GO_ON);
macro_res = -1;
} else if (!strcasecmp(macro_result, "CONTINUE")) {
/* hangup peer and keep chan alive assuming the macro has changed
the context / exten / priority or perhaps
the next priority in the current exten is desired.
*/
ast_set_flag64(peerflags, OPT_GO_ON);
macro_res = -1;
} else if (!strcasecmp(macro_result, "ABORT")) {
/* Hangup both ends unless the caller has the g flag */
macro_res = -1;
} else if (!strncasecmp(macro_result, "GOTO:", 5)) {
macro_transfer_dest = macro_result + 5;
macro_res = -1;
/* perform a transfer to a new extension */
if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
ast_replace_subargument_delimiter(macro_transfer_dest);
}
if (!ast_parseable_goto(chan, macro_transfer_dest)) {
ast_set_flag64(peerflags, OPT_GO_ON);
}
}
if (macro_res && !dial_end_raised) {
ast_channel_publish_dial(chan, peer, NULL, macro_result);
dial_end_raised = 1;
}
} else {
ast_channel_unlock(peer);
}
res = macro_res;
}
if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
const char *gosub_result_peer;
char *gosub_argstart;

View File

@ -267,9 +267,7 @@ static int compare(const char *text, const char *template)
static int goto_exten(struct ast_channel *chan, const char *dialcontext, char *ext)
{
if (!ast_goto_if_exists(chan, S_OR(dialcontext, ast_channel_context(chan)), ext, 1) ||
(!ast_strlen_zero(ast_channel_macrocontext(chan)) &&
!ast_goto_if_exists(chan, ast_channel_macrocontext(chan), ext, 1))) {
if (!ast_goto_if_exists(chan, S_OR(dialcontext, ast_channel_context(chan)), ext, 1)) {
return 0;
} else {
ast_log(LOG_WARNING, "Can't find extension '%s' in current context. "

View File

@ -1527,8 +1527,7 @@ static int app_exec(struct ast_channel *chan, const char *data)
/* Update connected line to caller if available. */
if (targs->pending_out_connected_update) {
if (ast_channel_connected_line_sub(outbound, caller, &targs->connected_out, 0) &&
ast_channel_connected_line_macro(outbound, caller, &targs->connected_out, 1, 0)) {
if (ast_channel_connected_line_sub(outbound, caller, &targs->connected_out, 0)) {
ast_channel_update_connected_line(caller, &targs->connected_out, NULL);
}
}
@ -1553,8 +1552,7 @@ static int app_exec(struct ast_channel *chan, const char *data)
/* Update connected line to winner if changed. */
if (targs->pending_in_connected_update) {
if (ast_channel_connected_line_sub(caller, outbound, &targs->connected_in, 0) &&
ast_channel_connected_line_macro(caller, outbound, &targs->connected_in, 0, 0)) {
if (ast_channel_connected_line_sub(caller, outbound, &targs->connected_in, 0)) {
ast_channel_update_connected_line(outbound, &targs->connected_in, NULL);
}
}

View File

@ -1,691 +0,0 @@
/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 1999 - 2005, Digium, Inc.
*
* Mark Spencer <markster@digium.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.
*/
/*! \file
*
* \brief Dial plan macro Implementation
*
* \author Mark Spencer <markster@digium.com>
*
* \ingroup applications
*/
/*** MODULEINFO
<defaultenabled>no</defaultenabled>
<support_level>deprecated</support_level>
<replacement>app_stack (GoSub)</replacement>
<deprecated_in>16</deprecated_in>
<removed_in>21</removed_in>
***/
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/extconf.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
/*** DOCUMENTATION
<application name="Macro" language="en_US">
<synopsis>
Macro Implementation.
</synopsis>
<syntax>
<parameter name="name" required="true">
<para>The name of the macro</para>
</parameter>
<parameter name="args">
<argument name="arg1" required="true" />
<argument name="arg2" multiple="true" />
</parameter>
</syntax>
<description>
<para>Executes a macro using the context macro-<replaceable>name</replaceable>,
jumping to the <literal>s</literal> extension of that context and executing each step,
then returning when the steps end.</para>
<para>The calling extension, context, and priority are stored in <variable>MACRO_EXTEN</variable>,
<variable>MACRO_CONTEXT</variable> and <variable>MACRO_PRIORITY</variable> respectively. Arguments
become <variable>ARG1</variable>, <variable>ARG2</variable>, etc in the macro context.</para>
<para>If you Goto out of the Macro context, the Macro will terminate and control will be returned
at the location of the Goto.</para>
<para>If <variable>MACRO_OFFSET</variable> is set at termination, Macro will attempt to continue
at priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.</para>
<warning><para>Because of the way Macro is implemented (it executes the priorities contained within
it via sub-engine), and a fixed per-thread memory stack allowance, macros are limited to 7 levels
of nesting (macro calling macro calling macro, etc.); It may be possible that stack-intensive
applications in deeply nested macros could cause asterisk to crash earlier than this limit.
It is advised that if you need to deeply nest macro calls, that you use the Gosub application
(now allows arguments like a Macro) with explicit Return() calls instead.</para></warning>
<warning><para>Use of the application <literal>WaitExten</literal> within a macro will not function
as expected. Please use the <literal>Read</literal> application in order to read DTMF from a channel
currently executing a macro.</para></warning>
</description>
<see-also>
<ref type="application">MacroExit</ref>
<ref type="application">Goto</ref>
<ref type="application">Gosub</ref>
</see-also>
</application>
<application name="MacroIf" language="en_US">
<synopsis>
Conditional Macro implementation.
</synopsis>
<syntax argsep="?">
<parameter name="expr" required="true" />
<parameter name="destination" required="true" argsep=":">
<argument name="macroiftrue" required="true">
<argument name="macroiftrue" required="true" />
<argument name="arg1" multiple="true" />
</argument>
<argument name="macroiffalse">
<argument name="macroiffalse" required="true" />
<argument name="arg1" multiple="true" />
</argument>
</parameter>
</syntax>
<description>
<para>Executes macro defined in <replaceable>macroiftrue</replaceable> if
<replaceable>expr</replaceable> is true (otherwise <replaceable>macroiffalse</replaceable>
if provided)</para>
<para>Arguments and return values as in application Macro()</para>
<xi:include xpointer="xpointer(/docs/application[@name='Macro']/description/warning[2])" />
</description>
<see-also>
<ref type="application">GotoIf</ref>
<ref type="application">GosubIf</ref>
<ref type="function">IF</ref>
</see-also>
</application>
<application name="MacroExclusive" language="en_US">
<synopsis>
Exclusive Macro Implementation.
</synopsis>
<syntax>
<parameter name="name" required="true">
<para>The name of the macro</para>
</parameter>
<parameter name="arg1" />
<parameter name="arg2" multiple="true" />
</syntax>
<description>
<para>Executes macro defined in the context macro-<replaceable>name</replaceable>.
Only one call at a time may run the macro. (we'll wait if another call is busy
executing in the Macro)</para>
<para>Arguments and return values as in application Macro()</para>
<xi:include xpointer="xpointer(/docs/application[@name='Macro']/description/warning[2])" />
</description>
<see-also>
<ref type="application">Macro</ref>
</see-also>
</application>
<application name="MacroExit" language="en_US">
<synopsis>
Exit from Macro.
</synopsis>
<syntax />
<description>
<para>Causes the currently running macro to exit as if it had
ended normally by running out of priorities to execute.
If used outside a macro, will likely cause unexpected behavior.</para>
</description>
<see-also>
<ref type="application">Macro</ref>
</see-also>
</application>
***/
#define MAX_ARGS 80
/* special result value used to force macro exit */
#define MACRO_EXIT_RESULT 1024
static char *app = "Macro";
static char *if_app = "MacroIf";
static char *exclusive_app = "MacroExclusive";
static char *exit_app = "MacroExit";
static void macro_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
static const struct ast_datastore_info macro_ds_info = {
.type = "MACRO",
.chan_fixup = macro_fixup,
};
static void macro_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
{
int i;
char varname[10];
pbx_builtin_setvar_helper(new_chan, "MACRO_DEPTH", "0");
pbx_builtin_setvar_helper(new_chan, "MACRO_CONTEXT", NULL);
pbx_builtin_setvar_helper(new_chan, "MACRO_EXTEN", NULL);
pbx_builtin_setvar_helper(new_chan, "MACRO_PRIORITY", NULL);
pbx_builtin_setvar_helper(new_chan, "MACRO_OFFSET", NULL);
for (i = 1; i < 100; i++) {
snprintf(varname, sizeof(varname), "ARG%d", i);
while (pbx_builtin_getvar_helper(new_chan, varname)) {
/* Kill all levels of arguments */
pbx_builtin_setvar_helper(new_chan, varname, NULL);
}
}
}
static struct ast_exten *find_matching_priority(struct ast_context *c, const char *exten,
int priority, const char *callerid, int iter, int *had_error)
{
struct ast_exten *e;
struct ast_context *c2;
int idx;
if (iter >= AST_PBX_MAX_STACK) {
if (!(*had_error)) {
*had_error = 1;
ast_log(LOG_ERROR, "Potential infinite loop detected, will not recurse further.\n");
}
return NULL;
}
for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
if (ast_extension_match(ast_get_extension_name(e), exten)) {
int needmatch = ast_get_extension_matchcid(e);
if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) ||
(!needmatch)) {
/* This is the matching extension we want */
struct ast_exten *p;
for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) {
if (priority != ast_get_extension_priority(p))
continue;
return p;
}
}
}
}
/* No match; run through includes */
for (idx = 0; idx < ast_context_includes_count(c); idx++) {
const struct ast_include *i = ast_context_includes_get(c, idx);
for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
e = find_matching_priority(c2, exten, priority, callerid, iter + 1, had_error);
if (e)
return e;
}
}
}
return NULL;
}
static int _macro_exec(struct ast_channel *chan, const char *data, int exclusive)
{
const char *s;
char *tmp;
char *cur, *rest;
char *macro;
char fullmacro[80];
char varname[80];
char runningapp[80], runningdata[1024];
char *oldargs[MAX_ARGS + 1] = { NULL, };
int argc, x;
int res=0;
char oldexten[256]="";
int oldpriority, gosub_level = 0;
char pc[80], depthc[12];
char oldcontext[AST_MAX_CONTEXT] = "";
const char *inhangupc;
int offset, depth = 0, maxdepth = 7;
int setmacrocontext=0;
int autoloopflag, inhangup = 0;
struct ast_str *tmp_subst = NULL;
const char *my_macro_exten = NULL;
char *save_macro_exten;
char *save_macro_context;
char *save_macro_priority;
char *save_macro_offset;
int save_in_subroutine;
struct ast_datastore *macro_store = ast_channel_datastore_find(chan, &macro_ds_info, NULL);
int had_infinite_include_error = 0;
static int deprecation_notice = 0;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Macro() requires arguments. See \"core show application macro\" for help.\n");
return -1;
}
if (!deprecation_notice) {
deprecation_notice = 1;
ast_log(LOG_WARNING, "Macro() is deprecated and will be removed from a future version of Asterisk.\n");
ast_log(LOG_WARNING, "Dialplan should be updated to use Gosub instead.\n");
}
do {
if (macro_store) {
break;
}
if (!(macro_store = ast_datastore_alloc(&macro_ds_info, NULL))) {
ast_log(LOG_WARNING, "Unable to allocate new datastore.\n");
break;
}
/* Just the existence of this datastore is enough. */
macro_store->inheritance = DATASTORE_INHERIT_FOREVER;
ast_channel_datastore_add(chan, macro_store);
} while (0);
/* does the user want a deeper rabbit hole? */
ast_channel_lock(chan);
if ((s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"))) {
sscanf(s, "%30d", &maxdepth);
}
/* Count how many levels deep the rabbit hole goes */
if ((s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH"))) {
sscanf(s, "%30d", &depth);
}
/* Used for detecting whether to return when a Macro is called from another Macro after hangup */
if (strcmp(ast_channel_exten(chan), "h") == 0)
pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1");
if ((inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP"))) {
sscanf(inhangupc, "%30d", &inhangup);
}
ast_channel_unlock(chan);
if (depth >= maxdepth) {
ast_log(LOG_ERROR, "Macro(): possible infinite loop detected. Returning early.\n");
return 0;
}
snprintf(depthc, sizeof(depthc), "%d", depth + 1);
tmp = ast_strdupa(data);
rest = tmp;
macro = strsep(&rest, ",");
if (ast_strlen_zero(macro)) {
ast_log(LOG_WARNING, "Invalid macro name specified\n");
return 0;
}
snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro);
/* first search for the macro */
if (!ast_context_find(fullmacro)) {
ast_log(LOG_WARNING, "No such context '%s' for macro '%s'. Was called by %s@%s\n",
fullmacro, macro, ast_channel_exten(chan), ast_channel_context(chan));
return 0;
}
/* now search for the right extension */
if (ast_exists_extension(chan, fullmacro, "s", 1,
S_COR(ast_channel_caller(chan)->id.number.valid,
ast_channel_caller(chan)->id.number.str, NULL))) {
/* We have a normal macro */
my_macro_exten = "s";
} else if (ast_exists_extension(chan, fullmacro, "~~s~~", 1,
S_COR(ast_channel_caller(chan)->id.number.valid,
ast_channel_caller(chan)->id.number.str, NULL))) {
/* We have an AEL generated macro */
my_macro_exten = "~~s~~";
}
/* do we have a valid exten? */
if (!my_macro_exten) {
ast_log(LOG_WARNING,
"Context '%s' for macro '%s' lacks 's' extension, priority 1\n",
fullmacro, macro);
return 0;
}
/* If we are to run the macro exclusively, take the mutex */
if (exclusive) {
ast_debug(1, "Locking macrolock for '%s'\n", fullmacro);
ast_autoservice_start(chan);
if (ast_context_lockmacro(fullmacro)) {
ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro);
ast_autoservice_stop(chan);
return 0;
}
ast_autoservice_stop(chan);
}
if (!(tmp_subst = ast_str_create(16))) {
return -1;
}
/* Save old info */
ast_channel_lock(chan);
oldpriority = ast_channel_priority(chan);
ast_copy_string(oldexten, ast_channel_exten(chan), sizeof(oldexten));
ast_copy_string(oldcontext, ast_channel_context(chan), sizeof(oldcontext));
if (ast_strlen_zero(ast_channel_macrocontext(chan))) {
ast_channel_macrocontext_set(chan, ast_channel_context(chan));
ast_channel_macroexten_set(chan, ast_channel_exten(chan));
ast_channel_macropriority_set(chan, ast_channel_priority(chan));
setmacrocontext=1;
}
argc = 1;
/* Save old macro variables */
save_macro_exten = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_EXTEN"));
pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten);
save_macro_context = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT"));
pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext);
save_macro_priority = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY"));
snprintf(pc, sizeof(pc), "%d", oldpriority);
pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc);
save_macro_offset = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"));
pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL);
pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
save_in_subroutine = ast_test_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
ast_set_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
/* Setup environment for new run */
ast_channel_exten_set(chan, my_macro_exten);
ast_channel_context_set(chan, fullmacro);
ast_channel_priority_set(chan, 1);
while((cur = strsep(&rest, ",")) && (argc < MAX_ARGS)) {
const char *argp;
/* Save copy of old arguments if we're overwriting some, otherwise
let them pass through to the other macro */
snprintf(varname, sizeof(varname), "ARG%d", argc);
if ((argp = pbx_builtin_getvar_helper(chan, varname))) {
oldargs[argc] = ast_strdup(argp);
}
pbx_builtin_setvar_helper(chan, varname, cur);
argc++;
}
autoloopflag = ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
ast_set_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
ast_channel_unlock(chan);
while (ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan),
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
struct ast_context *c;
struct ast_exten *e;
int foundx;
runningapp[0] = '\0';
runningdata[0] = '\0';
/* What application will execute? */
if (ast_rdlock_contexts()) {
ast_log(LOG_WARNING, "Failed to lock contexts list\n");
} else {
for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) {
if (!strcmp(ast_get_context_name(c), ast_channel_context(chan))) {
if (ast_rdlock_context(c)) {
ast_log(LOG_WARNING, "Unable to lock context?\n");
} else {
e = find_matching_priority(c, ast_channel_exten(chan), ast_channel_priority(chan),
S_COR(ast_channel_caller(chan)->id.number.valid,
ast_channel_caller(chan)->id.number.str, NULL),
0, &had_infinite_include_error);
if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */
ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp));
ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata));
}
ast_unlock_context(c);
}
break;
}
}
}
ast_unlock_contexts();
/* Reset the macro depth, if it was changed in the last iteration */
pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
res = ast_spawn_extension(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan),
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
&foundx, 1);
if (res) {
/* Something bad happened, or a hangup has been requested. */
if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
(res == '*') || (res == '#')) {
/* Just return result as to the previous application as if it had been dialed */
ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
break;
}
switch(res) {
case MACRO_EXIT_RESULT:
res = 0;
goto out;
default:
ast_debug(2, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), ast_channel_name(chan), macro);
ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), ast_channel_name(chan), macro);
goto out;
}
}
ast_debug(1, "Executed application: %s\n", runningapp);
if (!strcasecmp(runningapp, "GOSUB")) {
gosub_level++;
ast_debug(1, "Incrementing gosub_level\n");
} else if (!strcasecmp(runningapp, "GOSUBIF")) {
char *cond, *app_arg;
char *app2;
ast_str_substitute_variables(&tmp_subst, 0, chan, runningdata);
app2 = ast_str_buffer(tmp_subst);
cond = strsep(&app2, "?");
app_arg = strsep(&app2, ":");
if (pbx_checkcondition(cond)) {
if (!ast_strlen_zero(app_arg)) {
gosub_level++;
ast_debug(1, "Incrementing gosub_level\n");
}
} else {
if (!ast_strlen_zero(app2)) {
gosub_level++;
ast_debug(1, "Incrementing gosub_level\n");
}
}
} else if (!strcasecmp(runningapp, "RETURN")) {
gosub_level--;
ast_debug(1, "Decrementing gosub_level\n");
} else if (!strcasecmp(runningapp, "STACKPOP")) {
gosub_level--;
ast_debug(1, "Decrementing gosub_level\n");
} else if (!strncasecmp(runningapp, "EXEC", 4)) {
/* Must evaluate args to find actual app */
char *tmp2, *tmp3 = NULL;
ast_str_substitute_variables(&tmp_subst, 0, chan, runningdata);
tmp2 = ast_str_buffer(tmp_subst);
if (!strcasecmp(runningapp, "EXECIF")) {
if ((tmp3 = strchr(tmp2, '|'))) {
*tmp3++ = '\0';
}
if (!pbx_checkcondition(tmp2)) {
tmp3 = NULL;
}
} else {
tmp3 = tmp2;
}
if (tmp3) {
ast_debug(1, "Last app: %s\n", tmp3);
}
if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) {
gosub_level++;
ast_debug(1, "Incrementing gosub_level\n");
} else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) {
gosub_level--;
ast_debug(1, "Decrementing gosub_level\n");
} else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) {
gosub_level--;
ast_debug(1, "Decrementing gosub_level\n");
}
}
if (gosub_level == 0 && strcasecmp(ast_channel_context(chan), fullmacro)) {
ast_verb(2, "Channel '%s' jumping out of macro '%s'\n", ast_channel_name(chan), macro);
break;
}
/* don't stop executing extensions when we're in "h" */
if (ast_check_hangup(chan) && !inhangup) {
ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n",
ast_channel_exten(chan),
ast_channel_macroexten(chan),
ast_channel_priority(chan));
goto out;
}
ast_channel_priority_set(chan, ast_channel_priority(chan) + 1);
}
out:
/* Don't let the channel change now. */
ast_channel_lock(chan);
/* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */
snprintf(depthc, sizeof(depthc), "%d", depth);
pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
ast_set2_flag(ast_channel_flags(chan), autoloopflag, AST_FLAG_IN_AUTOLOOP);
ast_set2_flag(ast_channel_flags(chan), save_in_subroutine, AST_FLAG_SUBROUTINE_EXEC);
for (x = 1; x < argc; x++) {
/* Restore old arguments and delete ours */
snprintf(varname, sizeof(varname), "ARG%d", x);
pbx_builtin_setvar_helper(chan, varname, oldargs[x]);
ast_free(oldargs[x]);
}
/* Restore macro variables */
pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten);
pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context);
pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority);
ast_free(save_macro_exten);
ast_free(save_macro_context);
ast_free(save_macro_priority);
if (setmacrocontext) {
ast_channel_macrocontext_set(chan, "");
ast_channel_macroexten_set(chan, "");
ast_channel_macropriority_set(chan, 0);
}
if (!strcasecmp(ast_channel_context(chan), fullmacro)
&& !(ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO)) {
const char *offsets;
/* If we're leaving the macro normally, restore original information */
ast_channel_priority_set(chan, oldpriority);
ast_channel_context_set(chan, oldcontext);
ast_channel_exten_set(chan, oldexten);
if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
/* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
normally if there is any problem */
if (sscanf(offsets, "%30d", &offset) == 1) {
if (ast_exists_extension(chan, ast_channel_context(chan), ast_channel_exten(chan),
ast_channel_priority(chan) + offset + 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
ast_channel_priority_set(chan, ast_channel_priority(chan) + offset);
}
}
}
}
pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset);
ast_free(save_macro_offset);
/* Unlock the macro */
if (exclusive) {
ast_debug(1, "Unlocking macrolock for '%s'\n", fullmacro);
if (ast_context_unlockmacro(fullmacro)) {
ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro);
res = 0;
}
}
ast_channel_unlock(chan);
ast_free(tmp_subst);
return res;
}
static int macro_exec(struct ast_channel *chan, const char *data)
{
return _macro_exec(chan, data, 0);
}
static int macroexclusive_exec(struct ast_channel *chan, const char *data)
{
return _macro_exec(chan, data, 1);
}
static int macroif_exec(struct ast_channel *chan, const char *data)
{
char *expr = NULL, *label_a = NULL, *label_b = NULL;
int res = 0;
expr = ast_strdupa(data);
if ((label_a = strchr(expr, '?'))) {
*label_a = '\0';
label_a++;
if ((label_b = strchr(label_a, ':'))) {
*label_b = '\0';
label_b++;
}
if (pbx_checkcondition(expr))
res = macro_exec(chan, label_a);
else if (label_b)
res = macro_exec(chan, label_b);
} else
ast_log(LOG_WARNING, "Invalid Syntax.\n");
return res;
}
static int macro_exit_exec(struct ast_channel *chan, const char *data)
{
return MACRO_EXIT_RESULT;
}
static int unload_module(void)
{
int res;
res = ast_unregister_application(if_app);
res |= ast_unregister_application(exit_app);
res |= ast_unregister_application(app);
res |= ast_unregister_application(exclusive_app);
return res;
}
static int load_module(void)
{
int res;
res = ast_register_application_xml(exit_app, macro_exit_exec);
res |= ast_register_application_xml(if_app, macroif_exec);
res |= ast_register_application_xml(exclusive_app, macroexclusive_exec);
res |= ast_register_application_xml(app, macro_exec);
return res;
}
AST_MODULE_INFO_STANDARD_DEPRECATED(ASTERISK_GPL_KEY, "Extension Macros");

View File

@ -3596,8 +3596,6 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
ast_channel_lock(chan);
if ((tmpvar = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT"))) {
ast_copy_string(exitcontext, tmpvar, sizeof(exitcontext));
} else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
ast_copy_string(exitcontext, ast_channel_macrocontext(chan), sizeof(exitcontext));
} else {
ast_copy_string(exitcontext, ast_channel_context(chan), sizeof(exitcontext));
}

View File

@ -1878,11 +1878,10 @@ static int leave_voicemail(struct ast_channel *chan, char *username, struct leav
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
"Unknown");
snprintf(logbuf, sizeof(logbuf),
/* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */
"%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
/* "Mailbox:domain:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */
"%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
username,
ast_channel_context(chan),
ast_channel_macrocontext(chan),
ast_channel_exten(chan),
ast_channel_priority(chan),
ast_channel_name(chan),
@ -2140,8 +2139,6 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
struct ast_flags flags = { 0 };
char *opts[OPT_ARG_ARRAY_SIZE];
int res = 0;
int ausemacro = 0;
int ousemacro = 0;
int ouseexten = 0;
char tmp[PATH_MAX];
char dest[PATH_MAX];
@ -2212,7 +2209,7 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
}
ast_debug(2, "Preparing to play message ...\n");
/* Check current or macro-calling context for special extensions */
/* Check current context for special extensions */
if (ast_test_flag(vmu, MVM_OPERATOR)) {
if (!ast_strlen_zero(vmu->exit)) {
if (ast_exists_extension(chan, vmu->exit, "o", 1,
@ -2225,12 +2222,6 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
}
else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
&& ast_exists_extension(chan, ast_channel_macrocontext(chan), "o", 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ousemacro = 1;
}
}
if (!ast_strlen_zero(vmu->exit)) {
@ -2241,11 +2232,6 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
} else if (ast_exists_extension(chan, ast_channel_context(chan), "a", 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
} else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
&& ast_exists_extension(chan, ast_channel_macrocontext(chan), "a", 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
ausemacro = 1;
}
res = 0; /* Reset */
@ -2286,19 +2272,15 @@ static int minivm_greet_exec(struct ast_channel *chan, const char *data)
ast_channel_exten_set(chan, "a");
if (!ast_strlen_zero(vmu->exit)) {
ast_channel_context_set(chan, vmu->exit);
} else if (ausemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
ast_channel_context_set(chan, ast_channel_macrocontext(chan));
}
ast_channel_priority_set(chan, 0);
pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
res = 0;
} else if (res == '0') { /* Check for a '0' here */
if(ouseexten || ousemacro) {
if(ouseexten) {
ast_channel_exten_set(chan, "o");
if (!ast_strlen_zero(vmu->exit)) {
ast_channel_context_set(chan, vmu->exit);
} else if (ousemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
ast_channel_context_set(chan, ast_channel_macrocontext(chan));
}
ast_play_and_wait(chan, "transfer");
ast_channel_priority_set(chan, 0);

View File

@ -389,7 +389,6 @@ struct mixmonitor {
/* the below string fields describe data used for creating voicemails from the recording */
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(call_context);
AST_STRING_FIELD(call_macrocontext);
AST_STRING_FIELD(call_extension);
AST_STRING_FIELD(call_callerchan);
AST_STRING_FIELD(call_callerid);
@ -660,7 +659,6 @@ static void copy_to_voicemail(struct mixmonitor *mixmonitor, const char *ext, co
ast_string_field_set(&recording_data, recording_file, filename);
ast_string_field_set(&recording_data, recording_ext, ext);
ast_string_field_set(&recording_data, call_context, mixmonitor->call_context);
ast_string_field_set(&recording_data, call_macrocontext, mixmonitor->call_macrocontext);
ast_string_field_set(&recording_data, call_extension, mixmonitor->call_extension);
ast_string_field_set(&recording_data, call_callerchan, mixmonitor->call_callerchan);
ast_string_field_set(&recording_data, call_callerid, mixmonitor->call_callerid);
@ -1075,7 +1073,6 @@ static int launch_monitor_thread(struct ast_channel *chan, const char *filename,
}
ast_string_field_set(mixmonitor, call_context, ast_channel_context(chan));
ast_string_field_set(mixmonitor, call_macrocontext, ast_channel_macrocontext(chan));
ast_string_field_set(mixmonitor, call_extension, ast_channel_exten(chan));
ast_string_field_set(mixmonitor, call_callerchan, ast_channel_name(chan));
ast_string_field_set(mixmonitor, call_callerid, callerid);

View File

@ -177,7 +177,7 @@
the current extension and <emphasis>start</emphasis> execution at that location.</para>
<para>NOTE: Any channel variables you want the called channel to inherit from the caller channel must be
prefixed with one or two underbars ('_').</para>
<para>NOTE: Using this option from a Macro() or GoSub() might not make sense as there would be no return points.</para>
<para>NOTE: Using this option from a GoSub() might not make sense as there would be no return points.</para>
</option>
<option name="h">
<para>Allow <emphasis>callee</emphasis> to hang up by pressing <literal>*</literal>.</para>
@ -259,10 +259,6 @@
<para>Will setup an AGI script to be executed on the calling party's channel once they are
connected to a queue member.</para>
</parameter>
<parameter name="macro">
<para>Will run a macro on the called party's channel (the queue member) once the parties are connected.</para>
<para>NOTE: Macros are deprecated, GoSub should be used instead.</para>
</parameter>
<parameter name="gosub">
<para>Will run a gosub on the called party's channel (the queue member)
once the parties are connected. The subroutine execution starts in the
@ -1800,8 +1796,6 @@ struct call_queue {
AST_STRING_FIELD(announce);
/*! Exit context */
AST_STRING_FIELD(context);
/*! Macro to run upon member connection */
AST_STRING_FIELD(membermacro);
/*! Gosub to run upon member connection */
AST_STRING_FIELD(membergosub);
/*! Default rule to use if none specified in call to Queue() */
@ -3345,8 +3339,6 @@ static void queue_set_param(struct call_queue *q, const char *param, const char
q->setqueueentryvar = ast_true(val);
} else if (!strcasecmp(param, "monitor-format")) {
ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
} else if (!strcasecmp(param, "membermacro")) {
ast_string_field_set(q, membermacro, val);
} else if (!strcasecmp(param, "membergosub")) {
ast_string_field_set(q, membergosub, val);
} else if (!strcasecmp(param, "queue-youarenext")) {
@ -4687,7 +4679,6 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
int status;
char tech[256];
char *location;
const char *macrocontext, *macroexten;
struct ast_format_cap *nativeformats;
RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
@ -4748,8 +4739,8 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
ast_channel_set_caller_event(tmp->chan, &caller, NULL);
} else if (!ast_strlen_zero(ast_channel_dialed(qe->chan)->number.str)) {
ast_set_callerid(tmp->chan, ast_channel_dialed(qe->chan)->number.str, NULL, NULL);
} else if (!ast_strlen_zero(S_OR(ast_channel_macroexten(qe->chan), ast_channel_exten(qe->chan)))) {
ast_set_callerid(tmp->chan, S_OR(ast_channel_macroexten(qe->chan), ast_channel_exten(qe->chan)), NULL, NULL);
} else if (!ast_strlen_zero(ast_channel_exten(qe->chan))) {
ast_set_callerid(tmp->chan, ast_channel_exten(qe->chan), NULL, NULL);
}
tmp->dial_callerid_absent = 1;
}
@ -4769,14 +4760,8 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
ast_channel_adsicpe_set(tmp->chan, ast_channel_adsicpe(qe->chan));
/* Inherit context and extension */
macrocontext = pbx_builtin_getvar_helper(qe->chan, "MACRO_CONTEXT");
ast_channel_dialcontext_set(tmp->chan, ast_strlen_zero(macrocontext) ? ast_channel_context(qe->chan) : macrocontext);
macroexten = pbx_builtin_getvar_helper(qe->chan, "MACRO_EXTEN");
if (!ast_strlen_zero(macroexten)) {
ast_channel_exten_set(tmp->chan, macroexten);
} else {
ast_channel_exten_set(tmp->chan, ast_channel_exten(qe->chan));
}
ast_channel_dialcontext_set(tmp->chan, ast_channel_context(qe->chan));
ast_channel_exten_set(tmp->chan, ast_channel_exten(qe->chan));
/* Save the original channel name to detect call pickup masquerading in. */
tmp->orig_chan_name = ast_strdup(ast_channel_name(tmp->chan));
@ -5120,8 +5105,7 @@ static void update_connected_line_from_peer(struct ast_channel *chan, struct ast
ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(peer));
ast_channel_unlock(peer);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)
&& ast_channel_connected_line_macro(peer, chan, &connected_caller, is_caller, 0)) {
if (ast_channel_connected_line_sub(peer, chan, &connected_caller, 0)) {
ast_channel_update_connected_line(chan, &connected_caller, NULL);
}
ast_party_connected_line_free(&connected_caller);
@ -5241,8 +5225,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
update_connected_line_from_peer(in, o->chan, 1);
} else if (!o->block_connected_update) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) &&
ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0)) {
ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!o->dial_callerid_absent) {
@ -5352,7 +5335,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
ast_party_number_init(&ast_channel_redirecting(o->chan)->from.number);
ast_channel_redirecting(o->chan)->from.number.valid = 1;
ast_channel_redirecting(o->chan)->from.number.str =
ast_strdup(S_OR(ast_channel_macroexten(in), ast_channel_exten(in)));
ast_strdup(ast_channel_exten(in));
}
ast_channel_dialed(o->chan)->transit_network_select = ast_channel_dialed(in)->transit_network_select;
@ -5371,17 +5354,13 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
* Redirecting updates to the caller make sense only on single
* call at a time strategies.
*
* We must unlock o->chan before calling
* ast_channel_redirecting_macro, because we put o->chan into
* autoservice there. That is pretty much a guaranteed
* deadlock. This is why the handling of o->chan's lock may
* seem a bit unusual here.
* Need to re-evaluate if calling unlock is still required as we no longer
* use macro.
*/
ast_party_redirecting_init(&redirecting);
ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(o->chan));
ast_channel_unlock(o->chan);
if (ast_channel_redirecting_sub(o->chan, in, &redirecting, 0) &&
ast_channel_redirecting_macro(o->chan, in, &redirecting, 1, 0)) {
if (ast_channel_redirecting_sub(o->chan, in, &redirecting, 0)) {
ast_channel_update_redirecting(in, &redirecting, NULL);
}
ast_party_redirecting_free(&redirecting);
@ -5430,8 +5409,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
update_connected_line_from_peer(in, o->chan, 1);
} else if (!o->block_connected_update) {
if (o->pending_connected_update) {
if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0) &&
ast_channel_connected_line_macro(o->chan, in, &o->connected, 1, 0)) {
if (ast_channel_connected_line_sub(o->chan, in, &o->connected, 0)) {
ast_channel_update_connected_line(in, &o->connected, NULL);
}
} else if (!o->dial_callerid_absent) {
@ -5523,8 +5501,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
*/
o->dial_callerid_absent = 1;
if (ast_channel_connected_line_sub(o->chan, in, f, 1) &&
ast_channel_connected_line_macro(o->chan, in, f, 1, 1)) {
if (ast_channel_connected_line_sub(o->chan, in, f, 1)) {
ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
}
break;
@ -5554,8 +5531,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
}
ast_verb(3, "%s redirecting info has changed, passing it to %s\n",
ochan_name, inchan_name);
if (ast_channel_redirecting_sub(o->chan, in, f, 1) &&
ast_channel_redirecting_macro(o->chan, in, f, 1, 1)) {
if (ast_channel_redirecting_sub(o->chan, in, f, 1)) {
ast_indicate_data(in, AST_CONTROL_REDIRECTING, f->data.ptr, f->datalen);
}
break;
@ -5636,8 +5612,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
ast_verb(3, "Connected line update to %s prevented.\n", ast_channel_name(o->chan));
break;
}
if (ast_channel_connected_line_sub(in, o->chan, f, 1) &&
ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
if (ast_channel_connected_line_sub(in, o->chan, f, 1)) {
ast_indicate_data(o->chan, f->subclass.integer, f->data.ptr, f->datalen);
}
break;
@ -5646,8 +5621,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
ast_verb(3, "Redirecting update to %s prevented.\n", ast_channel_name(o->chan));
break;
}
if (ast_channel_redirecting_sub(in, o->chan, f, 1) &&
ast_channel_redirecting_macro(in, o->chan, f, 0, 1)) {
if (ast_channel_redirecting_sub(in, o->chan, f, 1)) {
ast_indicate_data(o->chan, f->subclass.integer, f->data.ptr, f->datalen);
}
break;
@ -6921,11 +6895,10 @@ static void setup_mixmonitor(struct queue_ent *qe, const char *filename)
* \param[in,out] tries the number of times we have tried calling queue members
* \param[out] noption set if the call to Queue() has the 'n' option set.
* \param[in] agi the agi passed as the fifth parameter to the Queue() application
* \param[in] macro the macro passed as the sixth parameter to the Queue() application
* \param[in] gosub the gosub passed as the seventh parameter to the Queue() application
* \param[in] ringing 1 if the 'r' option is set, otherwise 0
*/
static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_args, char *announceoverride, const char *url, int *tries, int *noption, const char *agi, const char *macro, const char *gosub, int ringing)
static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_args, char *announceoverride, const char *url, int *tries, int *noption, const char *agi, const char *gosub, int ringing)
{
struct member *cur;
struct callattempt *outgoing = NULL; /* the list of calls we are building */
@ -6947,7 +6920,6 @@ static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_a
struct ast_bridge_config bridge_config;
char nondataquality = 1;
char *agiexec = NULL;
char *macroexec = NULL;
char *gosubexec = NULL;
const char *monitorfilename;
char tmpid[256];
@ -7314,21 +7286,6 @@ static int try_calling(struct queue_ent *qe, struct ast_flags opts, char **opt_a
ast_channel_sendurl(peer, url);
}
/* run a macro for this connection if defined. The macro simply returns, no action is taken on the result */
/* use macro from dialplan if passed as a option, otherwise use the default queue macro */
if (!ast_strlen_zero(macro)) {
macroexec = ast_strdupa(macro);
} else {
if (qe->parent->membermacro) {
macroexec = ast_strdupa(qe->parent->membermacro);
}
}
if (!ast_strlen_zero(macroexec)) {
ast_debug(1, "app_queue: macro=%s.\n", macroexec);
ast_app_exec_macro(qe->chan, peer, macroexec);
}
/* run a gosub for this connection if defined. The gosub simply returns, no action is taken on the result */
/* use gosub from dialplan if passed as a option, otherwise use the default queue gosub */
if (!ast_strlen_zero(gosub)) {
@ -8463,7 +8420,6 @@ static int queue_exec(struct ast_channel *chan, const char *data)
AST_APP_ARG(announceoverride);
AST_APP_ARG(queuetimeoutstr);
AST_APP_ARG(agi);
AST_APP_ARG(macro);
AST_APP_ARG(gosub);
AST_APP_ARG(rule);
AST_APP_ARG(position);
@ -8475,7 +8431,7 @@ static int queue_exec(struct ast_channel *chan, const char *data)
int max_forwards;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,macro[,gosub[,rule[,position]]]]]]]]]\n");
ast_log(LOG_WARNING, "Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,gosub[,rule[,position]]]]]]]]\n");
return -1;
}
@ -8491,14 +8447,13 @@ static int queue_exec(struct ast_channel *chan, const char *data)
parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
ast_debug(1, "queue: %s, options: %s, url: %s, announce: %s, timeout: %s, agi: %s, macro: %s, gosub: %s, rule: %s, position: %s\n",
ast_debug(1, "queue: %s, options: %s, url: %s, announce: %s, timeout: %s, agi: %s, gosub: %s, rule: %s, position: %s\n",
args.queuename,
S_OR(args.options, ""),
S_OR(args.url, ""),
S_OR(args.announceoverride, ""),
S_OR(args.queuetimeoutstr, ""),
S_OR(args.agi, ""),
S_OR(args.macro, ""),
S_OR(args.gosub, ""),
S_OR(args.rule, ""),
S_OR(args.position, ""));
@ -8719,7 +8674,7 @@ check_turns:
}
/* Try calling all queue members for 'timeout' seconds */
res = try_calling(&qe, opts, opt_args, args.announceoverride, args.url, &tries, &noption, args.agi, args.macro, args.gosub, ringing);
res = try_calling(&qe, opts, opt_args, args.announceoverride, args.url, &tries, &noption, args.agi, args.gosub, ringing);
if (res) {
goto stop;
}

View File

@ -58,7 +58,6 @@
</description>
<see-also>
<ref type="application">GosubIf</ref>
<ref type="application">Macro</ref>
<ref type="application">Goto</ref>
<ref type="application">Return</ref>
<ref type="application">StackPop</ref>
@ -93,7 +92,6 @@
<see-also>
<ref type="application">Gosub</ref>
<ref type="application">Return</ref>
<ref type="application">MacroIf</ref>
<ref type="function">IF</ref>
<ref type="application">GotoIf</ref>
<ref type="application">Goto</ref>

View File

@ -4227,7 +4227,7 @@ static void copy_file(char *sdir, int smsg, char *ddir, int dmsg, char *dmailbox
snprintf(msgnums, sizeof(msgnums), "%d", smsg);
snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);
snprintf(sql, sizeof(sql), "INSERT INTO %s (dir, msgnum, msg_id, context, macrocontext, callerid, origtime, duration, recording, flag, mailboxuser, mailboxcontext) SELECT ?,?,?,context,macrocontext,callerid,origtime,duration,recording,flag,?,? FROM %s WHERE dir=? AND msgnum=?", odbc_table, odbc_table);
snprintf(sql, sizeof(sql), "INSERT INTO %s (dir, msgnum, msg_id, context, callerid, origtime, duration, recording, flag, mailboxuser, mailboxcontext) SELECT ?,?,?,context,callerid,origtime,duration,recording,flag,?,? FROM %s WHERE dir=? AND msgnum=?", odbc_table, odbc_table);
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
if (!stmt)
ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql);
@ -4246,7 +4246,6 @@ struct insert_data {
SQLLEN datalen;
SQLLEN indlen;
const char *context;
const char *macrocontext;
const char *callerid;
const char *origtime;
const char *duration;
@ -4273,7 +4272,6 @@ static SQLHSTMT insert_data_cb(struct odbc_obj *obj, void *vdata)
SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->msgnums), 0, (void *) data->msgnums, 0, NULL);
SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, data->datalen, 0, (void *) data->data, data->datalen, &data->indlen);
SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->context), 0, (void *) data->context, 0, NULL);
SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->macrocontext), 0, (void *) data->macrocontext, 0, NULL);
SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->callerid), 0, (void *) data->callerid, 0, NULL);
SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->origtime), 0, (void *) data->origtime, 0, NULL);
SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->duration), 0, (void *) data->duration, 0, NULL);
@ -4323,7 +4321,7 @@ static int store_file(const char *dir, const char *mailboxuser, const char *mail
struct ast_config *cfg = NULL;
struct odbc_obj *obj;
struct insert_data idata = { .sql = sql, .msgnums = msgnums, .dir = dir, .mailboxuser = mailboxuser, .mailboxcontext = mailboxcontext,
.context = "", .macrocontext = "", .callerid = "", .origtime = "", .duration = "", .category = "", .flag = "", .msg_id = "" };
.context = "", .callerid = "", .origtime = "", .duration = "", .category = "", .flag = "", .msg_id = "" };
struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
delete_file(dir, msgnum);
@ -4359,9 +4357,6 @@ static int store_file(const char *dir, const char *mailboxuser, const char *mail
if (!(idata.context = ast_variable_retrieve(cfg, "message", "context"))) {
idata.context = "";
}
if (!(idata.macrocontext = ast_variable_retrieve(cfg, "message", "macrocontext"))) {
idata.macrocontext = "";
}
if (!(idata.callerid = ast_variable_retrieve(cfg, "message", "callerid"))) {
idata.callerid = "";
}
@ -4397,9 +4392,9 @@ static int store_file(const char *dir, const char *mailboxuser, const char *mail
idata.datalen = idata.indlen = fdlen;
if (!ast_strlen_zero(idata.category))
snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,msg_id,category) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", odbc_table);
snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,msg_id,category) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", odbc_table);
else
snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,msg_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", odbc_table);
snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,msg_id) VALUES (?,?,?,?,?,?,?,?,?,?,?)", odbc_table);
if (ast_strlen_zero(idata.origtime)) {
idata.origtime = "0";
@ -4684,7 +4679,7 @@ static void copy_plain_file(char *frompath, char *topath)
{
char frompath2[PATH_MAX], topath2[PATH_MAX];
struct ast_variable *tmp, *var = NULL;
const char *origmailbox = "", *context = "", *macrocontext = "", *exten = "";
const char *origmailbox = "", *context = "", *exten = "";
const char *priority = "", *callerchan = "", *callerid = "", *origdate = "";
const char *origtime = "", *category = "", *duration = "";
@ -4700,8 +4695,6 @@ static void copy_plain_file(char *frompath, char *topath)
origmailbox = tmp->value;
} else if (!strcasecmp(tmp->name, "context")) {
context = tmp->value;
} else if (!strcasecmp(tmp->name, "macrocontext")) {
macrocontext = tmp->value;
} else if (!strcasecmp(tmp->name, "exten")) {
exten = tmp->value;
} else if (!strcasecmp(tmp->name, "priority")) {
@ -4720,7 +4713,7 @@ static void copy_plain_file(char *frompath, char *topath)
duration = tmp->value;
}
}
ast_store_realtime("voicemail_data", "filename", topath, "origmailbox", origmailbox, "context", context, "macrocontext", macrocontext, "exten", exten, "priority", priority, "callerchan", callerchan, "callerid", callerid, "origdate", origdate, "origtime", origtime, "category", category, "duration", duration, SENTINEL);
ast_store_realtime("voicemail_data", "filename", topath, "origmailbox", origmailbox, "context", context, "exten", exten, "priority", priority, "callerchan", callerchan, "callerid", callerid, "origdate", origdate, "origtime", origtime, "category", category, "duration", duration, SENTINEL);
}
copy(frompath2, topath2);
ast_variables_destroy(var);
@ -6271,7 +6264,6 @@ static int msg_create_from_file(struct ast_vm_recording_data *recdata)
"[message]\n"
"origmailbox=%s\n"
"context=%s\n"
"macrocontext=%s\n"
"exten=%s\n"
"rdnis=Unknown\n"
"priority=%d\n"
@ -6286,7 +6278,6 @@ static int msg_create_from_file(struct ast_vm_recording_data *recdata)
recdata->mailbox,
S_OR(recdata->call_context, ""),
S_OR(recdata->call_macrocontext, ""),
S_OR(recdata->call_extension, ""),
recdata->call_priority,
S_OR(recdata->call_callerchan, "Unknown"),
@ -6433,7 +6424,6 @@ static int msg_create_from_file(struct ast_vm_recording_data *recdata)
ast_store_realtime("voicemail_data",
"origmailbox", recdata->mailbox,
"context", S_OR(recdata->context, ""),
"macrocontext", S_OR(recdata->call_macrocontext, ""),
"exten", S_OR(recdata->call_extension, ""),
"priority", recdata->call_priority,
"callerchan", S_OR(recdata->call_callerchan, "Unknown"),
@ -6501,8 +6491,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
int msgnum;
int duration = 0;
int sound_duration = 0;
int ausemacro = 0;
int ousemacro = 0;
int ouseexten = 0;
int greeting_only = 0;
char tmpdur[16];
@ -6613,7 +6601,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
}
#endif
/* Check current or macro-calling context for special extensions */
/* Check current context for special extensions */
if (ast_test_flag(vmu, VM_OPERATOR)) {
if (!ast_strlen_zero(vmu->exit)) {
if (ast_exists_extension(chan, vmu->exit, "o", 1,
@ -6625,11 +6613,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
} else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
&& ast_exists_extension(chan, ast_channel_macrocontext(chan), "o", 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ousemacro = 1;
}
}
@ -6641,11 +6624,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
} else if (ast_exists_extension(chan, ast_channel_context(chan), "a", 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
} else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
&& ast_exists_extension(chan, ast_channel_macrocontext(chan), "a", 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
ausemacro = 1;
}
if (ast_test_flag(options, OPT_DTMFEXIT)) {
@ -6716,8 +6694,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
ast_channel_exten_set(chan, "a");
if (!ast_strlen_zero(vmu->exit)) {
ast_channel_context_set(chan, vmu->exit);
} else if (ausemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
ast_channel_context_set(chan, ast_channel_macrocontext(chan));
}
ast_channel_priority_set(chan, 0);
free_user(vmu);
@ -6729,12 +6705,10 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
/* Check for a '0' here */
if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') {
transfer:
if (ouseexten || ousemacro) {
if (ouseexten) {
ast_channel_exten_set(chan, "o");
if (!ast_strlen_zero(vmu->exit)) {
ast_channel_context_set(chan, vmu->exit);
} else if (ousemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
ast_channel_context_set(chan, ast_channel_macrocontext(chan));
}
ast_play_and_wait(chan, "transfer");
ast_channel_priority_set(chan, 0);
@ -6858,7 +6832,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
ast_store_realtime("voicemail_data",
"origmailbox", ext,
"context", ast_channel_context(chan),
"macrocontext", ast_channel_macrocontext(chan),
"exten", ast_channel_exten(chan),
"priority", priority,
"callerchan", ast_channel_name(chan),
@ -6886,7 +6859,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
"[message]\n"
"origmailbox=%s\n"
"context=%s\n"
"macrocontext=%s\n"
"exten=%s\n"
"rdnis=%s\n"
"priority=%d\n"
@ -6898,7 +6870,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
"msg_id=%s\n",
ext,
ast_channel_context(chan),
ast_channel_macrocontext(chan),
ast_channel_exten(chan),
S_COR(ast_channel_redirecting(chan)->from.number.valid,
ast_channel_redirecting(chan)->from.number.str, "unknown"),
@ -8854,8 +8825,6 @@ static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struc
category = ast_variable_retrieve(msg_cfg, "message", "category");
context = ast_variable_retrieve(msg_cfg, "message", "context");
if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
if (!res) {
res = play_message_category(chan, category);
}
@ -15289,8 +15258,6 @@ static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, s
cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
context = ast_variable_retrieve(msg_cfg, "message", "context");
if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
switch (option) {
case 3: /* Play message envelope */
if (!res) {

View File

@ -1777,7 +1777,7 @@ static void my_handle_dtmf(void *pvt, struct ast_channel *ast, enum analog_sub a
ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
}
if (strcmp(ast_channel_exten(ast), "fax")) {
const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
const char *target_context = ast_channel_context(ast);
/*
* We need to unlock 'ast' here because ast_exists_extension has the
@ -7433,7 +7433,7 @@ static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame
ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
}
if (strcmp(ast_channel_exten(ast), "fax")) {
const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
const char *target_context = ast_channel_context(ast);
/*
* We need to unlock 'ast' here because ast_exists_extension has the

View File

@ -776,7 +776,7 @@ static struct ast_frame *chan_pjsip_cng_tone_detected(struct ast_channel *ast, s
return f;
}
target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
target_context = ast_channel_context(ast);
/*
* We need to unlock the channel here because ast_exists_extension has the

View File

@ -89,8 +89,6 @@ documentation_language = en_US ; Set the language you want documentation
; configuration files (/etc/asterisk) with a
; lock.
;stdexten = gosub ; How to invoke the extensions.conf stdexten.
; macro - Invoke the stdexten using a macro as
; done by legacy Asterisk versions.
; gosub - Invoke the stdexten using a gosub as
; documented in extensions.conf.sample.
; Default gosub.

View File

@ -181,15 +181,10 @@
;
; When using a generic CC agent, the caller who requested CC will be
; called back when a called party becomes available. When the caller
; answers his phone, the administrator may opt to have a macro run.
; What this macro does is up to the administrator. By default there
; is no callback macro configured.
;
;cc_callback_macro=
;
; Alternatively, the administrator may run a subroutine. By default
; there is no callback subroutine configured. The subroutine should
; be specified in the format: [[context,]exten,]priority
; answers his phone, the administrator may opt to have a subroutine
; run. By default there is no callback subroutine configured. The
; subroutine should be specified in the format:
; [[context,]exten,]priority
;
;cc_callback_sub=
;

View File

@ -175,18 +175,6 @@ context ael-dundi-e164-lookup {
//
};
//
// DUNDi can also be implemented as a Macro instead of using
// the Local channel driver.
//
macro ael-dundi-e164(exten) {
//
// ARG1 is the extension to Dial
//
goto ${exten}|1;
return;
};
//
// Here are the entries you need to participate in the IAXTEL
// call routing system. Most IAXTEL numbers begin with 1-700, but
@ -313,22 +301,6 @@ context ael-local {
// eswitch => IAX2/context@${CURSERVER}
macro ael-std-exten-ael( ext , dev ) {
Dial(${dev}/${ext},20);
switch(${DIALSTATUS}) {
case BUSY:
Voicemail(${ext},b);
break;
default:
Voicemail(${ext},u);
};
catch a {
VoiceMailMain(${ext});
return;
};
return;
};
context ael-demo {
s => {
Wait(1);

View File

@ -290,8 +290,7 @@ include => dundi-e164-switch
; ARG1 is the extension to Dial
;
; Extension "s" is not a wildcard extension that matches "anything".
; In macros, it is the start extension. In most other cases,
; you have to goto "s" to execute that extension.
; In most other cases, you have to goto "s" to execute that extension.
;
; Note: In old versions of Asterisk the PBX in some cases defaulted to
; extension "s" when a given extension was wrong (like in AMI originate).

View File

@ -4,6 +4,9 @@
; This is an example on how to use the Mini-Voicemail system to build
; voicemail systems.
;
; This example remains for now despite using macro, with the idea that if anyone is still
; using this sample, they can be encouraged to re-write it using gosub.
;
;.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
; A macro to test the MINIVMACCOUNT dialplan function
; Currently, accountcode and pincode is not used in the application

View File

@ -95,8 +95,8 @@
; by the PBX core. In this case, these applications are executed outside of the
; PBX core, so it does *not* make sense to use any application which has any
; concept of dialplan flow. Examples of this would be things like Goto,
; Background, WaitExten, and many more. The exceptions to this are Gosub and
; Macro routines which must complete for the call to continue.
; Background, WaitExten, and many more. The exceptions to this are Gosub
; routines which must complete for the call to continue.
;
; Enabling these features means that the PBX needs to stay in the media flow and
; media will not be re-directed if DTMF is sent in the media stream.

View File

@ -34,7 +34,7 @@ format=wav49
;
;Turn on logfile with the following syntax. One line per voicemail received
;with minivmRecord()
; Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode
; Mailbox:domain:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode
;logfile=/var/log/asterisk/minivm.log
; Who the e-mail notification should appear to come from
serveremail=asterisk

View File

@ -254,12 +254,6 @@ monitor-type = MixMonitor
;
;setqueuevar=no
; if set, run this macro when connected to the queue member
; you can override this macro by setting the macro option on
; the queue application
;
;membermacro=macro_name[,arg1[,...][,argN]]
; if set, run this gosub when connected to the queue member
; you can override this gosub by setting the gosub option on
; the queue application

View File

@ -22,7 +22,7 @@ fullname = New User
;
userbase = 6000
;
; Create voicemail mailbox and use use macro-stdexten
; Create voicemail mailbox
;
hasvoicemail = yes
;

View File

@ -0,0 +1,37 @@
Subject: app_macro
Master-Only: True
This module was deprecated in Asterisk 16
and is now being removed in accordance with
the Asterisk Module Deprecation policy.
For most modules that interacted with app_macro,
this change is limited to no longer looking for
the current context from the macrocontext when set.
The following modules have additional impacts:
app_dial - no longer supports M^ connected/redirecting macro
app_minivm - samples written using macro will no longer work.
The sample needs to be re-written
app_queue - can no longer call a macro on the called party's
channel. Use gosub which is currently supported
ccss - no callback macro, gosub only
app_voicemail - no macro support
channel - remove macrocontext and priority, no connected
line or redirection macro options
options - stdexten is deprecated to gosub as the default
and only options
pbx - removed macrolock
pbx_dundi - no longer look for macro
snmp - removed macro context, exten, and priority

View File

@ -49,7 +49,6 @@
<enum name="cc_recall_timer" />
<enum name="cc_max_agents" />
<enum name="cc_max_monitors" />
<enum name="cc_callback_macro" />
<enum name="cc_agent_dialstring" />
</enumlist>
</parameter>

View File

@ -95,9 +95,7 @@ struct ast_vm_recording_data {
AST_STRING_FIELD(folder);
AST_STRING_FIELD(recording_file);
AST_STRING_FIELD(recording_ext);
AST_STRING_FIELD(call_context);
AST_STRING_FIELD(call_macrocontext);
AST_STRING_FIELD(call_extension);
AST_STRING_FIELD(call_callerchan);
AST_STRING_FIELD(call_callerid);
@ -161,50 +159,6 @@ int ast_app_getdata_terminator(struct ast_channel *c, const char *prompt, char *
/*! \brief Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions */
int ast_app_getdata_full(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd);
/*!
* \brief Run a macro on a channel, placing an optional second channel into autoservice.
* \since 11.0
*
* \details
* This is a shorthand method that makes it very easy to run a
* macro on any given channel. It is perfectly reasonable to
* supply a NULL autoservice_chan here in case there is no
* channel to place into autoservice.
*
* \note Absolutely _NO_ channel locks should be held before calling this function.
*
* \param autoservice_chan A channel to place into autoservice while the macro is run
* \param macro_chan Channel to execute macro on.
* \param macro_args Macro application argument string.
*
* \retval 0 success
* \retval -1 on error
*/
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args);
/*!
* \since 1.8
* \brief Run a macro on a channel, placing an optional second channel into autoservice.
*
* \details
* This is a shorthand method that makes it very easy to run a
* macro on any given channel. It is perfectly reasonable to
* supply a NULL autoservice_chan here in case there is no
* channel to place into autoservice.
*
* \note Absolutely _NO_ channel locks should be held before calling this function.
*
* \param autoservice_chan A channel to place into autoservice while the macro is run
* \param macro_chan Channel to execute macro on.
* \param macro_name The name of the macro to run.
* \param macro_args The arguments to pass to the macro.
*
* \retval 0 success
* \retval -1 on error
*/
int ast_app_run_macro(struct ast_channel *autoservice_chan,
struct ast_channel *macro_chan, const char *macro_name, const char *macro_args);
/*!
* \brief Stack applications callback functions.
*/

View File

@ -362,22 +362,6 @@ unsigned int ast_get_cc_max_monitors(struct ast_cc_config_params *config);
*/
void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int value);
/*!
* \since 1.8
* \brief Get the name of the callback_macro
* \param config The configuration to retrieve the callback_macro from
* \return The callback_macro name
*/
const char *ast_get_cc_callback_macro(struct ast_cc_config_params *config);
/*!
* \since 1.8
* \brief Set the callback_macro name
* \param config The configuration to set the callback_macro on
* \param value The new callback macro we want to change to
*/
void ast_set_cc_callback_macro(struct ast_cc_config_params *config, const char * const value);
/*!
* \since 11
* \brief Get the name of the callback subroutine

View File

@ -3847,37 +3847,6 @@ void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_p
*/
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
/*!
* \since 1.8
* \brief Run a connected line interception macro and update a channel's connected line
* information
* \deprecated You should use the ast_channel_connected_line_sub() function instead.
*
* Whenever we want to update a channel's connected line information, we may need to run
* a macro so that an administrator can manipulate the information before sending it
* out. This function both runs the macro and sends the update to the channel.
*
* \param autoservice_chan Channel to place into autoservice while the macro is running.
* It is perfectly safe for this to be NULL
* \param macro_chan The channel to run the macro on. Also the channel from which we
* determine which macro we need to run.
* \param connected_info Either an ast_party_connected_line or ast_frame pointer of type
* AST_CONTROL_CONNECTED_LINE
* \param is_caller If true, then run CONNECTED_LINE_CALLER_SEND_MACRO with arguments from
* CONNECTED_LINE_CALLER_SEND_MACRO_ARGS, otherwise run CONNECTED_LINE_CALLEE_SEND_MACRO
* with arguments from CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS
* \param frame If true, then connected_info is an ast_frame pointer, otherwise it is an
* ast_party_connected_line pointer.
* \retval 0 Success
* \retval -1 Either the macro does not exist, or there was an error while attempting to
* run the macro
*
* \todo Have multiple return codes based on the MACRO_RESULT
* \todo Make constants so that caller and frame can be more expressive than just '1' and
* '0'
*/
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame);
/*!
* \since 11
* \brief Run a connected line interception subroutine and update a channel's connected line
@ -3902,38 +3871,6 @@ int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struc
*/
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame);
/*!
* \since 1.8
* \brief Run a redirecting interception macro and update a channel's redirecting information
* \deprecated You should use the ast_channel_redirecting_sub() function instead.
*
* \details
* Whenever we want to update a channel's redirecting information, we may need to run
* a macro so that an administrator can manipulate the information before sending it
* out. This function both runs the macro and sends the update to the channel.
*
* \param autoservice_chan Channel to place into autoservice while the macro is running.
* It is perfectly safe for this to be NULL
* \param macro_chan The channel to run the macro on. Also the channel from which we
* determine which macro we need to run.
* \param redirecting_info Either an ast_party_redirecting or ast_frame pointer of type
* AST_CONTROL_REDIRECTING
* \param is_caller If true, then run REDIRECTING_CALLER_SEND_MACRO with arguments from
* REDIRECTING_CALLER_SEND_MACRO_ARGS, otherwise run REDIRECTING_CALLEE_SEND_MACRO with
* arguments from REDIRECTING_CALLEE_SEND_MACRO_ARGS
* \param is_frame If true, then redirecting_info is an ast_frame pointer, otherwise it is an
* ast_party_redirecting pointer.
*
* \retval 0 Success
* \retval -1 Either the macro does not exist, or there was an error while attempting to
* run the macro
*
* \todo Have multiple return codes based on the MACRO_RESULT
* \todo Make constants so that caller and frame can be more expressive than just '1' and
* '0'
*/
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame);
/*!
* \since 11
* \brief Run a redirecting interception subroutine and update a channel's redirecting information
@ -4168,10 +4105,6 @@ void ast_channel_context_set(struct ast_channel *chan, const char *value);
const char *ast_channel_lastexten(const struct ast_channel *chan);
const char *ast_channel_exten(const struct ast_channel *chan);
void ast_channel_exten_set(struct ast_channel *chan, const char *value);
const char *ast_channel_macrocontext(const struct ast_channel *chan);
void ast_channel_macrocontext_set(struct ast_channel *chan, const char *value);
const char *ast_channel_macroexten(const struct ast_channel *chan);
void ast_channel_macroexten_set(struct ast_channel *chan, const char *value);
char ast_channel_dtmf_digit_to_emulate(const struct ast_channel *chan);
void ast_channel_dtmf_digit_to_emulate_set(struct ast_channel *chan, char value);
@ -4191,8 +4124,6 @@ int ast_channel_fdno(const struct ast_channel *chan);
void ast_channel_fdno_set(struct ast_channel *chan, int value);
int ast_channel_hangupcause(const struct ast_channel *chan);
void ast_channel_hangupcause_set(struct ast_channel *chan, int value);
int ast_channel_macropriority(const struct ast_channel *chan);
void ast_channel_macropriority_set(struct ast_channel *chan, int value);
int ast_channel_priority(const struct ast_channel *chan);
void ast_channel_priority_set(struct ast_channel *chan, int value);
int ast_channel_rings(const struct ast_channel *chan);

View File

@ -157,7 +157,6 @@ struct ast_context {
struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
const char *registrar; /*!< Registrar */
AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
char name[0]; /*!< Name of the context */
};

View File

@ -114,8 +114,6 @@ enum ast_option_flags {
#define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
#define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
#define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
/*! Invoke the stdexten using the legacy macro method. */
#define ast_opt_stdexten_macro ast_test_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO)
#define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
#define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
#define ast_opt_cache_media_frames ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_MEDIA_FRAMES)

View File

@ -1123,30 +1123,6 @@ int ast_rdlock_context(struct ast_context *con);
*/
int ast_unlock_context(struct ast_context *con);
/*!
* \brief locks the macrolock in the given context
*
* \param macrocontext name of the macro-context to lock
*
* Locks the given macro-context to ensure only one thread (call) can execute it at a time
*
* \retval 0 on success
* \retval -1 on failure
*/
int ast_context_lockmacro(const char *macrocontext);
/*!
* \brief Unlocks the macrolock in the given context
*
* \param macrocontext name of the macro-context to unlock
*
* Unlocks the given macro-context so that another thread (call) can execute it
*
* \retval 0 on success
* \retval -1 on failure
*/
int ast_context_unlockmacro(const char *macrocontext);
/*!
* \brief Set the channel to next execute the specified dialplan location.
* \see ast_async_parseable_goto, ast_async_goto_if_exists

View File

@ -267,76 +267,6 @@ int ast_app_getdata_full(struct ast_channel *c, const char *prompt, char *s, int
return res;
}
int ast_app_exec_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_args)
{
struct ast_app *macro_app;
int res;
macro_app = pbx_findapp("Macro");
if (!macro_app) {
ast_log(LOG_WARNING,
"Cannot run 'Macro(%s)'. The application is not available.\n", macro_args);
return -1;
}
if (autoservice_chan) {
ast_autoservice_start(autoservice_chan);
}
ast_debug(4, "%s Original location: %s,%s,%d\n", ast_channel_name(macro_chan),
ast_channel_context(macro_chan), ast_channel_exten(macro_chan),
ast_channel_priority(macro_chan));
res = pbx_exec(macro_chan, macro_app, macro_args);
ast_debug(4, "Macro exited with status %d\n", res);
/*
* Assume anything negative from Macro is an error.
* Anything else is success.
*/
if (res < 0) {
res = -1;
} else {
res = 0;
}
ast_debug(4, "%s Ending location: %s,%s,%d\n", ast_channel_name(macro_chan),
ast_channel_context(macro_chan), ast_channel_exten(macro_chan),
ast_channel_priority(macro_chan));
if (autoservice_chan) {
ast_autoservice_stop(autoservice_chan);
}
if (ast_check_hangup_locked(macro_chan)) {
ast_queue_hangup(macro_chan);
}
return res;
}
int ast_app_run_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const char *macro_name, const char *macro_args)
{
int res;
char *args_str;
size_t args_len;
if (ast_strlen_zero(macro_args)) {
return ast_app_exec_macro(autoservice_chan, macro_chan, macro_name);
}
/* Create the Macro application argument string. */
args_len = strlen(macro_name) + strlen(macro_args) + 2;
args_str = ast_malloc(args_len);
if (!args_str) {
return -1;
}
snprintf(args_str, args_len, "%s,%s", macro_name, macro_args);
res = ast_app_exec_macro(autoservice_chan, macro_chan, args_str);
ast_free(args_str);
return res;
}
/* BUGBUG this is not thread safe. */
static const struct ast_app_stack_funcs *app_stack_callbacks;

View File

@ -1386,10 +1386,6 @@ static const char *get_transfer_context(struct ast_channel *transferer, const ch
if (!ast_strlen_zero(context)) {
return context;
}
context = ast_channel_macrocontext(transferer);
if (!ast_strlen_zero(context)) {
return context;
}
context = ast_channel_context(transferer);
if (!ast_strlen_zero(context)) {
return context;

View File

@ -1175,8 +1175,6 @@ static int run_app_helper(struct ast_channel *chan, const char *app_name, const
if (!strcasecmp("Gosub", app_name)) {
ast_app_exec_sub(NULL, chan, app_args, 0);
} else if (!strcasecmp("Macro", app_name)) {
ast_app_exec_macro(NULL, chan, app_args);
} else {
res = ast_pbx_exec_application(chan, app_name, app_args);
}
@ -2263,21 +2261,16 @@ static void bridge_channel_handle_control(struct ast_bridge_channel *bridge_chan
{
struct ast_channel *chan;
struct ast_option_header *aoh;
int is_caller;
chan = bridge_channel->chan;
switch (fr->subclass.integer) {
case AST_CONTROL_REDIRECTING:
is_caller = !ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
if (ast_channel_redirecting_sub(NULL, chan, fr, 1) &&
ast_channel_redirecting_macro(NULL, chan, fr, is_caller, 1)) {
if (ast_channel_redirecting_sub(NULL, chan, fr, 1)) {
ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
}
break;
case AST_CONTROL_CONNECTED_LINE:
is_caller = !ast_test_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING);
if (ast_channel_connected_line_sub(NULL, chan, fr, 1) &&
ast_channel_connected_line_macro(NULL, chan, fr, is_caller, 1)) {
if (ast_channel_connected_line_sub(NULL, chan, fr, 1)) {
ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
}
break;

View File

@ -167,7 +167,6 @@ struct ast_cc_config_params {
unsigned int cc_recall_timer;
unsigned int cc_max_agents;
unsigned int cc_max_monitors;
char cc_callback_macro[AST_MAX_EXTENSION];
char cc_callback_sub[AST_MAX_EXTENSION];
char cc_agent_dialstring[AST_MAX_EXTENSION];
};
@ -669,7 +668,6 @@ static const struct ast_cc_config_params cc_default_params = {
.cc_recall_timer = CC_RECALL_TIMER_DEFAULT,
.cc_max_agents = CC_MAX_AGENTS_DEFAULT,
.cc_max_monitors = CC_MAX_MONITORS_DEFAULT,
.cc_callback_macro = "",
.cc_callback_sub = "",
.cc_agent_dialstring = "",
};
@ -762,9 +760,7 @@ int ast_cc_get_param(struct ast_cc_config_params *params, const char * const nam
{
const char *value = NULL;
if (!strcasecmp(name, "cc_callback_macro")) {
value = ast_get_cc_callback_macro(params);
} else if (!strcasecmp(name, "cc_callback_sub")) {
if (!strcasecmp(name, "cc_callback_sub")) {
value = ast_get_cc_callback_sub(params);
} else if (!strcasecmp(name, "cc_agent_policy")) {
value = agent_policy_to_str(ast_get_cc_agent_policy(params));
@ -812,9 +808,6 @@ int ast_cc_set_param(struct ast_cc_config_params *params, const char * const nam
return ast_set_cc_monitor_policy(params, str_to_monitor_policy(value));
} else if (!strcasecmp(name, "cc_agent_dialstring")) {
ast_set_cc_agent_dialstring(params, value);
} else if (!strcasecmp(name, "cc_callback_macro")) {
ast_set_cc_callback_macro(params, value);
return 0;
} else if (!strcasecmp(name, "cc_callback_sub")) {
ast_set_cc_callback_sub(params, value);
return 0;
@ -853,7 +846,6 @@ int ast_cc_is_config_param(const char * const name)
!strcasecmp(name, "ccbs_available_timer") ||
!strcasecmp(name, "cc_max_agents") ||
!strcasecmp(name, "cc_max_monitors") ||
!strcasecmp(name, "cc_callback_macro") ||
!strcasecmp(name, "cc_callback_sub") ||
!strcasecmp(name, "cc_agent_dialstring") ||
!strcasecmp(name, "cc_recall_timer"));
@ -992,26 +984,11 @@ void ast_set_cc_max_monitors(struct ast_cc_config_params *config, unsigned int v
config->cc_max_monitors = value;
}
const char *ast_get_cc_callback_macro(struct ast_cc_config_params *config)
{
return config->cc_callback_macro;
}
const char *ast_get_cc_callback_sub(struct ast_cc_config_params *config)
{
return config->cc_callback_sub;
}
void ast_set_cc_callback_macro(struct ast_cc_config_params *config, const char * const value)
{
ast_log(LOG_WARNING, "Usage of cc_callback_macro is deprecated. Please use cc_callback_sub instead.\n");
if (ast_strlen_zero(value)) {
config->cc_callback_macro[0] = '\0';
} else {
ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro));
}
}
void ast_set_cc_callback_sub(struct ast_cc_config_params *config, const char * const value)
{
if (ast_strlen_zero(value)) {
@ -2156,7 +2133,7 @@ static int cc_interfaces_datastore_init(struct ast_channel *chan) {
return -1;
}
if (!(monitor = cc_extension_monitor_init(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)), S_OR(ast_channel_macrocontext(chan), ast_channel_context(chan)), 0))) {
if (!(monitor = cc_extension_monitor_init(ast_channel_exten(chan), ast_channel_context(chan), 0))) {
ast_free(interfaces);
return -1;
}
@ -2465,8 +2442,9 @@ int ast_cc_call_init(struct ast_channel *chan, int *ignore_cc)
}
/* Situation 2 has occurred */
if (!(monitor = cc_extension_monitor_init(S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)),
S_OR(ast_channel_macrocontext(chan), ast_channel_context(chan)), interfaces->dial_parent_id))) {
if (!(monitor = cc_extension_monitor_init(ast_channel_exten(chan),
ast_channel_context(chan),
interfaces->dial_parent_id))) {
return -1;
}
monitor->core_id = interfaces->core_id;
@ -2681,8 +2659,8 @@ static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel
if (ast_channel_caller(chan)->id.name.valid && ast_channel_caller(chan)->id.name.str) {
ast_copy_string(generic_pvt->cid_name, ast_channel_caller(chan)->id.name.str, sizeof(generic_pvt->cid_name));
}
ast_copy_string(generic_pvt->exten, S_OR(ast_channel_macroexten(chan), ast_channel_exten(chan)), sizeof(generic_pvt->exten));
ast_copy_string(generic_pvt->context, S_OR(ast_channel_macrocontext(chan), ast_channel_context(chan)), sizeof(generic_pvt->context));
ast_copy_string(generic_pvt->exten, ast_channel_exten(chan), sizeof(generic_pvt->exten));
ast_copy_string(generic_pvt->context, ast_channel_context(chan), sizeof(generic_pvt->context));
agent->private_data = generic_pvt;
ast_set_flag(agent, AST_CC_AGENT_SKIP_OFFER);
return 0;
@ -2822,7 +2800,6 @@ static void *generic_recall(void *data)
char *target;
int reason;
struct ast_channel *chan;
const char *callback_macro = ast_get_cc_callback_macro(agent->cc_params);
const char *callback_sub = ast_get_cc_callback_sub(agent->cc_params);
unsigned int recall_timer = ast_get_cc_recall_timer(agent->cc_params) * 1000;
struct ast_format_cap *tmp_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
@ -2863,16 +2840,6 @@ static void *generic_recall(void *data)
pbx_builtin_setvar_helper(chan, "CC_EXTEN", generic_pvt->exten);
pbx_builtin_setvar_helper(chan, "CC_CONTEXT", generic_pvt->context);
if (!ast_strlen_zero(callback_macro)) {
ast_log_dynamic_level(cc_logger_level, "Core %u: There's a callback macro configured for agent %s\n",
agent->core_id, agent->device_name);
if (ast_app_exec_macro(NULL, chan, callback_macro)) {
ast_cc_failed(agent->core_id, "Callback macro to %s failed. Maybe a hangup?", agent->device_name);
ast_hangup(chan);
return NULL;
}
}
if (!ast_strlen_zero(callback_sub)) {
ast_log_dynamic_level(cc_logger_level, "Core %u: There's a callback subroutine configured for agent %s\n",
agent->core_id, agent->device_name);

View File

@ -1702,7 +1702,7 @@ static int single_state_process_dial_begin(struct cdr_object *cdr, struct ast_ch
/* If we have two parties, lock the application that caused the
* two parties to be associated. This prevents mid-call event
* macros/gosubs from perturbing the CDR application/data
* gosubs from perturbing the CDR application/data
*/
ast_set_flag(&cdr->flags, AST_CDR_LOCK_APP);
} else if (!strcasecmp(cdr->party_a.snapshot->base->name, peer->base->name)) {

View File

@ -1310,9 +1310,9 @@ static int ast_channel_by_exten_cb(void *obj, void *arg, void *data, int flags)
}
ast_channel_lock(chan);
if (strcasecmp(ast_channel_context(chan), context) && strcasecmp(ast_channel_macrocontext(chan), context)) {
if (strcasecmp(ast_channel_context(chan), context)) {
ret = 0; /* Context match failed, continue */
} else if (strcasecmp(ast_channel_exten(chan), exten) && strcasecmp(ast_channel_macroexten(chan), exten)) {
} else if (strcasecmp(ast_channel_exten(chan), exten)) {
ret = 0; /* Extension match failed, continue */
}
ast_channel_unlock(chan);
@ -3841,8 +3841,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
break;
}
ast_channel_unlock(chan);
if (ast_channel_connected_line_sub(NULL, chan, &connected, 0) &&
ast_channel_connected_line_macro(NULL, chan, &connected, 1, 0)) {
if (ast_channel_connected_line_sub(NULL, chan, &connected, 0)) {
ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE,
read_action_payload->payload,
read_action_payload->payload_size);
@ -5957,8 +5956,7 @@ static void call_forward_inherit(struct ast_channel *new_chan, struct ast_channe
ast_channel_lock(orig);
ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(orig));
ast_channel_unlock(orig);
if (ast_channel_redirecting_sub(orig, parent, &redirecting, 0) &&
ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
if (ast_channel_redirecting_sub(orig, parent, &redirecting, 0)) {
ast_channel_update_redirecting(parent, &redirecting, NULL);
}
ast_party_redirecting_free(&redirecting);
@ -10417,110 +10415,6 @@ int ast_channel_get_intercept_mode(void)
return ast_threadstorage_get_ptr(&in_intercept_routine) ? 1 : 0;
}
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int is_frame)
{
static int deprecation_warning = 0;
const char *macro;
const char *macro_args;
int retval;
ast_channel_lock(macro_chan);
macro = pbx_builtin_getvar_helper(macro_chan, is_caller
? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO");
macro = ast_strdupa(S_OR(macro, ""));
macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS");
macro_args = ast_strdupa(S_OR(macro_args, ""));
if (ast_strlen_zero(macro)) {
ast_channel_unlock(macro_chan);
return -1;
}
if (!deprecation_warning) {
deprecation_warning = 1;
ast_log(LOG_WARNING, "Usage of CONNECTED_LINE_CALLE[ER]_SEND_MACRO is deprecated. Please use CONNECTED_LINE_SEND_SUB instead.\n");
}
if (is_frame) {
const struct ast_frame *frame = connected_info;
ast_connected_line_parse_data(frame->data.ptr, frame->datalen, ast_channel_connected(macro_chan));
} else {
const struct ast_party_connected_line *connected = connected_info;
ast_party_connected_line_copy(ast_channel_connected(macro_chan), connected);
}
ast_channel_unlock(macro_chan);
channel_set_intercept_mode(1);
retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
channel_set_intercept_mode(0);
if (!retval) {
struct ast_party_connected_line saved_connected;
ast_party_connected_line_init(&saved_connected);
ast_channel_lock(macro_chan);
ast_party_connected_line_copy(&saved_connected, ast_channel_connected(macro_chan));
ast_channel_unlock(macro_chan);
ast_channel_update_connected_line(macro_chan, &saved_connected, NULL);
ast_party_connected_line_free(&saved_connected);
}
return retval;
}
int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *redirecting_info, int is_caller, int is_frame)
{
static int deprecation_warning = 0;
const char *macro;
const char *macro_args;
int retval;
ast_channel_lock(macro_chan);
macro = pbx_builtin_getvar_helper(macro_chan, is_caller
? "REDIRECTING_CALLER_SEND_MACRO" : "REDIRECTING_CALLEE_SEND_MACRO");
macro = ast_strdupa(S_OR(macro, ""));
macro_args = pbx_builtin_getvar_helper(macro_chan, is_caller
? "REDIRECTING_CALLER_SEND_MACRO_ARGS" : "REDIRECTING_CALLEE_SEND_MACRO_ARGS");
macro_args = ast_strdupa(S_OR(macro_args, ""));
if (ast_strlen_zero(macro)) {
ast_channel_unlock(macro_chan);
return -1;
}
if (!deprecation_warning) {
deprecation_warning = 1;
ast_log(LOG_WARNING, "Usage of REDIRECTING_CALLE[ER]_SEND_MACRO is deprecated. Please use REDIRECTING_SEND_SUB instead.\n");
}
if (is_frame) {
const struct ast_frame *frame = redirecting_info;
ast_redirecting_parse_data(frame->data.ptr, frame->datalen, ast_channel_redirecting(macro_chan));
} else {
const struct ast_party_redirecting *redirecting = redirecting_info;
ast_party_redirecting_copy(ast_channel_redirecting(macro_chan), redirecting);
}
ast_channel_unlock(macro_chan);
channel_set_intercept_mode(1);
retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
channel_set_intercept_mode(0);
if (!retval) {
struct ast_party_redirecting saved_redirecting;
ast_party_redirecting_init(&saved_redirecting);
ast_channel_lock(macro_chan);
ast_party_redirecting_copy(&saved_redirecting, ast_channel_redirecting(macro_chan));
ast_channel_unlock(macro_chan);
ast_channel_update_redirecting(macro_chan, &saved_redirecting, NULL);
ast_party_redirecting_free(&saved_redirecting);
}
return retval;
}
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int is_frame)
{
const char *sub;

View File

@ -178,7 +178,6 @@ struct ast_channel {
enum ast_channel_state state; /*!< State of line -- Don't write directly, use ast_setstate() */
int rings; /*!< Number of rings so far */
int priority; /*!< Dialplan: Current extension priority */
int macropriority; /*!< Macro: Current non-macro priority. See app_macro.c */
int amaflags; /*!< Set BEFORE PBX is started to determine AMA flags */
enum ast_channel_adsicpe adsicpe; /*!< Whether or not ADSI is detected on CPE */
unsigned int fin; /*!< Frames in counters. The high bit is a debug mask, so
@ -208,8 +207,6 @@ struct ast_channel {
char exten[AST_MAX_EXTENSION]; /*!< Dialplan: Current extension number */
char lastcontext[AST_MAX_CONTEXT]; /*!< Dialplan: Previous extension context */
char lastexten[AST_MAX_EXTENSION]; /*!< Dialplan: Previous extension number */
char macrocontext[AST_MAX_CONTEXT]; /*!< Macro: Current non-macro context. See app_macro.c */
char macroexten[AST_MAX_EXTENSION]; /*!< Macro: Current non-macro extension. See app_macro.c */
char unbridged; /*!< non-zero if the bridge core needs to re-evaluate the current
bridging technology which is in use by this channel's bridge. */
char is_t38_active; /*!< non-zero if T.38 is active on this channel. */
@ -377,22 +374,6 @@ void ast_channel_exten_set(struct ast_channel *chan, const char *value)
ast_copy_string(chan->exten, value, sizeof(chan->exten));
ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN);
}
const char *ast_channel_macrocontext(const struct ast_channel *chan)
{
return chan->macrocontext;
}
void ast_channel_macrocontext_set(struct ast_channel *chan, const char *value)
{
ast_copy_string(chan->macrocontext, value, sizeof(chan->macrocontext));
}
const char *ast_channel_macroexten(const struct ast_channel *chan)
{
return chan->macroexten;
}
void ast_channel_macroexten_set(struct ast_channel *chan, const char *value)
{
ast_copy_string(chan->macroexten, value, sizeof(chan->macroexten));
}
char ast_channel_dtmf_digit_to_emulate(const struct ast_channel *chan)
{
@ -451,14 +432,6 @@ void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
chan->hangupcause = value;
ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_HANGUP);
}
int ast_channel_macropriority(const struct ast_channel *chan)
{
return chan->macropriority;
}
void ast_channel_macropriority_set(struct ast_channel *chan, int value)
{
chan->macropriority = value;
}
int ast_channel_priority(const struct ast_channel *chan)
{
return chan->priority;

View File

@ -654,8 +654,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
break;
}
ast_verb(3, "%s connected line has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
if (ast_channel_connected_line_sub(channel->owner, chan, fr, 1) &&
ast_channel_connected_line_macro(channel->owner, chan, fr, 1, 1)) {
if (ast_channel_connected_line_sub(channel->owner, chan, fr, 1)) {
ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, fr->data.ptr, fr->datalen);
}
break;
@ -664,8 +663,7 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
break;
}
ast_verb(3, "%s redirecting info has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
if (ast_channel_redirecting_sub(channel->owner, chan, fr, 1) &&
ast_channel_redirecting_macro(channel->owner, chan, fr, 1, 1)) {
if (ast_channel_redirecting_sub(channel->owner, chan, fr, 1)) {
ast_indicate_data(chan, AST_CONTROL_REDIRECTING, fr->data.ptr, fr->datalen);
}
break;

View File

@ -117,7 +117,7 @@
prefixed with one or two underbars ('_').</para>
</note>
<note>
<para>Using this option from a Macro() or GoSub() might not make sense as there would be no return points.</para>
<para>Using this option from a or GoSub() might not make sense as there would be no return points.</para>
</note>
<note>
<para>This option will override the 'x' option</para>
@ -372,9 +372,8 @@ void ast_channel_log(char *title, struct ast_channel *chan) /* for debug, this i
ast_log(LOG_NOTICE, "CHAN: name: %s; appl: %s; data: %s; contxt: %s; exten: %s; pri: %d;\n",
ast_channel_name(chan), ast_channel_appl(chan), ast_channel_data(chan),
ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan));
ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x; maccontxt: %s; macexten: %s; macpri: %d;\n",
ast_channel_accountcode(chan), ast_channel_dialcontext(chan), ast_channel_amaflags(chan),
ast_channel_macrocontext(chan), ast_channel_macroexten(chan), ast_channel_macropriority(chan));
ast_log(LOG_NOTICE, "CHAN: acctcode: %s; dialcontext: %s; amaflags: %x;\n",
ast_channel_accountcode(chan), ast_channel_dialcontext(chan), ast_channel_amaflags(chan));
ast_log(LOG_NOTICE, "CHAN: masq: %p; masqr: %p; uniqueID: %s; linkedID:%s\n",
ast_channel_masq(chan), ast_channel_masqr(chan),
ast_channel_uniqueid(chan), ast_channel_linkedid(chan));

View File

@ -295,7 +295,6 @@ struct ast_context {
struct ast_sws alts; /*!< Alternative switches */
int refcount; /*!< each module that would have created this context should inc/dec this as appropriate */
int autohints; /*!< Whether autohints support is enabled or not */
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
/*!
* Buffer to hold the name & registrar character data.
@ -5149,49 +5148,6 @@ int ast_context_remove_extension_callerid2(struct ast_context *con, const char *
return found ? 0 : -1;
}
/*!
* \note This function locks contexts list by &conlist, searches for the right context
* structure, and locks the macrolock mutex in that context.
* macrolock is used to limit a macro to be executed by one call at a time.
*/
int ast_context_lockmacro(const char *macrocontext)
{
struct ast_context *c;
int ret = -1;
c = find_context_locked(macrocontext);
if (c) {
ast_unlock_contexts();
/* if we found context, lock macrolock */
ret = ast_mutex_lock(&c->macrolock);
}
return ret;
}
/*!
* \note This function locks contexts list by &conlist, searches for the right context
* structure, and unlocks the macrolock mutex in that context.
* macrolock is used to limit a macro to be executed by one call at a time.
*/
int ast_context_unlockmacro(const char *macrocontext)
{
struct ast_context *c;
int ret = -1;
c = find_context_locked(macrocontext);
if (c) {
ast_unlock_contexts();
/* if we found context, unlock macrolock */
ret = ast_mutex_unlock(&c->macrolock);
}
return ret;
}
/*
* Help for CLI commands ...
*/
@ -6234,7 +6190,6 @@ struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts,
if ((tmp = ast_calloc(1, length))) {
ast_rwlock_init(&tmp->lock);
ast_mutex_init(&tmp->macrolock);
tmp->name = memcpy(&tmp->data[0], name, name_bytes);
tmp->registrar = memcpy(&tmp->data[name_bytes + 1], registrar, registrar_bytes);
tmp->root = NULL;
@ -8094,7 +8049,6 @@ static void __ast_internal_context_destroy( struct ast_context *con)
}
tmp->root = NULL;
ast_rwlock_destroy(&tmp->lock);
ast_mutex_destroy(&tmp->macrolock);
ast_free(tmp);
}

View File

@ -227,7 +227,6 @@
<ref type="application">GotoIf</ref>
<ref type="application">GotoIfTime</ref>
<ref type="application">Gosub</ref>
<ref type="application">Macro</ref>
</see-also>
</application>
<application name="GotoIf" language="en_US">
@ -266,7 +265,6 @@
<ref type="application">Goto</ref>
<ref type="application">GotoIfTime</ref>
<ref type="application">GosubIf</ref>
<ref type="application">MacroIf</ref>
</see-also>
</application>
<application name="GotoIfTime" language="en_US">
@ -685,7 +683,6 @@
<description>
<para>This application waits for the user to enter a new extension for a specified number
of <replaceable>seconds</replaceable>.</para>
<xi:include xpointer="xpointer(/docs/application[@name='Macro']/description/warning[2])" />
</description>
<see-also>
<ref type="application">Background</ref>
@ -1146,13 +1143,8 @@ static int pbx_builtin_background(struct ast_channel *chan, const char *data)
args.lang = (char *)ast_channel_language(chan); /* XXX this is const */
if (ast_strlen_zero(args.context)) {
const char *context;
ast_channel_lock(chan);
if ((context = pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT"))) {
args.context = ast_strdupa(context);
} else {
args.context = ast_strdupa(ast_channel_context(chan));
}
args.context = ast_strdupa(ast_channel_context(chan));
ast_channel_unlock(chan);
}
@ -1208,9 +1200,7 @@ static int pbx_builtin_background(struct ast_channel *chan, const char *data)
/*
* If the single digit DTMF is an extension in the specified context, then
* go there and signal no DTMF. Otherwise, we should exit with that DTMF.
* If we're in Macro, we'll exit and seek that DTMF as the beginning of an
* extension in the Macro's calling context. If we're not in Macro, then
* we'll simply seek that extension in the calling context. Previously,
* We'll simply seek that extension in the calling context. Previously,
* someone complained about the behavior as it related to the interior of a
* Gosub routine, and the fix (#14011) inadvertently broke FreePBX
* (#14940). This change should fix both of these situations, but with the

View File

@ -328,8 +328,7 @@ int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
ast_party_id_reset(&connected_caller.priv);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
if (ast_channel_connected_line_sub(NULL, chan, &connected_caller, 0) &&
ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) {
if (ast_channel_connected_line_sub(NULL, chan, &connected_caller, 0)) {
ast_channel_update_connected_line(chan, &connected_caller, NULL);
}
ast_party_connected_line_free(&connected_caller);

View File

@ -64,8 +64,6 @@
</member>
<member name="app_lookupcidname" displayname="Look up CallerID Name from local database" remove_on_change="apps/app_lookupcidname.o apps/app_lookupcidname.so">
</member>
<member name="app_macro" displayname="Extension Macros" remove_on_change="apps/app_macro.o apps/app_macro.so">
</member>
<member name="app_meetme" displayname="MeetMe conference bridge" remove_on_change="apps/app_meetme.o apps/app_meetme.so">
<depend>zaptel</depend>
</member>

View File

@ -72,8 +72,6 @@
<depend>jack</depend>
<depend name="resample">libresample</depend>
</member>
<member name="app_macro" displayname="Extension Macros" remove_on_change="apps/app_macro.o apps/app_macro.so">
</member>
<member name="app_meetme" displayname="MeetMe conference bridge" remove_on_change="apps/app_meetme.o apps/app_meetme.so">
<depend>dahdi</depend>
</member>

View File

@ -98,10 +98,8 @@ void check_pval_item(pval *item, struct argapp *apps, int in_globals);
void check_switch_expr(pval *item, struct argapp *apps);
void ast_expr_register_extra_error_info(char *errmsg);
void ast_expr_clear_extra_error_info(void);
struct pval *find_macro(char *name);
struct pval *find_context(char *name);
struct pval *find_context(char *name);
struct pval *find_macro(char *name);
struct ael_priority *new_prio(void);
struct ael_extension *new_exten(void);
void destroy_extensions(struct ael_extension *exten);
@ -199,10 +197,10 @@ static char *handle_cli_ael_set_debug(struct ast_cli_entry *e, int cmd, struct a
{
switch (cmd) {
case CLI_INIT:
e->command = "ael set debug {read|tokens|macros|contexts|off}";
e->command = "ael set debug {read|tokens|contexts|off}";
e->usage =
"Usage: ael set debug {read|tokens|macros|contexts|off}\n"
" Enable AEL read, token, macro, or context debugging,\n"
"Usage: ael set debug {read|tokens|contexts|off}\n"
" Enable AEL read, token, or context debugging,\n"
" or disable all AEL debugging messages. Note: this\n"
" currently does nothing.\n";
return NULL;
@ -217,8 +215,6 @@ static char *handle_cli_ael_set_debug(struct ast_cli_entry *e, int cmd, struct a
aeldebug |= DEBUG_READ;
else if (!strcasecmp(a->argv[3], "tokens"))
aeldebug |= DEBUG_TOKENS;
else if (!strcasecmp(a->argv[3], "macros"))
aeldebug |= DEBUG_MACROS;
else if (!strcasecmp(a->argv[3], "contexts"))
aeldebug |= DEBUG_CONTEXTS;
else if (!strcasecmp(a->argv[3], "off"))

View File

@ -2053,14 +2053,8 @@ static void pbx_load_users(void)
ast_add_extension2(con, 0, cat, -1, NULL, NULL, iface, NULL, NULL, registrar, NULL, 0);
/* If voicemail, use "stdexten" else use plain old dial */
if (hasvoicemail) {
if (ast_opt_stdexten_macro) {
/* Use legacy stdexten macro method. */
snprintf(tmp, sizeof(tmp), "stdexten,%s,${HINT}", cat);
ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Macro", ast_strdup(tmp), ast_free_ptr, registrar, NULL, 0);
} else {
snprintf(tmp, sizeof(tmp), "%s,stdexten(${HINT})", cat);
ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Gosub", ast_strdup(tmp), ast_free_ptr, registrar, NULL, 0);
}
snprintf(tmp, sizeof(tmp), "%s,stdexten(${HINT})", cat);
ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Gosub", ast_strdup(tmp), ast_free_ptr, registrar, NULL, 0);
} else {
ast_add_extension2(con, 0, cat, 1, NULL, NULL, "Dial", ast_strdup("${HINT}"), ast_free_ptr, registrar, NULL, 0);
}

View File

@ -4786,29 +4786,9 @@ static int dundi_helper(struct ast_channel *chan, const char *context, const cha
int res;
int x;
int found = 0;
if (!strncasecmp(context, "macro-", 6)) {
if (!chan) {
ast_log(LOG_NOTICE, "Can't use macro mode without a channel!\n");
return -1;
}
/* If done as a macro, use macro extension */
if (!strcasecmp(exten, "s")) {
exten = pbx_builtin_getvar_helper(chan, "ARG1");
if (ast_strlen_zero(exten))
exten = ast_channel_macroexten(chan);
if (ast_strlen_zero(exten))
exten = ast_channel_exten(chan);
if (ast_strlen_zero(exten)) {
ast_log(LOG_WARNING, "Called in Macro mode with no ARG1 or MACRO_EXTEN?\n");
return -1;
}
}
if (ast_strlen_zero(data))
data = "e164";
} else {
if (ast_strlen_zero(data))
data = context;
}
if (ast_strlen_zero(data))
data = context;
res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
for (x=0;x<res;x++) {
if (ast_test_flag(results + x, flag))
@ -4838,29 +4818,9 @@ static int dundi_exec(struct ast_channel *chan, const char *context, const char
const char *dundiargs;
struct ast_app *dial;
if (!strncasecmp(context, "macro-", 6)) {
if (!chan) {
ast_log(LOG_NOTICE, "Can't use macro mode without a channel!\n");
return -1;
}
/* If done as a macro, use macro extension */
if (!strcasecmp(exten, "s")) {
exten = pbx_builtin_getvar_helper(chan, "ARG1");
if (ast_strlen_zero(exten))
exten = ast_channel_macroexten(chan);
if (ast_strlen_zero(exten))
exten = ast_channel_exten(chan);
if (ast_strlen_zero(exten)) {
ast_log(LOG_WARNING, "Called in Macro mode with no ARG1 or MACRO_EXTEN?\n");
return -1;
}
}
if (ast_strlen_zero(data))
data = "e164";
} else {
if (ast_strlen_zero(data))
data = context;
}
if (ast_strlen_zero(data))
data = context;
res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
if (res > 0) {
sort_results(results, res);

View File

@ -3848,7 +3848,7 @@ static struct ast_frame *fax_detect_framehook(struct ast_channel *chan, struct a
switch (result) {
case 'f':
case 't':
target_context = S_OR(ast_channel_macrocontext(chan), ast_channel_context(chan));
target_context = ast_channel_context(chan);
ast_channel_unlock(chan);
ast_frfree(f);

View File

@ -142,9 +142,6 @@ static oid asterisk_oid[] = { 1, 3, 6, 1, 4, 1, 22736, 1 };
#define ASTCHANAPP 10
#define ASTCHANDATA 11
#define ASTCHANCONTEXT 12
#define ASTCHANMACROCONTEXT 13
#define ASTCHANMACROEXTEN 14
#define ASTCHANMACROPRI 15
#define ASTCHANEXTEN 16
#define ASTCHANPRI 17
#define ASTCHANACCOUNTCODE 18
@ -355,20 +352,6 @@ static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *le
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
break;
case ASTCHANMACROCONTEXT:
ast_copy_string(string_ret, ast_channel_macrocontext(chan), sizeof(string_ret));
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
break;
case ASTCHANMACROEXTEN:
ast_copy_string(string_ret, ast_channel_macroexten(chan), sizeof(string_ret));
*var_len = strlen(string_ret);
ret = (u_char *)string_ret;
break;
case ASTCHANMACROPRI:
long_ret = ast_channel_macropriority(chan);
ret = (u_char *)&long_ret;
break;
case ASTCHANEXTEN:
ast_copy_string(string_ret, ast_channel_exten(chan), sizeof(string_ret));
*var_len = strlen(string_ret);
@ -854,9 +837,6 @@ static void init_asterisk_mib(void)
{ASTCHANAPP, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAPP}},
{ASTCHANDATA, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANDATA}},
{ASTCHANCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCONTEXT}},
{ASTCHANMACROCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROCONTEXT}},
{ASTCHANMACROEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROEXTEN}},
{ASTCHANMACROPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROPRI}},
{ASTCHANEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANEXTEN}},
{ASTCHANPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPRI}},
{ASTCHANACCOUNTCODE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANACCOUNTCODE}},

View File

@ -490,7 +490,6 @@ static int test_vm_api_create_voicemail_files(const char *context, const char *m
"[message]\n"
"origmailbox=%s\n"
"context=%s\n"
"macrocontext=%s\n"
"exten=%s\n"
"rdnis=%s\n"
"priority=%d\n"
@ -504,7 +503,6 @@ static int test_vm_api_create_voicemail_files(const char *context, const char *m
"duration=%s\n",
mailbox,
context,
"",
snapshot->exten,
"unknown",
1,

View File

@ -2398,7 +2398,6 @@ struct ast_context {
struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
const char *registrar; /*!< Registrar */
AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
char name[0]; /*!< Name of the context */
};
@ -4728,7 +4727,6 @@ static struct ast_context *__ast_context_create(struct ast_context **extcontexts
}
if ((tmp = ast_calloc(1, length))) {
ast_rwlock_init(&tmp->lock);
ast_mutex_init(&tmp->macrolock);
strcpy(tmp->name, name);
tmp->root = NULL;
tmp->registrar = registrar;