Note: I have a much updated version that I am working on posting here. The following remains for archival and theoretical purposes only.
I've been playing with Asterisk for awhile now. In hooking it to Icecast and Liquidsoap, I needed to come up with some sort of management system for the conference calls.
Meetme Manager really didn't fit the bill. I liked the available controls but hated that you had to click on something to update the page. This meant either a local GUI or an Ajax-driven web interface.
Luckily, John at Asterikast had played with an Ajax (I think it's Ajax) interface which maintains a connection to the Asterisk Management Interface (AMI). The drawback to John's script is that it hasn't seen an update since he posted the code last March. I did like the baseline code though, so I've made a few changes.
The major revisions are in the output.php file and secondary functions. John's files seemed to contain a lot of code to perform just a few functions. I've heavily edited that so that it now recognizes local connections and miscellaneous SIP connections that didn't meet the original filter constraints. John's original code only allowed for kicking users. I've added a few more functions like mute/unmute and some miscellaneous Icecast stream management.
The Kick and Mute/Unmute buttons are kinda obvious. The "Muzak" button starts playing music into the conference room. The stream button starts streaming the conference room to a local Icecast server. The "trick" behind these last two buttons is the "Originate" function call in the AMI.
This picture is included to display the disparate call types that the code works with. That's two local internal connections, one SIP call from the local network, and a number of IAX2 calls from cellphones and SkypeOut, via IPKall and FWD. (Yeah, I call Washington State to connect to my own machine in Virginia Beach. What the heck, it doesn't cost extra...)
The power behind the tool is the Asterisk Manager Interface (AMI). This code connects to the AMI on port 5038 and passes commands to it/pulls various statuses from it. Following are examples of various functions. Please note that command sequences sent to AMI must have a double carriage return to signal AMI that the command should be processed. To get a list of all of the available AMI commands, connect to asterisk (via "asterisk -r") and type "manager show commands".
Telneting to port 5038 returns the following:
joat@localhost:~/Desktop$ telnet localhost 5038 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. Asterisk Call Manager/1.0
To following is an example of authenticating to the interface. Hint: The first "paragraph" (in this case, four lines) is what you type. The last "paragraph" (in this case, two lines) is the response from AMI.
Action: login Username: joat Secret: phone Events: on Response: Success Message: Authentication accepted
The "Events" setting lets AMI know if you want any events to be displayed via AMI. If you're scripting a control interface, you may want to change this to "off".
To log off, use the "Logoff" action:
Action: Logoff Response: Goodbye Message: Thanks for all the fish.
To list the channels connected to Conference Room #200, use the "meetme list" action:
Action: Command Command: meetme list 200 Response: Follows Privilege: Command User #: 01 701 Tim-1 Channel: SIP/701-b6d13438 (Admin Muted) (unmonitored) 01:37:22 User #: 02 <unknown> Music Stream Channel: Local/202@stream-6464,1 (unmonitored) 01:17:01 2 users in that conference. --END COMMAND--
To set a variable, use the "SetVar" command:
Action: SetVar Channel: SIP/701-b6d13438 Variable: topic Value: bob from cincinati, computer won't shut down
Response: Success Message: Variable Set
The "Channel" setting affects the scope of the variable. If "Channel:" is included, the variable's scope is limited to the specific call channel (i.e., the variable is destroyed once the call goes away). If "Channel:" is omitted, the variable becomes global.
To retrieve a variable, use the "GetVar" action:
Action: GetVar Channel: SIP/701-b6d13438 Variable: topic Response: Success Variable: topic Value: bob from cincinati, computer won't shut down
To disconnect a specific call, use the "Hangup" action:
Action: Hangup Channel: SIP/701-b6d13438
Response: Success Message: Channel Hungup
If you have "Events" turned on, you should also see the following:
Event: MeetmeLeave Privilege: call,all Channel: SIP/701-b6d13438 Uniqueid: 1196601811.21 Meetme: 200 Usernum: 1 CallerIDnum: 701 CallerIDname: Tim-1 Duration: 6836 Event: Hangup Privilege: call,all Channel: SIP/701-b6d13438 Uniqueid: 1196601811.21 Cause: 0 Cause-txt: Unknown
If you have music on hold force to play on a specific extension, and you have a conference room attached to another extension, say via the following in extensions.conf:
exten => _201,1,Answer exten => _201,2,Wait(1) exten => _201,3,MeetMe(200||66677) exten => _202,1,Answer exten => _202,2,Wait(1) exten => _202,3,MusicOnHold(manual)
You can then push music into the conference room via the "Originate" action:
Action: Originate Channel: Local/202@stream Context: stream Exten: 201 Priority: 1 CallerID: Music Stream Response: Success Message: Originate successfully queued
If you have "Events" turned on, you'll also see many, many lines of follow-on information (too many for here).
To mute someone, use the "MeetMeMute" action:
Action: MeetmeMute Meetme: 200 Usernum: 03 Response: Success Message: User muted
If you have "Events" turned on, you'll also see:
Event: MeetmeMute Privilege: call,all Channel: SIP/701-b6d13438 Uniqueid: 1196608655.30 Meetme: 200 Usernum: 3 Status: on
To unmute them, use the "MeetmeUnmute" action:
Action: MeetmeUnmute Meetme: 200 Usernum: 3 Response: Success Message: User unmuted
If you have "Events" turned on, you also see:
Event: MeetmeMute Privilege: call,all Channel: SIP/701-b6d13438 Uniqueid: 1196608655.30 Meetme: 200 Usernum: 3 Status: off
If you have extension 200 configured to stream to a local Icecast server, say via:
exten => _200,1,Answer exten => _200,2,Wait(1) exten => _200,3,Ices(/etc/asterisk-ices.xml)
You can then tell AMI to start streaming the conference to the Icecast server via the (again) "Originate" action:
Action: Originate Channel: Local/200@stream Context: stream Exten: 201 Priority: 1 CallerID: Conference Stream Response: Success Message: Originate successfully queued
If you have "Events" turned on, you'll also see many, many lines of follow-on information (too many for here).
The following allows you to transfer (redirect) a call to somewhere else in your dial plan:
Action: Redirect Channel: Local/200@stream Context: stream Exten: 207 Priority: 1
Here's a screenshot of use of the above:
The above probably needs a bit of explanation. The panel to the right is generated by a Perl script and a MySQL database. Basically, it's a phonebook and has the ability to connect the conference room to wherever. The green note is from the Internote plugin for Firefox. The warning blurb at the bottom of the left-hand side is there because I've sometimes leave the interface open for friends to use. Some of those friends suffer from a need for immediate response (forgetting that calls take time to negotiate and erect). If you've seen me in TalkShoe lately, this is what I've been connecting through.
That's it for now. All of the AMI commands above are what I used to create the PHP interface. I'll continue to play with the interface. Things that I want to add: a call queue, recording start/stop, being able to edit to edit the "topic" via the interface, and more. I'll attempt to document them here.
1) I've found a bug in the original script. Where the calling script had "Exten: Local/201", change it to "Exten: 201".