In Asterisk, Shared Line Appearances (SLA)—sometimes also referred to in the industry as Bridged Line Appearances (BLA)—can be used. This functionality can be used to satisfy two primary use cases, which include emulating a simple key system and creating shared extensions on a PBX.
Building key system emulation is the use case for which these applications were primarily designed. In this environment, you have some small number of trunks coming into the PBX, such as analog phone lines, and each phone has a dedicated button for calls on that trunk. You may refer to these trunks as line 1, line 2, and line 3, for example.
The second primary use case is for creating shared extensions on your PBX. This use case seems to be the most common these days. There are many reasons you might want to do this. One example is that you may want an extension to appear on both the phones of an executive and her administrative assistant. Another example would be if you want the same extension to appear on all of the phones in the same lab.
While these use cases are supported to an extent, there are limitations. There is still more work to be done in Asterisk to make these features work really well for what people want to do with them. These limitations are discussed in the section called “Limitations”.
The SLA applications are built on two key technologies in
Asterisk. The first is device state
processing, and the second is conferencing. Specifically, the
conferencing used by these applications is the
MeetMe()
application. The SLA applications come with
the same module as the MeetMe()
application, so you
must install the app_meetme
module.
You can check at the Asterisk CLI to see if you already have the module:
pbx*CLI>
module show like app_meetme.so
Module Description Use Count 0 modules loaded
In this case, the module is not
present. The most common reason that an
Asterisk system does not have the
app_meetme
module is because
DAHDI has not been installed. The
MeetMe()
application uses DAHDI to perform
conference mixing. Once DAHDI is installed (refer to Chapter 3, Installing Asterisk for installation information), rerun the
Asterisk configure script, recompile, and reinstall.
Once the module has been properly installed, you should be able to see
it at the CLI:
*CLI>
module show like app_meetme.so
Module Description Use Count app_meetme.so MeetMe conference bridge 0 1 modules loaded
Once the
app_meetme
module is loaded, you should have both the
SLAStation()
and SLATrunk()
applications available:
*CLI>
core show applications like SLA
-= Matching Asterisk Applications =- SLAStation: Shared Line Appearance Station. SLATrunk: Shared Line Appearance Trunk. -= 2 Applications Matching =-
The two main configuration files that must be edited to
set up SLA are /etc/asterisk/extensions.conf
and
/etc/asterisk/sla.conf
. The
sla.conf
file is used for defining trunks and
stations. A station is any SIP phone that will be using SLA. Trunks are
the literal trunks or shared extensions that will be appearing on two or
more stations. The Asterisk dialplan,
extensions.conf
, provides some important glue that
pulls an SLA configuration together. The dialplan includes some
extension state hints and extensions that define how calls get into and
out of an SLA setup. The next few sections provide detailed examples of
the configuration for a few different use cases.
This usage of SLA comes with the simplest
configuration.[132] This scenario would typically be used for a fairly small
installation, where you have a few analog lines and SIP phones that all
have line keys directly associated with the analog lines. For the
purposes of this example, we will say we have two analog lines and four
SIP phones. Each SIP phone will have a button for
line1
and a button for line2
. This
section will assume that you have done some configuration up front,
including:
Configuring the four SIP phones. For more information on setting up SIP phones, see Chapter 5, User Device Configuration.
Configuring the two analog lines. Fore more information on setting up analog lines with Asterisk, see Chapter 7, Outside Connectivity.
For this example, we will use the following device names for the SIP phones and analog lines. Be sure to adapt the examples to match your own configuration:
As mentioned previously, sla.conf
contains configuration that maps devices to trunks and stations. For
this example, we will start by defining the two trunks:
[line1] type = trunk device = DAHDI/1 [line2] type = trunk device = DAHDI/2
Next, we will set up the station
definitions. We have four SIP phones, which will each use both trunks.
Note that the section names in sla.conf
for
stations do not need to match the SIP device names, but it is done
that way here for convenience:
[station1] type = station device = SIP/station1 trunk = line1 trunk = line2 [station2] type = station device = SIP/station2 trunk = line1 trunk = line2 [station3] type = station device = SIP/station3 trunk = line1 trunk = line2 [station4] type = station device = SIP/station4 trunk = line1 trunk = line2
The station configuration is a bit repetitive. Asterisk configuration file template sections come in handy here to collapse the configuration down a bit. Here is the station configuration again, but this time using a template:
[station](!) type = trunk trunk = line1 trunk = line2 [station1](station) device = SIP/station1 [station2](station) device = SIP/station2 [station3](station) device = SIP/station3 [station4](station) device = SIP/station4
The next configuration file required for this example is
/etc/asterisk/extensions.conf
. There are three
contexts. First, we have the line1
and
line2
contexts. When a call comes in on one of the
analog lines, it will come in to one of these contexts in the dialplan
and execute the SLATrunk()
application. This application will take care of ringing all of the
appropriate stations:
[line1] exten => s,1,SLATrunk(line1) [line2] exten => s,1,SLATrunk(line2)
The next section of the dialplan is
the sla_stations
context. All calls from the SIP
phones should be sent to this context. Further, the SIP phones should
be configured such that as soon as they go off-hook, they immediately
make a call to the station1
extension (or
station2
, station3
, etc., as
appropriate). If the line1
key on the phone is
pressed, a call should be sent to the
station1_line1
extension (or
station2_line1
, etc.).
Any time that a phone goes off-hook
or a line key is pressed, the call that is made will immediately
connect it to one of the analog lines. For a line that is not already
in use, the analog line will be providing a dialtone, and the user
will be able to send digits to make a call. If a user presses a line
key for a line that is already in use, that user will be bridged into
the existing call on that line. The sla_stations
context looks like this:
[sla_stations] exten => station1,1,SLAStation(station1) exten => station1_line1,hint,SLA:station1_line1 exten => station1_line1,1,SLAStation(station1_line1) exten => station1_line2,hint,SLA:station1_line2 exten => station1_line2,1,SLAStation(station1_line2) exten => station2,1,SLAStation(station2) exten => station2_line1,hint,SLA:station2_line1 exten => station2_line1,1,SLAStation(station2_line1) exten => station2_line2,hint,SLA:station2_line2 exten => station2_line2,1,SLAStation(station2_line2) exten => station3,1,SLAStation(station3) exten => station3_line1,hint,SLA:station3_line1 exten => station3_line1,1,SLAStation(station3_line1) exten => station3_line2,hint,SLA:station3_line2 exten => station3_line2,1,SLAStation(station3_line2) exten => station4,1,SLAStation(station4) exten => station4_line1,hint,SLA:station4_line1 exten => station4_line1,1,SLAStation(station4_line1) exten => station4_line2,hint,SLA:station4_line2 exten => station4_line2,1,SLAStation(station4_line2)
The previous section covered the dialplan for trunks and stations. There are some specific things to keep in mind when setting up phones for use with this setup. First, each phone should be configured to send a call as soon as it is taken off-hook.
The other important item is the configuration of the line keys. Asterisk uses extension state subscriptions to control the LEDs next to the line buttons. Beyond that, each line key should be configured as a speed-dial. Use the following checklist for your line key configuration (how you accomplish these tasks will depend on the specific phones you are using):
Set the label of the key to be Line 1 (etc.), or whatever you deem appropriate.
Set up the keys such that the
Line 1 key on station1
subscribes to the state of station1_line1
, and
so on. This is required so Asterisk can make the LEDs reflect the
state of the lines.
Ensure that if the
Line 1 key on station1
is
pressed a call is sent to the station1_line1
extension, and so on.
This example is intended to be identical in functionality to the previous example. The difference is that instead of using analog lines as trunks, we will use a connection to a SIP provider that will terminate the calls to the PSTN. For more information on setting up Asterisk to connect to a SIP provider, see Chapter 7, Outside Connectivity.
The sla.conf
file for this scenario
is a bit tricky.[133] You might expect to see the device line in the trunk
configuration have a SIP channel listed, but instead we’re going to
use a Local channel. This will allow us to use some additional
dialplan logic for call processing. The purpose of the Local channel
will become clearer in the next section, when the dialplan example is
discussed. Here are the trunk configurations:
[line1] type = trunk device = Local/disa@line1_outbound [line2] type = trunk device = Local/disa@line2_outbound
The station configuration is identical to the last example, so let’s get right to it:
[station](!) type = trunk trunk = line1 trunk = line2 [station1](station) device = SIP/station1 [station2](station) device = SIP/station2 [station3](station) device = SIP/station3 [station4](station) device = SIP/station4
As in the last example, you will need
line1
and line2
contexts to
process incoming calls on these trunks:
[line1] exten => s,1,SLATrunk(line1) ; ; If the provider specifies your phone number when sending you ; a call, you will need another rule in the dialplan to match that. ; exten => _X.,1,Goto(s,1) [line2] exten => s,1,SLATrunk(line2) exten => _X.,1,Goto(s,1)
This example requires an
sla_stations
context, as well. This is for all
calls coming from the phones. It’s the same as it was in the last
example:
[sla_stations] exten => station1,1,SLAStation(station1) exten => station1_line1,hint,SLA:station1_line1 exten => station1_line1,1,SLAStation(station1_line1) exten => station1_line2,hint,SLA:station1_line2 exten => station1_line2,1,SLAStation(station1_line2) exten => station2,1,SLAStation(station2) exten => station2_line1,hint,SLA:station2_line1 exten => station2_line1,1,SLAStation(station2_line1) exten => station2_line2,hint,SLA:station2_line2 exten => station2_line2,1,SLAStation(station2_line2) exten => station3,1,SLAStation(station3) exten => station3_line1,hint,SLA:station3_line1 exten => station3_line1,1,SLAStation(station3_line1) exten => station3_line2,hint,SLA:station3_line2 exten => station3_line2,1,SLAStation(station3_line2) exten => station4,1,SLAStation(station4) exten => station4_line1,hint,SLA:station4_line1 exten => station4_line1,1,SLAStation(station4_line1) exten => station4_line2,hint,SLA:station4_line2 exten => station4_line2,1,SLAStation(station4_line2)
The last piece of the dialplan that
is required is the implementation of the
line1_outbound
and
line2_outbound
contexts. This is what the SLA
applications use when they want to send calls out to a SIP provider.
The key to this setup is the usage of the DISA()
application. In the last example, phones were directly connected to
an analog line. This allowed the upstream switch to provide a
dialtone, collect digits, and then complete the call. In this example,
we use the DISA()
application locally to provide a
dialtone and collect digits. Once a complete number has been dialed,
the call will proceed to go out to a SIP provider:
[line1_outbound] exten => disa,1,DISA(no-password,line1_outbound) ; ; Add extensions for whatever numbers you would like to ; allow to be dialed. ; exten => _1NXXNXXXXXX,1,Dial(SIP/${EXTEN}@myprovider) [line2_outbound] exten => disa,1,DISA(no-password,line2_outbound) exten => _1NXXNXXXXXX,1,Dial(SIP/${EXTEN}@myprovider)
The previous two examples were for small key system emulation. For this example, we’ll try something quite different. Many PBX vendors offer the ability to have the same extension shared across multiple phones. This is not simply a matter of having multiple phones ring when an extension is called: it is deeper integration than that. The behavior of the line key for a shared extension is similar to that of a line key on a key system. For example, you can simply put a call on hold from one phone and pick it up from another. Also, if multiple phones press the key for the shared extension, they will all be bridged into the same call. That is why this functionality is often also referred to as Bridged Line Appearances (BLA).
In the previous two examples, we had
two trunks and four stations. For this example, we’re going to set up a
single shared extension on two phones. The shared extension will be
referred to as extension 5001
.
Every usage of the SLA applications requires trunk and
station definitions. This example, like the previous ones, will be
making use of the DISA()
application and the sla.conf
file will look
very similar:
[5001] type = trunk device = Local/disa@5001_outbound [5001_phone1] device = SIP/5001_phone1 trunk = 5001 [5001_phone2] device = SIP/5001_phone2 trunk = 5001
The first part of the dialplan that is required is what
will be executed when extension 5001
is dialed on
the PBX. Normally, to call a phone you would use the
Dial()
application. In this case, we’re going
to use the SLATrunk()
application. This will take care of ringing both phones and keeping
them bridged together:
exten => 5001,1,SLATrunk(5001)
Next, we will need a context that
will be used for making outbound calls from this shared extension.
This assumes that 5001_phone1
and
5001_phone2
have been configured with their
context
options set to 5001
in
sip.conf
:
[5001] ; ; This extension is needed if you want the shared extension to ; be used by default. In that case, have this extension dialed ; when the phone goes off-hook. ; exten => 5001_phone1,1,SLAStation(5001_phone1) ; ; This is the extension that should be dialed when the 5001 key is ; pressed on 5001_phone1. ; exten => 5001_phone1_5001,hint,SLA:5001_phone1_5001 exten => 5001_phone1_5001,1,SLAStation(5001_phone1_5001) exten => 5001_phone2,1,SLAStation(5001_phone2) exten => 5001_phone2_5001,hint,SLA:5001_phone2_5001 exten => 5001_phone2_5001,1,SLAStation(5001_phone2_5001)
Finally, we need an implementation
of the 5001_outbound
context. This will be used to
provide a dialtone and collect digits on the bridged line:
[5001_outbound] exten => disa,1,DISA(no-password,5001_outbound) ; ; This context will also need to be able to see whatever ; extensions you would like to be reachable from this extension. ; include => pbx_extensions
The /etc/asterisk/sla.conf
file has
some optional configuration parameters that were not used in any of the
examples in this chapter. To give you an idea of what other behavior can
be configured, the options are covered here. This file has a
[general]
section that is reserved for global configuration options.
Currently, there is only a single option that can be specified in this
section:
The trunk definitions in the previous examples only specified the type and device. Here are some additional options that can be specified for a trunk:
autocontext = line1
If this option is set, Asterisk will automatically create a
dialplan context using this name. The context will contain an
s
extension that executes the
SLATrunk()
application with the appropriate
argument for this trunk. By default, all dialplan entries must be
created manually.
ringtimeout = 20
This option allows you to specify the number of seconds to
allow an inbound call on this trunk to ring before the
SLATrunk()
application will exit and consider
it an unanswered call. By default, this option is not set.
barge = no
The barge
option specifies whether or not
other stations are allowed to join a call that is in progress on
this trunk by pressing the same line button. Barging into a call
on a trunk is allowed by default.
hold = private
The hold
option specifies hold
permissions for this trunk. If this option is set to
open
, any station can place this trunk on hold
and any other station is allowed to take it back off of hold. If
this option is set to private
, only the station
that placed the trunk on hold is allowed to take it back off of
hold. This option is set to open
by
default.
When we defined the stations in the
previous examples, we only supplied the type
,
device
, and a list of trunks. However, station
definitions accept some additional configuration options, as well. They
are listed here:
autocontext = sla_stations
If this option is specified, Asterisk will automatically create the extensions required for calls coming from this station in the context specified. This is off by default, which means that all extensions must be specified manually.
ringtimeout = 20
A timeout may be specified in seconds for how long this station will ring before the call is considered unanswered. There is no timeout set by default.
ringdelay = 5
A ring delay in seconds can be specified for a station. If a delay is specified, this station will not start ringing until this number of seconds after the call first came in on this shared line. There is no delay set by default.
hold = private
Hold permissions can be specified for a specific station as
well. If this option is set to private
, any
trunks put on hold by this station can only be picked back up by
this station. By default, this is set to
open
.
trunk = line1,ringtimeout=20
A ringtimeout
can be applied to calls
coming from only a specific trunk.
trunk = line1,ringdelay=5
A ringdelay
can also be applied to calls
from a specific trunk.
While Asterisk makes many things easy, SLA is not one of them. Despite this functionality being intended to emulate simple features, the configuration required to make it work is fairly complex. Someone who is new to Asterisk and only wants a simple key system setup will have to learn a lot of complex Asterisk and SIP phone concepts to get it working.
Another feature that still needs some development work before it will work seamlessly with SLA is caller ID. At the time that this functionality was written, Asterisk did not have the appropriate infrastructure in place to be able to update caller ID information throughout the duration of the call. Based on how this functionality is implemented, this infrastructure is required to make the display on the phones useful. It does exist as of Asterisk 1.8 but the SLA applications have not yet been updated to use it. The end result is that you can either have no caller ID information at all, or you can enable it and understand that the phone displays are not always going to display correctly as changes happen throughout the duration of a call.
Another limitation, most relevant to usage of shared extensions, is that transfers do not work. The main reason is that transfers generally involve putting a call on hold for a short time. Call hold is processed in a special way with SLA, in that the held call is not controlled by the phone that initiated the hold. This breaks transfer processing.
In summary, SLA is not necessarily simple to set up, and it comes with some significant limitations. With that said, if what does exist suits your needs, by all means go for it.