Asterisk Asynchronous AGI

I have been coding some new stuff for Asterisk lately, but the feature I like the most is Asynchronous AGI. I got the idea from MAGI, an old patch written by David Pollak that allowed AGI execution thru the manager interface. For those ignoring what AGI and AMI are, go read:

Asterisk Gateway Interface ( AGI )
Asterisk Manager API ( AMI )

So, my patch, allow users to execute AGI commands using “Action: AGI” and get the response reading “Event: AsyncAGI”. The manager header “CommandID” can be specified to match up the responses. Let’s see an example

In extensions.ael you would put something like this:
context sample-async-agi {     test => {         AGI(agi:async);     }; };
That will put the channel to wait AGI commands. The channel will NOT do anything but wait for Hangup or any AGI command you ask it to execute. AGI commands can arrive from 2 sources. The most important and useful source of commands is the manager, but with my patch you can also execute AGI from the command line. Let’s see how it is done from the manager:
# telnet localhost 5038 Action: Login Username: test Secret: test Action: AGI Channel: SIP/33-blah Command: EXEC Playback tt-monkeys CommandID: MyCommandID

That would cause Asterisk to execute the “Playback” application on channel SIP/33-blah, which MUST be in AGI(agi:async) application. After executing the command you will be able to read an event with the AGI response url-encoded. If the channel is not in Async AGI, the command will not be executed and you will get an error response.

As I said, you can use the command line to execute Async AGI as well, just like this:

tcore*CLI> agi exec SIP/testing-09a5b960 “EXEC startmusiconhold”
tcore*CLI> agi exec SIP/testing-09a5b960 “EXEC stopmusiconhold”
tcore*CLI> agi exec SIP/testing-09a5b960 “EXEC Dial(Agent/23)”

That will start MOH, then stop it, and finally will dial to the Agent 23. This means you can implement a Queue without using native buggy Asterisk queues. You can receive calls and send them to Async AGI to put them on hold, then, when you detect availability of some of your Agents, Dial() to that agent.

If you want to learn more about this feature here is the mantis bug entry: http://bugs.digium.com/view.php?id=11282.

If you want the patch back-ported to 1.4, I have one here: http://www.moythreads.com/asterisk-1.4.15-async-agi.patch

In case you find this patch useful, please try it in trunk as well and provide feedback in mantis. Even when some people has found this patch useful, some of the top developers at asterisk-dev are hesitating in accepting it because similar results can be obtained thru the use of FastAGI, however, me and other people at asterisk-dev are trying to prove the patch also makes easier the implementation of some applications.

This is a hot discussion we got some weeks ago about it: http://lists.digium.com/pipermail/asterisk-dev/2007-December/031046.html

See you!

16 Responses to “Asterisk Asynchronous AGI”

  1. SinoLogic » Cómo ejecutar AGI de forma asíncrona Says:

    […] http://www.moythreads.com/wordpress/2007/12/24/asterisk-asynchronous-agi/   Autor: Elio Rojano | Asterisk, Curiosidades | Permalink | Comentarios […]

  2. el_pop Says:

    Why no “ActionID” in place of “CommandID”?. In all Manager commands is used “ActionID”. only to have a homogeneus notation with AMI.

  3. moy Says:

    The “CommandID” header is independent of the “ActionID” header. This means you can actually specify both. ActionID is used internally by the core AMI system, so you will get an AMI packet with the specified ActionID as soon as the command enter the Async AGI queue. The “CommandID” will be sent as part of an AsyncAGI event to notify execution of the command, hence, you can add 3 commands in a row and get almost immediate response with the proper ActionID, but the CommandID will only get back until the each queued command gets actually executed.

  4. Asterisk-Java Says:

    Preview: Support for AsyncAGI

    I’ve just finished adding support for Asynchronous AGI to Asterisk-Java. The way AsyncAGI is supported by Asterisk-Java hides the differences in the underlying communication from the differences in the underlying communication from the users of our l…

  5. manuna Says:

    Last days i tried to make something usable with AsyncAgi (using Asterisk-Java). It’s a nice thing, but really undocumented over the internet.
    The question is: what’s the simplest way of replacing FastAGI server with AsyncAGI server? I guess, all AGI scripts can be left intact, but i don’t quite understand, how should dialplan look like.

    ie, Fastagi call looked like:
    123 =>{
    AGI(agi://hostname:4567/scriptname?param1=val1&param2=val2);
    };

    How should this be implemented with AsyncAGI?

  6. moy Says:

    You are correct in that it’s quite undocumented. Sorry about that, I will fix that as soon as I have a chance, I will add an entry into voip-info.org

    Even when anything you can do through FastAGI you can do it as well throug Async AGI, the client code has to change quite a bit since now, froma single connection you have to be aware of ALL channels, not of a single channel. This brings power but also complexity when dealing with many channels.

    Currently you cannot pass parameters directly to AsyncAGI, but you can

    Set(param1=val1)
    Set(param2=val2)
    AGI(agi:async)

    Then from your manager connection
    Action: AGI
    Command: GetVariable param1

    However I agree is easier to just pass parameters, so I will add that support.

  7. manuna Says:

    Will this be implemented in a way like:
    AGI(agi:async/scriptname?par1=val1&par2=val2…) ?
    For me it’s crucial to determine scriptname, because my FastAGI server processes different kinds of scripts, depending on extension dialed.

  8. moy Says:

    Then probably AsyncAGI is not for you.

    What you don’t seem to understand is what I just said to you, AsyncAGI HANDLES ALL THE CHANNELS THROUGH THE MANAGER, there is no such thing as an execution script (sure thing probably there will be manager connections controled from scripts, but that’s outside the AsyncAGI scope to know). That’s what “Async” means, Asynchronous.

    When you execute a script via FastAGI that script will control the channel during the life of the script, your script just takes care of that single channel and when you execute an AGI command your script “blocks” its execution until the command finishes.

    AsyncAGI just puts the channel to wait for Asynchronous AGI commands, where those commands will come from? is up to you. In my case I had a program that connected to the Asterisk manager and handled all the channels, so I had a single script that worked pretty much like a PBX in a scripting language, took care of knowing which channels were active and what to do with ALL of them, bridging them, un-bridging them, put in them in conferences, play audio etc.

    If you do anything at all with Async AGI you will have to understand event-oriented programming, because that’s how you do to control channels over AsyncAGI.

  9. manuna Says:

    Sorry, i’ve really misunderstood the way it works. My mind was that asynchronous channel can execute some AGI script (determined in dialplan), meanwhile being able to receive and execute asynchronous commands (from an external AMI application). So the initial script sets up a call, and later on it can be asynchronously bridged, put on hold, etc.

  10. cyr2242 Says:

    I’m pulling it up because I’m interested on it. I have written some asynchronous voice and telephony application for years and this AsyncAGI almost meets my expectations about a 3rd party call control for Asterisk, but IMHO there’s a lack:
    If I’m playing an announcement for a wait on queue functionality … how can I stop the announcement when an agent (I have my own implementation for agents in my application) becomes free before redirect him the call? I can’t see any AGI command like stopPlay.
    I know your AsyncAGI relies on AGI, so this lack for a stop function isn’t a FastAGI’s fail but I suppose you have already thought about it before me. I would appreciate some hints about it in order to becoming the use of AsyncAGI in something as useful as I think it would be.
    Thanks

  11. moy Says:

    Hello,

    The problem you mention is addressed by redirecting the channel, you can do that with the manager Redirect action (I have not used Asterisk lately, but I expect that action to still be named the same), the truth is that behind the scenes, a Redirect causes a hangup of the channel, but the call stays alive in a new channel (this process is known as masquerade), this will break your channel out of any application (Playback, Dial, etc) and return control to the dial plan. This is useful for you to Redirect the channel to the one and only Async AGI control loop (ideally in my ideal system there is only 1 Async AGI loop) and then you can proceed to Dial() to the free Agent.

    Let me know if this crappy explanation was not enough.

  12. cyr2242 Says:

    Hi,
    redirecting caller’s channel (listening a playback in AGI) to agent’s channel was the first thing I tried but I got a disconnection on my device (caller’s channel) so I thought it wasn’t the right way. However your approach redirecting the call to AGI again, then Dialing to the agent, could be work. I’ll give it a go.

    Thanks for the hint

  13. moy Says:

    mmm, I don’t see why you would get a hangup, I’d like to see the debug output of such scenario.

  14. cyr2242 Says:

    Hi, I just do it. You can find an output for that scenario in:
    http://docs.google.com/Doc?id=ahfnfrcrh3rr_29863zkwc2
    Regards

  15. moy Says:

    I see, thanks a lot for the detailed explanation, in order to determine where the problem is I need the debug output of Asterisk itself, not just the manager. That is, enable debugging in /etc/asterisk/logger.conf and pastebin.com the output of a success and failing scenario just as you did with the manager output.

    What do you say if we take this conversation to asterisk-users mailing list? just let me know the name of the thread name when you send it and I will continue answering there.

  16. cyr2242 Says:

    great, I posted the DEBUG output at:
    http://lists.digium.com/pipermail/asterisk-users/2009-March/229524.html
    I see you there

Leave a Reply

You must be logged in to post a comment.