Using Predefined Channel Variables in Asterisk Dialplans
Learn how Asterisk predefined channel variables such as CONTEXT, EXTEN, and PRIORITY describe call execution, plus practical EXTEN pattern and substring examples.
What predefined channel variables are
A channel variable is a named value available to the dialplan for a particular active call channel. Asterisk automatically supplies some variables while it processes a call. These are called predefined channel variables.
Predefined variables let dialplan applications inspect the current call state. For example, a dialplan can read the extension that the caller dialed and pass it to another application. You read a variable with an expression such as ${EXTEN}.
This differs from assigning a custom channel variable. For example, Set(DESTINATION=${EXTEN:1}) creates or changes a variable named DESTINATION. Asterisk supplies EXTEN automatically, while DESTINATION is a value that the dialplan author chooses to store.
Values associated with execution state can change as the channel moves through contexts, extensions, and priorities. Therefore, always interpret a predefined variable according to the point at which the dialplan reads it.
CONTEXT, EXTEN, and PRIORITY
A dialplan is organized into named contexts. A context is a collection of extensions and their ordered application steps. An extension is a dialable value, or a pattern that matches dialed values, together with the applications that should run. A priority is one ordered instruction position within that extension.
Together, CONTEXT, EXTEN, and PRIORITY identify the channel's current location in the dialplan:
| Variable | Meaning | Typical value | How it is used |
|---|---|---|---|
CONTEXT | The dialplan context currently associated with the executing channel. | demo-predefined-vars | Identify which group of routing rules is being executed. |
EXTEN | The current extension value being processed by the dialplan. | 2005 | Pass the dialed or matched extension to an application, or transform it for routing. |
PRIORITY | The current execution priority or step within the extension. | 1, then 2 | Inspect which instruction is currently running. |
For example, a call might begin in context demo-predefined-vars, match extension 2005 through the pattern _XXXX, and start at priority 1. After priority 1 completes, the channel proceeds to the next priority in that extension.
For more detail about ordered execution, see Priorities.
Variable expansion syntax
Variable expansion means replacing an expression with its current value while an application is being evaluated. The general form is:
${VARIABLE_NAME}
Put the expression inside an application argument when you want Asterisk to substitute the value. To speak the current extension, for example, use:
same => n,SayDigits(${EXTEN})
When this application runs, Asterisk expands ${EXTEN} and passes the resulting value to SayDigits(). Writing EXTEN without the ${...} syntax does not request variable expansion.
Pattern matching for four-digit extensions
An extension pattern matches a class of dialed values instead of one literal extension.
| Pattern element | Meaning | Example |
|---|---|---|
_ | Begins an Asterisk extension pattern. | _XXXX |
X | Matches one digit from 0 through 9. | The first X can match 2. |
_XXXX | Matches exactly four numeric digits. | 2005 matches; 200 and 20056 do not. |
The underscore is important: without it, the text would be treated differently from a pattern. Four X characters after the underscore mean that the caller must provide exactly four digits for this rule to match.
Example: speak the full dialed extension
This example accepts any four-digit extension in the demo-predefined-vars context, answers the call, and speaks the value held in EXTEN:
[demo-predefined-vars]
exten => _XXXX,1,Answer()
same => n,SayDigits(${EXTEN})
The flow is:
- The caller dials a four-digit value.
- Asterisk checks the channel's current context and finds the matching
_XXXXpattern. - At priority 1,
Answer()answers the inbound call. - The
same => nform advances to the next priority in the same extension. ${EXTEN}expands to the current four-digit extension.SayDigits()speaks those digits to the caller.
If the caller dials 2005, EXTEN contains 2005, and the caller should hear the digits 2, 0, 0, and 5.
Answer() is placed before media playback so the call is answered before the dialplan attempts to play information. Read more about it in The Answer Application.
Substring extraction from EXTEN
Asterisk supports substring expansion with the form ${EXTEN:n}. The number after the colon is a zero-based character offset: position 0 is the first character, position 1 is the second character, and so on.
| Dialed EXTEN value | Expression | Starting position | Result |
|---|---|---|---|
2005 | ${EXTEN} | Entire value | 2005 |
2005 | ${EXTEN:0} | 0, the first character | 2005 |
2005 | ${EXTEN:1} | 1, the second character | 005 |
2005 | ${EXTEN:2} | 2, the third character | 05 |
Using ${EXTEN:1} removes the first character because extraction begins at the second character. With an EXTEN value of 2005, the result is 005.
Example: speak the extension after skipping its first digit
[demo-predefined-vars]
exten => _XXXX,1,Answer()
same => n,SayDigits(${EXTEN:1})
When the caller dials 2005, the expression expands to 005. The caller should therefore hear 0, 0, and 5, not the initial 2.
This technique is commonly used when the first digit is an access prefix. For example, a deployment might require callers to dial 0 before an outside number. The dialplan can remove that prefix before submitting the destination to an external carrier. The offset does not itself prove that the first character is 0; the matching rule and validation policy must ensure that assumption is correct.
Preparing a destination for an outside carrier
The following example logs the original extension, stores the value without its first character, and logs the transformed destination:
[outbound]
exten => _0X.,1,NoOp(Original number: ${EXTEN})
same => n,Set(DESTINATION=${EXTEN:1})
same => n,NoOp(Number without access prefix: ${DESTINATION})
Here, _0X. is intended to represent a number beginning with an access digit followed by additional digits. Before adding Dial(), restrict the pattern and apply destination-format and authorization rules appropriate to the deployment. Do not assume that every matched value is acceptable to a carrier.
Always validate the actual dialed number before sending transformed digits to a trunk. Confirm that the caller used the expected prefix, that the resulting number has the required length and format, and that the caller is authorized to place the call.
Testing and inspecting the dialplan
- Place the pattern in the intended context, such as
demo-predefined-vars. - Reload the dialplan after saving the configuration.
- Confirm that the pattern and priorities are loaded.
- Dial a matching value such as
2005. - Compare the caller's audio with the expected full or stripped value.
asterisk -rx "dialplan reload"
asterisk -rx "dialplan show _XXXX@demo-predefined-vars"
The inspection command should show the _XXXX pattern and its priorities in the selected context. If you are working with a running Asterisk CLI, console verbosity or debug logging can also help show the channel's execution path.
Troubleshooting
A four-digit call does not enter the example
- Verify that the endpoint is assigned to the context containing the pattern.
- Run
dialplan reloadafter editing the configuration. - Confirm that the dialed value contains exactly four digits.
- Check for a more specific or competing pattern.
- Use
dialplan show _XXXX@demo-predefined-varsto verify that the rule is loaded. - Enable console verbosity or debug logging while placing the test call.
SayDigits does not speak the expected value
- Confirm that
Answer()runs beforeSayDigits(). - Check that the expression is
${EXTEN}, not plainEXTEN. - Verify the number actually dialed by the test caller.
- Temporarily add
NoOp(${EXTEN})to observe the value in the Asterisk console.
The wrong number of digits is removed
- Remember that substring positions start at zero.
- Use
${EXTEN:1}to begin with the second character. - Compare the original and transformed values with
NoOp(). - Test with the known value
2005; the result of${EXTEN:1}should be005. - Confirm that the extension actually includes the access prefix you intend to remove.
An outbound call fails after prefix removal
- Log both the original extension and the final destination.
- Restrict the matching pattern to calls that really include the access prefix.
- Check that the resulting number meets the trunk's required format.
- Verify outbound route permissions and carrier number-normalization requirements before invoking
Dial().
Exam-relevant notes
CONTEXTidentifies the current dialplan context.EXTENidentifies the current extension value being processed.PRIORITYidentifies the current ordered execution step.${VARIABLE_NAME}expands a variable while an application argument is evaluated.- An underscore begins an Asterisk extension pattern, and
Xmatches one digit from 0 through 9. _XXXXmatches exactly four numeric digits.${EXTEN:1}starts at zero-based position 1 and removes the first character.- For
2005,${EXTEN:1}produces005. - Validate transformed destinations before sending them to a trunk or carrier.