app_dial is one of the most (if not THE MOST) useful Asterisk applications. ARI extends the ability to control and interact with existing channels and bridges, in ways that were beyond horrific in previous versions. However, due to the stateful and synchronous nature of app_dial, re-implementing it with ARI is somewhat of a challenge. Further than that, as PHP is a single threaded environment, supporting multiple calls using a single PHPARI application isn’t a straight forward task. This question had been bugging me for a while now, and following a few hours of realizing what dial should actually do – I managed to cook up a simple wireframe for implementing app_dial using ARI.
How does it work?
Let’s understand one thing first, the original asterisk application (app_dial) was totally synchronous and as it was working inside a thread of its own, it was a fairly self contained environment. Sure, it was able to access variables and global variables, however, it was still confined to its own work space. A PHPARI script is a self contained environment, however, if you don’t pay attention to what you’re doing, it’s very easy to have 2 (or more) calls influence each other – specifically if you are using global variables.
The simplest way to solve this is using a form of in-memory data store – or in our case, an array that is used as a hash map. Our array is called:
The trick is to understand the relations between the channels and how they interact.
The application can be activated in two manners – with arguments or without arguments. It currently accepts two arguments – an endpoint and a timeout (seems familiar, no?). When the application is triggered from the dialplan, it will call the StasisStart event, executing the following code:
When the application is activated from the dialplan, it will automatically generate a ringing tone to the calling party and originate a call to the second party.
Pay attention to the activation of the application from within originate, there are no arguments now. For this application, activation without arguments indicate a connection from the second channel, and should be handled by this code:
Pay attention to how StasisEnd is handled, to verify that our memory, channels and bridges are cleared accordingly:
And there we have it – app_dial re-implemented using PHPARI.