Working with the manager API and its limitations
After battling with the Asterisk Manager interface(and getting it to pretty
much do everything I want to do with it) I thought I’d share my experiences
with those who are developing or are thinking of developing applications
using it.
First here’s a list of some of the things the manager interface will let you do:
- Dial a call from any extension/resource to any other extension/resource,
some examples:
- initiate a call from a sip phone to external zap line
- initiate a call from an extension number to an external iax extension
- initiate a call from within a meetme room to a zap channel
- Redirect ANY live call to ANY destination, some examples:
- take a live SIP call from whereever it is connected and send it to a meetme room
- take a zap call from a meetme room and send it to an extension
- take a ANY call and redirect it to an outside Zap channel
- as an alternative to parking, just dump a call to a long background sound file or MoH and then retrieve it later by redirecting their channel somewhere else
- Hangup any live channel whether it be SIP, Zap, IAX, H323, etc…
- Hangup individual channels within a meetme conference
- Initiate a recording(and stop it too) of any live Zap channel at any time(with custom filename)
- Get the status of voicemail in any mailbox
- Get the status of an extension
- – Get data from commands such as “show channels”
- Get data on Queues
- Get data on IAX peers
Second, here are some things you should know if you are going to program for the manager interface:
- The manager API is not well documented(Yes I know I need to add my notes to the wiki)
- All connected terminals will receive all “Events” that happen on the Asterisk box
- Not all Asterisk commands will be accepted with the “Action: Command” action
- Disconnecting the connection between a remote connected terminal and the Asterisk box will often cause a deadlock (https://issues.asterisk.org/jira/browse/ASTERISK-855) <<<–This bug has been reported fixed on 2-07-2004
- Any form of freeze on the connected terminal will cause a buffer overflow and will also deadlock Asterisk
- “Status” Actions can yield upto a hundred lines of output depending on how busy your Asterisk machine is.
- “Ping” and “Show uptime” may not return results in some applications(like perl Net::Telnet)
- generally for applications where you will be sending under a hundred commands daily, the manager interface will work well and shouldn’t cause any crashes/deadlocks.
- for applications where you could be sending over a thousand manager commands to an Asterisk server from different client machines daily you will almost definitely have at least one crash/deadlock happen per day.
- you can connect to the asterisk manager interface through any programming language that has a socket IO implementation(C, Python, Perl, PHP, etc…)
- you can program an AGI to use the manager even(it you really wanted to)
How I solved my crash problem:
I had a problem, I was using the manager interface through over 30 desktop machines to do a high number of redirect, originate, recording, hangup and command actions to the tune of over five thousand commands per day. This lead to upto 4 crashes/deadlocks per day on one of my Asterisk servers. That’s when I started to look hard at a centralized manager queue. After some initial testing I determined that the best way for me to process all of these actions was to have a database driven system by which two constantly running scripts would separately send and parse
manager actions and events. Here’s how the steps proceed on an Originate command:
- client inserts an Originate record into the queue table (with a unique Callerid value)
- action_sender application grabs the new record, submits the action and marks the record as SENT
- manager_listen application parses every line of manager output and sends blind UPDATE commands to the database based on the action CallerID field and/or the uniqueid field for a key – in the manager interface the callerid field can be unique to the call as sent into the manager
- client can grab the uniqueid and channel values out of the database now that the record has been processed
Under this process there is no risk of losing a manager connection on the
client machine, all manager connections exist on the localhost Asterisk
machine. Also, there is very little lag in processing actions through this
model even on a busy machine.
My suggestions for improving the manager interface:
- make it more fault tolerant, I can live with the querky API and data formatting, but buffer overflows and not killing inactive connections causing crashes/deadlocks is VERY bad.
- make a simple manager action file parser(sample.action), something like the sample.call interface except for manager actions, for output you can have the manager generate a sampleaction.out file that would have the output for that specific command on it. Many people that currently use the sample.call format would love to have a simple way to add manager functions to their apps that already generate sample.call files
- make a transaction-based send-receive protocol, something like the HTTP protocol. This would be a lot more involved than the sample.action idea, but it is probably a step in the right direction for the future of Asterisk (this one isn’t my idea, “jayson” is working on thishttps://issues.asterisk.org/jira/browse/ASTERISK-119)
Well, that’s the end of my rambling for now, hope this helps.
MATT–
A Note About Busy
(Joel Rowbottom, joel <at> enovi <dot> com)
Annoyingly, the Manager API doesn’t seem to return ‘Busy’ at all – instead just giving back a Hangup with no result codes.
See Also
Go back to Asterisk manager API