This week’s #FridayFun focuses on one single field in the fpbx GUI. After creating an extension, if you edit it and browse to the ‘Advanced’ tab, scroll down a bit, you’ll see a field labeled ‘Dial’, this one
The tool tip admonishes us all not to touch it unless we know what we’re doing. If FreePBX was developed in the early age of navigation, the tool tip would say “Here be dragons”. Let’s ignore the dragons and sail on …
All of what follows ignores the existence of Device and User mode, a largely forgotten but still used aspect of fpbx operation that is now discouraged. I suspect none of this is compatible with D&U mode.
The capture above defines the device dial string for extension 5002. Whenever a call is destined for extension 5002, it is this field’s value which tells Asterisk how to get ahold of that device. So if I pick up extension 5001 and dial 5002, at some point in the dial process a log line is generated that looks like this:
-- Executing [5002@dialOne-with-exten:1] Dial("PJSIP/5001-0000002f", "PJSIP/5002 ... rest removed for clarity
And from the Asterisk console, we can query the AstDB and determine this string value
tangopbx5*CLI> database get AMPUSER 5002/device
Value: 5002
tangopbx5*CLI> database get DEVICE 5002/dial
Value: PJSIP/5002
The asterisk dial command is capable of taking more than a single endpoint separated by the &
character, so lets try that. I have extension 5001 on the same system, lets throw that in the GUI dial field:
tangopbx5*CLI> database get AMPUSER 5002/device
Value: 5002
tangopbx5*CLI> database get DEVICE 5002/dial
Value: PJSIP/5002&PJSIP/5001
and the console output
-- Executing [5002@dialOne-with-exten:1] Dial("PJSIP/5001-00000037", "PJSIP/5002&PJSIP/5001 .... removed
With the above change in place, any call to 5002 results in both 5001 and 5002 devices ringing. The first one to answer wins. This is just a proof of concept though, as there are probably 10 different ways of doing this in a more supportable way via the GUI
What it can be used for safely is to run dialplan in parallel with a call to the device, as long as that parallel dialplan does not answer the channel and interrupt the call going to the user’s device.
Let’s see what this does:
tangopbx5*CLI> database get DEVICE 5002/dial
Value: PJSIP/5002&LOCAL/5002@test-context
After the apply config, a call to 5002 now shows this console output
[2025-07-11 15:21:21] NOTICE[1438197][C-0000001f]: core_local.c:741 local_call: No such extension/context 5002@test-context while calling Local channel
-- Couldn't call LOCAL/5002@test-context
So that would have worked, had the exten and context actually existed, so lets create it by adding this to /etc/asterisk/extensions_custom.conf
[test-context]
exten => _X.,1,Noop(Entering user defined context test-context in extensions_custom.conf)
exten => _X.,n,Noop(Calling party is: ${CALLERID(number)})
exten => _X.,n,Noop(Called party is: ${EXTEN})
exten => _X.,n,Hangup
After doing an apply config (or dialplan reload) you see this at the Asterisk console when calling 5002:
-- Called LOCAL/5002@test-context
-- Executing [5002@test-context:1] NoOp("Local/5002@test-context-00000002;2", "Entering user defined context test-context in extensions_custom.conf") in new stack
-- Executing [5002@test-context:2] NoOp("Local/5002@test-context-00000002;2", "Calling party is: 5001") in new stack
-- Executing [5002@test-context:3] NoOp("Local/5002@test-context-00000002;2", "Called party is: 5002") in new stack
-- Executing [5002@test-context:4] Hangup("Local/5002@test-context-00000002;2", "") in new stack
This is a pretty lightweight way of running your own dialplan when an extension is called. There are two caveats:
- If you’re set things up like above with both the device and a local channel, then the custom dialplan can’t answer the ringing channel or the call to the user’s device will fail.
- You don’t have an unlimited amount of time to run your custom dialplan. Asterisk performs the
DIAL
to both endpoints more or less simultaneously, but as soon as any of the endpoints responds with anANSWER
then all other channels are canceled. For the example above, the custom dialplan really needs to finish and hangup before the user’s device answers the channel.
If the caveats are an issue, or if you find yourself editing a lot of dial strings, then you’re probably in dialplan hook territory, in which case you can ignore this thread and instead read up on how to be a first rate hoooker here.