System information
Returning from a Subroutine
Unlike Macro(), the GoSub() dialplan application does not return automatically once it
is done executing. In order to return from whence we came, we need to use the
Return() application. Now that we know how to call a subroutine and pass arguments,
we can look at an example where we might need to return from the subroutine.
Using our previous example, we could break out the dialing portion and the voicemail
portion into separate subroutines:
[subDialer]
exten => start,1,Dial(${ARG1},${ARG2})
same => n,Return()
[subVoicemail]
exten => start,1,VoiceMail(${ARG1}@${ARG2},${ARG3})
same => n,Hangup()
The [subDialer] context created here takes two arguments: ${ARG1}, which contains
the destination to dial; and ${ARG2}, which contains the ring cycle, defined in seconds.
We conclude the [subDialer] context with the dialplan application Return(), which
will return to the priority following the one that called GoSub() (the next line of the
dialplan).
The [subVoicemail] context contains the VoiceMail() application, which is using three
arguments passed to it: ${ARG1} contains the mailbox number, ${ARG2} contains the
voicemail context, and ${ARG3} contains a value to indicate which voicemail message
(unavailable or busy) to play to the caller.
Calling these subroutines might look like this:
exten => 101,1,GoSub(subDialer,start,1(${JOHN},30))
same => n,GoSub(subVoicemail,start,1(${EXTEN},default,u))
Here we’ve used the subDialer subroutine, which attempts to call ${JOHN}, ringing him
for 30 seconds. If the Dial() application returns (e.g., if the line was busy, or there was
no answer for 30 seconds), we Return() from the subroutine and execute the next line
of our dialplan, which calls the subVoicemail subroutine. From there, we pass the ex-
tension that was dialed (e.g., 101) as the mailbox number, and pass the values
default for the voicemail context and the letter u to play the unavailable message.
Our example has been hardcoded to play the unavailable voicemail message, but we
can modify the Return() application to return the ${DIALSTATUS} so that we can play
the busy message if its value is BUSY. To do this, we’ll use the ${GOSUB_RETVAL} channel
variable, which is set whenever we pass a value to the Return() application:
[subDialer]
exten => start,1,Dial(${ARG1},${ARG2})
same => n,Return(${DIALSTATUS})
[subVoicemail]
210 | Chapter 10: Deeper into the Dialplan