[Home]

Summary:ASTERISK-08961: [branch] [patch] No way to create actual macros in AEL2.
Reporter:Sherwood McGowan (rushowr)Labels:
Date Opened:2007-03-07 14:17:57.000-0600Date Closed:2007-06-20 16:50:48
Priority:MajorRegression?No
Status:Closed/CompleteComponents:PBX/pbx_ael
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) dialgosub
Description:Because of the conversion of AEL's compiler to use Gosub and contexts when it encounters a macro (and/or a call to a macro) in a dialplan, the only way to actually create a macro now is to create it within extensions.conf or some other included dialplan file using the main standard language.

If a dialplan developer writes exclusively in AEL, he/she would technically be unable to create macros, which are sometimes essential due to needs in applications like Dial() which has the ^M(macroname) argument.

Example:

context test_dial_with_macro_call {
 _X. => {
   Dial(SIP/123,30,M(test_macro));
   return;
 }
}

macro test_macro() {
 Verbose(1|Inside the macro);
}

Technically, when the dial is placed and the call is answered, you should see "Inside the macro" show up on the CLI as long as you have verbose set to 1 or higher. However, because of the Gosub usage transition, no actual macro named macro-test_macro would be created, and therefore Asterisk would not be able to execute it.

The workaround for the moment would be to create the file in a .conf file.

While this could be considered minor, I personally believe it's major, as I code dialplan solutions in AEL almost exclusively.
Comments:By: Serge Vecher (serge-v) 2007-03-07 14:19:52.000-0600

AEL is no longer considered experimental ;)

By: Sherwood McGowan (rushowr) 2007-03-07 14:34:44.000-0600

Not sure why serge changed this to 1.4.1, as I confirmed with murf that the Gosub replacement is not in place for 1.4 release.

I meant to post that for trunk rev 58288.



By: Sherwood McGowan (rushowr) 2007-03-08 04:35:45.000-0600

Steve, I had a suggestion I'd like to make for this.

What if we could revert the macro behavior in AEL, but add a new definition such as "subroutine" that uses the Gosub format and implement a command to call a subroutine?

Here's an example of what I think the code format would look like:

// example of a subroutine definition
subroutine example(arg1,arg2) {
 Verbose(2|This is an example subroutine);
 Verbose(2|This is the first argument ${arg1});
 Verbose(2|This is the second argument ${arg2});
}

// sample call to a subroutine
context test {
 _X. => {
   Verbose(2|Calling the subroutine);
   &&example("foo","bar");
   Hangup();
 }
}

What do you think?

By: Steve Murphy (murf) 2007-03-08 09:11:12.000-0600

I have a different approach. I've added another option to the Dial command, the 'U' option, which behaves exactly the same as the 'M' option, except that it calls a Gosub instead of the Macro app. And, really, it is logically necessary. To keep up with convention, I specified a GOSUB_RESULT value. Hmmm. I suppose I should create a branch just for this, for the moment, so you can test it out. More to come.

By: Steve Murphy (murf) 2007-03-08 09:54:04.000-0600

OK, I committed this to http://svn.digium.com/svn/asterisk/team/murf/bug9228

I also will append a patch to this bug, if you want to go that route.

By: Steve Murphy (murf) 2007-03-08 09:57:35.000-0600

See if this solves the problem. If there are other apps that call a macro, let me know, we'll need to update them all, if there's others.


By: Sherwood McGowan (rushowr) 2007-03-08 13:26:50.000-0600

I'll test this as soon as I can, probably within the day

By: Sherwood McGowan (rushowr) 2007-03-21 09:14:42

Just downloaded and compiled, putting together a test now and will update shortly

By: Sherwood McGowan (rushowr) 2007-03-30 22:35:32

Murf,

I attempted to test this fix but for some strange reason when I attempted to place a call with XLite (the softphone I currently use for testing) Asterisk just crashed. I'm checking out a new working copy and recompiling to see if it was a problem on my end, it doesn't seem like your change would cause this...

More later, and sorry for the slow responses I've been unable to get a spare moment lately.

By: Sherwood McGowan (rushowr) 2007-03-31 05:33:32

I checked out a fresh copy, recompiled, and then ran test calls. On the first test call I used the new "U" option with no arguments, as shown below:

Dial(SIP/${EXTEN},10,U(test));

I dialed my second test phone and upon answer by the second phone, Asterisk should have executed the context "test" but instead gave me an error message (shown below)

[Mar 31 06:23:35] NOTICE[14644]: pbx.c:1762 pbx_extension_helper: Cannot find extension '' in context 'outbound'
[Mar 31 06:23:35] WARNING[14644]: pbx.c:6316 ast_parseable_goto: Priority 'test' must be a number > 0, or valid label
[Mar 31 06:23:35] ERROR[14644]: app_stack.c:252 gosub_exec: Gosub address is invalid: 'test'

So, I changed to U option's arguments to include the priority and extension to use for the Gosub as shown below:

Dial(SIP/${EXTEN},10,U(test^s^1));

This still did not work as expected. Asterisk's output on the CLI (at verbosity of 3, which shows all dialplan executions) did not show "test" being executed upon answer of the call. The output from the call is shown below:

   -- Executing [321@outbound:1] Dial("SIP/123-081a10b8", "SIP/321|10|U(test^s^1)") in new stack
   -- Called 321
   -- SIP/321-081a2968 is ringing
   -- SIP/321-081a2968 answered SIP/123-081a10b8
   -- Native bridging SIP/123-081a10b8 and SIP/321-081a2968
 == Spawn extension (outbound, 321, 1) exited non-zero on 'SIP/123-081a10b8'
   -- Executing [h@outbound:1] Hangup("SIP/123-081a10b8", "") in new stack
 == Spawn extension (outbound, h, 1) exited non-zero on 'SIP/123-081a10b8'

The test context was set to execute a Verbose() command which would show the message "inside the test subroutine" at verbose level 1 or higher. As you can see from the output list above this did not occur.

Below is a copy of the relevant dialplan code used for this test:

context outbound {
_X. => {
Dial(SIP/${EXTEN},10,U(test^s^1));
Softhangup();
}

_h => {
Hangup();
}
}

macro test() {
Verbose(1|inside the test subroutine);
return;
}

By: pkempgen (pkempgen) 2007-04-17 17:28:54

Because this is somewhat related I thought I should post it here instead of
opening a new bug: The scope of arguments to macros is not what you would
expect. Example:

macro testmacro( dest, active ) {
 // do something
}

&testmacro(internal,1);
Verbose(1,### dest  : ${dest});
Verbose(1,### active: ${active});

You wouldn't expect the arguments to the macro be available as channel
variables after the call to the macro. But they are, because the macro gets
the arguments by executing
Set(dest=${ARG1});
Set(active=${ARG2});

I don't think there is a quick solution to this but posted anyway for
completeness. (Maybe someone else has an idea.)

By: Arcadiy Ivanov (arcivanov) 2007-05-22 23:34:53

I have this problem I encountered a few minutes ago:

---------------------------------------------------

macro macro1(param1)
{
param1=x;
};

macro macro2(param1)
{
Verbose(${param1});
};


macro main(param1)
{
&macro1(param1);
&macro2(param1);
};

context default
{
s =>
{
&main(a);
};
};

---------------------------------------------------

Verbose in macro2 will print "x", not "a".

Currently all macro arguments are in the channel scope, which is a huge issue IMHO, since it is inconsistent with macro behavior in extensions.conf

Maybe introduction of a block-scope is necessary?



By: Steve Murphy (murf) 2007-06-19 18:52:26

ahhh, looks like I have some more work to do here.

First, let's create a different bug for macro/gosub arg scope, as created by AEL. It's related, but an entirely different work set.

rushowr-- I've just checked into trunk the stuff I did back in March. I'll investigate the points you brought up tomorrow.

By: Steve Murphy (murf) 2007-06-20 16:50:47

In a series of commits, ending with 70531 (in trunk), Tilghman and I have resolved this bug. Tilghman supplied the LOCAL function to make local variables, and also helped solve the problem of running a gosub from an app (like app_dial, and app_queue), in the same manner as they are now running macros. The hitch was that macros run their own show, and gosubs just set a stack entry, and set the context/exten/prio on the channel to jump to the routine, and exit.

I introduced a new keyword into AEL, "local", which you can prepend to a variable set, as in "local x=howdy;"  you can get x's value via ${x} as normal, but x is a local var and will disappear when the AEL macro returns. Also, all macro arguments, both the named args (like zork and mindy of
  "macro mymac(zork, mindy){...}") and the ARG1, ARG2, etc. are all local variables to the macro. So, yes, I did resolve both requests/problems with this one bug report. I also updated the doc/ael.tex document.

So, now you should be able to define macros in AEL, that you can use (as gosubs) in apps like app_dial and app_queue. Enjoy! And, of course, let me know about problems, by re-opening this bug!