Search the Asterisk Blog

Asterisk 14 ARI: Create, Bridge, Dial.

By Joshua Colp

Asterisk’s REST Interface (ARI) in both Asterisk 12 and 13 has the ability to originate (create) outgoing channels.  The functionality in ARI mirrors that of the “originate” CLI command, AMI action and dialplan applications.  In its use, it creates, in one operation, a channel that is setup, dialed, and directed to a location upon answer.  The big limiting factor is that all of these things happen in a single operation, and an answer is a required part of the process.

In Asterisk 14, much more flexibility is provided by splitting the operation in two parts: channel creation and channel dialing.

POST /channels/create

As you might imagine, the create operation will create an outgoing channel; but, unlike the regular originate operation, the channel will be immediately placed into your ARI application, without being dialed. While in the ARI application, you can perform operations on it that logically make sense. Any that don’t will respond with an error – don’t try to play a sound file to it, it hasn’t been dialed yet, silly. If your outgoing channel is the result of an incoming channel, you may want to connect the two in a bridge in case the outgoing channel provides progress in the form of media – inband ringing, or a friendly phrase saying the call could not be connected.

The operation takes a very slimmed down list of arguments in comparison to the origination one; just those required to create an outgoing channel and location information, nothing more. In fact, arguments controlling variables or caller ID are not present, as these should be set using the variable operation before dialing. You might also notice that you can not send created channels to the dialplan. This is because the dialplan, and dialplan applications, were not written to take into account created, but un-dialed channels, and thus do not support them. You can only send a created channel to an ARI application.

Early Bridging

The act of placing channels into a bridge before one has answered is referred to as “early bridging”. The bridging functionality in Asterisk has been changed to transparently, without any effort on your part, handle this case and do “the right thing.” You need only use the same operations that you would have used previously on answered channels to add them to the bridge.

A common scenario would be the following:

  1. Create an outgoing channel
  2. Set variables and callerid on the outgoing channel
  3. Create a bridge
  4. Add the calling channel to the bridge
  5. Add the outgoing channel to the bridge
  6. Dial the outgoing channel

This mirrors that of Asterisk’s Dial() application and ensures that any early media is conveyed. Building on this as a base allow you to implement many of the features of app_dial or even create new ones more easily.

POST /channels/{channelId}/dial

Once a channel has been created and you have performed any operations you want on it, you can actually perform the dial operation by calling “dial” on it. Dial places the actual outgoing call and you will receive events as they occur.

Give It A Try

As of this writing Asterisk 14.0.0-beta1 is available which includes this functionality. If you’ve been wanting more control over the dialing process in your ARI application, the future is now. If you experience any issues please submit an issue on the issue tracker so we can squash it before release.

There Are 10 Comments

  • Dovid says:

    Does this mean that I can finally replace AGI’s with ARI?

    • Joshua Colp says:

      That depends! As ARI doesn’t provide access to run arbitrary dialplan applications you have to use the primitives provided to do what you need. If they fit your needs – then yes!

  • Fabio says:

    Hi Joshua,
    Currently I have Asterisk 11 running on a production server and communicating with my c++ application on linux using AMI / ARI.
    2 weeks ago I installed Asterisk 13 in another server to check if I can upgrade my production server from Asterisk 11 to Asterisk 13 and use the ARI communication. So in order to evaluate that, i created a client application using c++. Unfortunatelly it is very hard to find examples on c++, but i managed to make it work. I created the following archtecture:

    1- WebSocketClient which performs the handshake with Asterisk 13 (i.e.)
    “GET /ari/events?api_key=fabio_ari:123&app=hello-fabio”
    “GET /ari/events?api_key=fabio_ari:123&app=hello-fabio HTTP/1.1 \nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: IidMJmdoGe4kYu0+1VlrvQ==\nSec-WebSocket-Version: 13 \n\n”

    2- For all the other operations I use an httpClient i implemented to send POSTs, DELETEs, etc… For example the Originate
    “POST /ari/channels?endpoint=PJSIP/111&extension=s&context=fabio_test HTTP/1.1”

    Sorry for this information. Everything is working fine so far. I am able to create channels, bridges, hangup on a channel, shutdown a bridge, etc…

    In fact I only have one question for you.
    Can I use only the WebSocket connection for everything?
    I mean, can i send POST, GET and DELETE using my websocket connection with Asterisk? Or do I need to use a connection for each POST, GET, … using an HTTP Client?

    I really want to understand what should i implement in my application. So far i couldn’t start an Originate thru the websocket, I can only do it using HTTP. When it gets to the DialPlan and I call the STASIS then i get updates for that channel on my websocket. But still, I need to know if i really need to send those HTTP messages.

    Thanks in advance!
    Fabio

    • Joshua Colp says:

      The WebSocket connection is strictly for events from Asterisk to applications. It can not currently be used for sending commands, these have to be done using a HTTP client with HTTP requests.

      • Fabio says:

        Thanks Joshua for the quick response and confirmation.

        • Fabio says:

          Hi Joshua,
          Is there a command to destroy all bridges in CLI ?
          Or the only way is using ARI and GET all bridges and do a DELETE on each one of them?

          I would prefer a quick command to run in CLI to delete all the bridges like “hangup request all” for the channels.

          • Joshua Colp says:

            There is no CLI command to do this, it’s up to the ARI application to do so as it has ownership.

    • Daniele Pallastrelli says:

      Hi Fabio,
      if you’re using modern C++ you could have a look at my library aricpp: https://github.com/daniele77/aricpp

      • Fabio says:

        Hi Daniele,
        Thanks very much for sharing your library. It looks amazing, congrats ! When I started developing it, I couldn’t find any good examples in c++ and I am glad you shared that with me.

        It shows me I chose the correct approach when using boost::asio and boost::beast. I was afraid of using boost::beast as it is not released yet with latest boost, but I read it will be released in the next version (probably available on december). Anyway I am already using it and it looks good enought for me so far.

        I am using c++11 but its only a tech example to prove/test Asterisk 13. I am testing performance against Asterisk 11 and so far I am getting very good results.
        Have you performed such high load tests ?

        Thanks in advance,
        Fabio Carvalho

        • Daniele Pallastrelli says:

          Hi Fabio,

          these days I’m just writing a post for this blog that will explain in detail the design choices of the library (e.g., boost, beast, async architecture) and the performance issues I encountered.

          To cut it short:

          I chose beast because it’s the only http/websocket asynchronous library available and because it follows boost ASIO idioms. Actually, I find the API poor designed and error prone, but I hope they will improve it when finally beast will become part of boost 1.66 .

          I did stress tests using a sip load generator (sipp) and asterisk 14. Unfortunately, I couldn’t reach a high rate of calls per seconds because of a “performance bug” I discovered in asterisk sources. I opened a ticket for that:
          https://issues.asterisk.org/jira/browse/ASTERISK-26771
          basically, in the worst case, ARI http requests can take 200ms to be taken into account by asterisk.
          So, I basically could use the sip traffic generator only to prove my library is correct, but not to optimize aricpp for speed.

Add to the Discussion

Your email address will not be published. Required fields are marked *

About the Author

Joshua Colp

Joshua Colp is a Senior Software Developer at Digium and a long time Asterisk developer. He originally started in the community submitting simple patches and grew into improving and creating new core components of Asterisk itself. He is a self-taught programmer who believes in finding the balance between doing things the way they should be done and doing what is right for the people using the software. In his spare time he enjoys smashing fax machines.

See All of Joshua's Articles

More From
The Digium Blog

  • No items