Gosub: Macro’s Successor

Overview

This blog post is a friendly reminder that Macro will soon be deprecated in Asterisk. What does that mean? Well, for a start, it means that you’ll need an alternative. You might be wondering what you can use in place of Macro. The answer is Gosub, and we’re going to give a little introduction to help get you started if you haven’t already.

The focus of this post is going to be more on example usage to help get you acquainted with Gosub. The Asterisk wiki[1] is a great place to find more information.

Why is Macro Going Away?

On the outside, Macro and Gosub seem very similar. Why is Macro going away, then? The answer is a bit complicated. First off, Macro uses recursion whereas Gosub does not. Because of this, Macro can run into some nasty situations that Gosub doesn’t have to worry about. Macro also required explicit logic for contexts and macro contexts, another problem that Gosub does not have. In the end, Gosub is better to work with for both the user and the developer.

What is Gosub?

Gosub is very similar to Macro, so learning it shouldn’t take any time at all. The syntax itself is very similar. From the Gosub wiki page[2]:

Gosub([[context,]exten,]priority[(arg1[,...][,argN])])

context and exten are optional, but there must always be a priority. Additionally, custom arguments can be passed to Gosub after the priority. They must be put inside parentheses, and you can pass in as many as you want. Gosub can also be used with other applications such as Queue just like Macro can. However, Gosub can also be used with Dial in the form of a pre-dial handler. Gosub offers a lot of flexibility!

Examples

Just the priority:

exten => example,1,Gosub(3)
 same => 2,Verbose("Skip me!")
 same => 3,Verbose("Go here!")

The extension and the priority:

exten => example,1,Gosub(destination, 1)

exten => destination,1,Verbose("We're here!")

The context, extension, and priority:

[default]

exten => example,1,Gosub(not-default,destination,1)

[not-default]

exten => destination,1,Verbose("Another context")

You can also return to dialplan execution from where you called Gosub originally:

exten => example,1,Gosub(with-return,1)
 same => n,Verbose("After Gosub")

exten => with-return,1,Verbose("Start Gosub")
 same => n,Return()

Arguments can be passed in as well:

exten => example,1,Gosub(with-args,1(${EXTEN}))

exten => with-args,1,Verbose("ARG1 is ${ARG1}")

You can also use Gosub with pre-dial handlers and pre-bridge handlers. From the pre-dial handler wiki page[3]:

b([[context^]exten^]priority[(arg1[^...][^argN])])
B([[context^]exten^]priority[(arg1[^...][^argN])])

And the pre-bridge handler wiki page[4]:

U(x[^arg[^...]])

Here’s a pre-dial example:

exten => 1234,1,Dial(PJSIP/yourfriend,,B(predial^1))
 same => n,Hangup()

exten => predial,1,Verbose("Executed on caller channel")
 same => n,Playback(hello-world)
 same => n,Return()

Note that when using Gosub with these handlers, there MUST be a Return().

References

[1]: https://wiki.asterisk.org/

[2]: https://wiki.asterisk.org/wiki/display/AST/Gosub

[3]: https://wiki.asterisk.org/wiki/display/AST/Pre-Dial+Handlers

[4]: https://wiki.asterisk.org/wiki/display/AST/Pre-Bridge+Handlers

About the Author

What can we help you find?