Shared Line Appearances

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”.

Installing the SLA Applications

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 =-

Configuration Overview

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.

Key System Example with Analog Trunks

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:

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:

  • SIP/station1

  • SIP/station2

  • SIP/station3

  • SIP/station4

  • DAHDI/1

  • DAHDI/2

sla.conf

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

extensions.conf

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)

Additional phone configuration tasks

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.

Key System Example with SIP Trunks

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.

sla.conf

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

extensions.conf

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)

Shared Extension Example

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.

sla.conf

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

extensions.conf

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

Additional Configuration

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:

attemptcallerid = yes

This option specifies whether or not the SLA applications should attempt to pass caller ID information. It is set to no by default. If this is enabled, the display of the phones may not be what you would expect in some situations.

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.

Limitations

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.



[132] Admittedly, none of the configuration for SLA is simple.

[133] Read: a hack.