Dynamic Conferences with Asterisk

I recently had a play with conference calling in Asterisk. It's pretty easy to use the built in applications in combination with the asterisk-extra-sounds sound libraries to produce quite a professional feeling conferencing system.

One of the things people most often ask for in a new Asterisk installation is the ability to host teleconferences (essentially multi-way phonecalls). Asterisk offers a flexible way to achieve this.

I'll be using Asterisk 13 (the latest and greatest at the time of writing), but there shouldn't be too much difference for earlier Asterisk versions.

ConfBridge or MeetMe?

Asterisk ships with two conferencing applications - MeetMe (app_meetme) and ConfBridge (app_confbridge). ConfBridge has now pretty much replaced MeetMe in terms of functionality, but there might still be a few cases for using MeetMe. This post will cover ConfBridge, since that seems to have become the most accepted tool in newer versions of Asterisk (11+).

It should also be said that MeetMe requires DAHDI for a number of internal tasks such as timing and channel mixing, so that may restrict you from using it in some situations where you don't want to run your Asterisk installation with DAHDI.

Setup

I'll assume we've already got Asterisk installed and operational.

Now, we're British, so Allison is much too American for our liking - as lovely as her voice is. Joking aside, the en_GB prompts are more suitable for UK companies. You can download a wide variety of sounds from the Asterisk Downloads site for free. For this example, we'll need the asterisk-extra-sounds-en_GB sound archive to be extracted to a sounds/en_GB/ directory in the astdatadir directory (typically /var/lib/asterisk).

You should choose the codec that fits the one used in the environment for which you're setting up Asterisk. If you're not sure, alaw is a safe enough bet.

Configuring ConfBridge

ConfBridge is configured in confbridge.conf in your Asterisk configuration directory (typically /etc/asterisk). The configuration file can define three types of entity: Conference Bridge Profiles (type=bridge), User Profiles (type=user) and Menus (type=menu).

Conference Bridge Profiles

A Conference Bridge Profile defines a template for conferences created with that profile. Here is the simplest possible Conference Bridge Profile:

[my_bridge]
type=bridge  
language=en_GB  

This just defines a Conference Bridge Profile with the language set to en_GB, meaning the IVR (Interactive Voice Response) prompts used for conferences using this Conference Bridge Profile will use sounds from the sounds/en_GB/ subdirectory under the astdatadir directory configured in asterisk.conf (usually /usr/share/asterisk/).

The Asterisk Wiki has information about the possible options for Conference Bridge Profiles.

User Profiles

A User Profile defines a template for users joining a conference. It includes configuration for how the user should be treated by Asterisk at various parts of the conference lifecycle. For instance, the music_on_hold_when_empty option controls whether or not users with this profile should hear music-on-hold if they're in an empty conference.

Here's a simple User Profile:

[my_user]
type=user  
music_on_hold_when_empty=yes  
announce_join_leave=yes  

Users with this profile will also be asked to say their name when they join a conference, and their name will be announced by Asterisk to the rest of the conference right before they're added.

As before, the Asterisk Wiki has information about the possible options for User Profiles.

A Menu defines the buttons that a user can press while they're in a conference call, and what those buttons do. You do as much or as little as you want here. I like to allow the user to adjust their listening volume and to mute and unmute themselves, so here's a menu to do that:

[my_menu]
type=menu  
*=playback_and_continue(press&digits/1&confbridge-dec-list-vol-out&press&digits/2&confbridge-inc-list-vol-out&press&digits/3&confbridge-mute-out&confbridge-menu-exit-in&press&digits/0)
*1=decrease_listening_volume
1=decrease_listening_volume  
*2=increase_listening_volume
2=increase_listening_volume  
*3=toggle_mute
3=toggle_mute  
*0=no_op

This might seem a little complex, but it's actually straightforward.

When a user presses *, Asterisk will execute the * menu item - playback_and_continue(...). The string between the parenthesis is a concatenation of the sounds that should be played to the user. The sounds will read: "Press 1 to decrease the listening volume. Press 2 to increase the listening volume. Press 3 to mute or unmute yourself. To exit the menu, press 0."

If the user presses an option after pressing *, the relevant option (*1, *2, *3 or *0) will be executed. If the user presses an option without first pressing *, the relevant option will be executed (1, 2 or 3).

The Asterisk Wiki has information about the other options you can present to users in conference menus. There are even special admin options that you can offer to users with the is_admin flag set to 1 in their User Profile.

Creating a Conference

Once you've configured a Conference Bridge Profile, a User Profile and a Menu, you can start creating conferences based on them.

There are a lot of different ways you may want to do this. I'll be detailing the easiest (in terms of user effort) way - dynamic conferences. These are conferences that require no setup beforehand. A user dials a special extension, is given a conference number which they can then share with other parties. The other parties can enter that number somewhere else in the system (either by dialling an extension and entering it when requested, or by dialling the conference number itself).

Initiating a Conference

First, we'll create an macro that will initiate new conferences:

[macro-create_conference]
; Start off with a random conference number between 9001 and 9999
exten => s,1,Set(__CONFERENCENUM=${RAND(9001,9999)})

; If it already exists, jump back and increment it again
same => n,GotoIf($[${GROUP_COUNT(${CONFERENCENUM}@conference)} > 0] ? 1)

; Mark it as existing.
; For the observant, yes there's a race condition here, but the number of concurrent conferences will probably be low
same => n,Set(GROUP(conference)=${CONFERENCENUM})

; Tell the user which conference this is
same => n,Playback(conf-youareinconfnum)  
same => n,SayDigits(${CONFERENCENUM})

; Create the conference using the "my_bridge" Bridge Profile and "my_user" User Profile 
same => n,ConfBridge(${CONFERENCENUM},my_bridge,my_user)  

Then we'll create an extension that users can call to initiate a new conference:

exten => 9000,1,Macro(create_conference)  

That's it - users can create conferences by calling the 9000 extension. Here's an example of what that sounds like for a user:

Dialling In

Now we need a way for users to enter existing conferences.

First, we'll write a macro that requests a conference number from the user and then dumps them into that conference if it exists:

[macro-join_conference]
; Ask the user to key in their conference number, then read the 4 DTMF digits
exten => s,1,Read(CONFERENCENUM,enter-conf-call-number,4)

; Check if the conference doesn't exist, if so, go to statement 10
same => n,GotoIf($[${GROUP_COUNT(${CONFERENCENUM}@conference)} == 0] ? 10)

; Dump the user into the conference
same => n,ConfBridge(${CONFERENCENUM},default_bridge,admin_user)

; Tell the user they entered an invalid number and take them back to the top to try again
same => 10,Playback(conf-invalid)  
same => 11,Goto(1)  

With the macro in place, we can call it from anywhere we need to. For instance, straight in an inbound context for users dialling in to a dedicated conference call number:

[inbound_calls]
exten => 5554202,1,Macro(join_conference)  

This way, users dialling in on the 5554202 extension will be given the option to join a conference by keying in their conference number. Here's an example of how joining a conference sounds to a user:

Note that you can't hear the DTMF tones of the keys I'm pressing when I enter the Conference Number here because they're being sent as NTEs (Named Telephone Events) in the RTP data stream (see RFC 4733), not as in-band audio tones as you might expect with a traditional telephone. Asterisk will handle tones arriving in-band just fine too (for instance from a POTS line connected via an FXO card), however.

Let me know if this helps you out with setting up conference calling in Asterisk.


comments powered by Disqus