Chapter 11. Parking and Paging
I don’t believe in angels, no. But I do have a wee parking angel. It’s on my dashboard and you wind it up. The wings flap and it’s supposed to give you a parking space. It’s worked so far.
This chapter will focus on two important aspects of a PBX system: parking calls to allow them to be answered from a location different from where they were originally answered, and paging, which allows the announcement of who the call is for and how it can be retrieved.
In Asterisk, these two functionalities are exclusive to one another, and can be used independently of one another. Some businesses that contain large warehouses, or have employees who move around the office a lot and don’t necessarily sit at a desk all day, utilize the paging and parking functionality of their systems to direct calls around the office. In this chapter we’ll show you how to use both parking and paging in the traditional setting, along with a couple of more modern takes on this commonly used functionality.
features.conf
There are several features common to most modern PBXs that
Asterisk also provides. Many of these features have optional parameters.
The features.conf file is where you
can adjust or define the various feature parameters in Asterisk.
The [general] section
In the [general]
section of features.conf, you can
define options that fine-tune the behavior of the park and transfer
features in Asterisk. These options are listed in Table 11.1, “features.conf [general] section”.
Table 11.1. features.conf [general] section
| Option | Value/Example | Notes |
|---|---|---|
parkext | 700 | Sets the default extension used to park calls. |
parkpos | 701-720 | Sets the range of extensions used as the parking lot. Parked calls may be retrieved by dialing the numbers in this range. |
context | parkedcalls | Sets the default dialplan context where the parking extension and the parking lot extensions are created. |
parkinghints | no | Enables/disables automatic creation of dialplan hints for
the parking lot extensions so that phones can subscribe to the
state of extensions in the parking lot. The default is no. |
parkingtime | 45 | Specifies the number of seconds a call will wait in the parking lot before timing out. |
comebacktoorigin | yes | Configures the handling of timed-out parked calls. For more information on the behavior of this option, see the sidebar titled Handling Timed-Out Parked Calls with the comebacktoorigin Option. |
courtesytone | beep | Specifies the sound file to be played to the parked caller when the parked call is retrieved from the parking lot. |
parkedplay | caller | Indicates which side of the call to play the courtesytone to when a parked call is
picked up. Valid options include callee, caller, both, or no. The default is no. |
parkedcalltransfers | caller | Controls which side of a call has the ability to execute
a DTMF-based transfer in the call that results from picking up a
parked call. Valid options include callee, caller, both, or no. The default is no. |
parkedcallreparking | caller | Controls which side of a call has the ability to execute
a DTMF-based park in the call that results from picking up a
parked call.[a] Valid options include callee, caller, both, or no. The default is no. |
parkedcallhangup | caller | Controls which side of a call has the ability to execute
a DTMF-based hangup in the call that results from picking up a
parked call. Valid options include callee, caller, both, or no. The default is no. |
parkedcallrecording | caller | Controls which side of a call has the ability to initiate
a DTMF-based one-touch recording in the call that results from
picking up a parked call. Valid options include callee, caller, both, or no. The default is no. |
parkeddynamic | yes | Enables the dynamic creation of parking lots in the
dialplan. The channel variables PARKINGDYNAMIC, PARKINGDYNCONTEXT, and PARKINGDYNPOS need to be set. |
adsipark | yes | Passes ADSI information regarding the parked call back to the originating set. |
findslot | next | Configures the parking slot selection behavior. See Parking Lots for more details. |
parkedmusicclass | default | Specifies the class to be used for the music on hold
played to a parked caller. A music class set in the dialplan
using the CHANNEL(musicclass)
dialplan function will override this setting. |
transferdigittimeout | 3 | Sets the number of seconds to wait for each digit from the caller executing a transfer. |
xfersound | beep | Specifies the sound to be played to indicate that an attended transfer is complete. |
xferfailsound | beeperr | Specifies the sound to be played to indicate that an attended transfer has failed to complete. |
pickupexten | *8 | Configures the extension used for call pickup. |
pickupsound | beep | Specifies the sound to be played to indicate a successful call pickup attempt. No sound is played by default. |
pickupfailsound | beeperr | Specifies the sound to be played to indicate a failed call pickup attempt. No sound is played by default. |
featuredigittimeout | 1000 | Sets the number of milliseconds to wait in between digits pressed during a bridged call when matching against DTMF activated call features. |
atxfernoanswertimeout | 15 | Configures the number of seconds to wait for the target of an attended transfer to answer before considering the attempt timed out. |
atxferdropcall | no | Configures behavior of attended transfer call handling
when the transferer hangs up before the transfer is complete and
the transfer fails. By default, this option is set to no and a call will be originated to
attempt to connect the transferee back to the caller that
initiated the transfer. If set to yes, the call will be dropped after
the transfer fails. |
atxferloopdelay | 10 | Sets the number of seconds to wait in between callback
retries if atxferdropcall is
set to no. |
atxfercallbackretries | 2 | Sets the number of callback attempts to make if atxferdropcall is set to no. By default, this is set to
2 callback attempts. |
[a] Read that again. It makes sense. | ||
The [featuremap] Section
This section allows you to define specific DTMF sequences,
which will trigger various features on channels that have been bridged
via options in the Dial() or Queue() application. The options are detailed
in Table 11.2, “features.conf [featuremap] section”.
Table 11.2. features.conf [featuremap] section
Note
The default blindxfer and
disconnect codes are and
#, respectively. Normally you’ll
want to change them from the defaults, as they will interfere with
other things that you might want to do (for example, if you use the
*Tt option in your Dial() command, every time
you press the # key you’ll
initiate a transfer).
The [applicationmap] Section
This section of features.conf allows you to map DTMF codes to
dialplan applications. The caller will be placed on hold until the
application has completed execution.
The syntax for defining an application map is as follows (it must appear on a single line; line breaks are not allowed)[99]:
<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>] ,<Application>([<AppArguments>])[,MOH_Class]
What you are doing is the following:
Giving your map a name so that it can be enabled in the dialplan through the use of the
DYNAMIC_FEATURESchannel variable.Defining the DTMF sequence that activates this feature (we recommend using at least two digits for this).
Defining which channel the feature will be activated on, and (optionally) which participant is allowed to activate the feature (the default is to allow both channels to use/activate this feature).
Giving the name of the application that this map will trigger, and its arguments.
Providing an optional music on hold (MOH) class to assign to this feature (which the opposite channel will hear when the application is executing). If you do not define any MOH class, the caller will hear only silence.
Here is an example of an application map that will trigger an AGI script:
agi_test => *6,self/callee,AGI(agi-test.agi),default
Note
Since applications spawned from
the application map are run outside the PBX core, you cannot execute
any applications that trigger the dialplan (such as Goto(), Macro(), Background(), etc.). If you wish to use the
application map to spawn external processes (including executing
dialplan code), you will need to trigger an external application
through an AGI() call or the
System() application. Point being,
if you want anything complex to happen through the use of an
application map, you will need to test very carefully, as not all
things will work as you might
expect.
To use an application map, you must
declare it in the dialplan by setting the DYNAMIC_FEATURES variable somewhere before the Dial() command that connects the channels. Use
the double underscore modifier on the variable name in order to ensure
that the application map is available to both channels throughout the
life of the call. For example:
exten => 101,n,Set(__DYNAMIC_FEATURES=agi_test) exten => 101,n,Dial(SIP/0000FFFF0002)
Note
If you want to allow more than
one application map to be available on a call, you will need to use
the # symbol as a delimiter between multiple map names:
Set(__DYNAMIC_FEATURES=agi_test#my_other_map) |
The reason why the character was chosen instead
of a simple comma is that older versions of the #Set() application interpreted the comma
differently than more recent versions, and the syntax for
application maps has never been updated.
Don’t forget to reload the features
module after making changes to the features.conf file:
*CLI> features reloadYou can verify that your changes have taken place through the CLI command features show. Make sure you test out your application map before you turn it over to your users!
Application Map Grouping
If you have a lot of features that you need to activate
for a particular context or extension, you can group several features
together in an application map grouping, so that one assignment of the
DYNAMIC_FEATURES variable will assign all of the designated features of that
map.
The application map groupings are
added at the end of the features.conf file. Each grouping is given a
name, and then the relevant features are listed.
[shifteight] unpauseMonitor => *1 ; custom key mapping pauseMonitor => *2 ; custom key mapping agi_test => ; no custom key mapping
Note
If you want to specify a custom
key mapping to a feature in an application map grouping, simply
follow the => with the key
mapping you want. If you do not specify a key mapping, the default
key map for that feature will be used (as found in the [featuremap] section). Regardless of
whether you want to assign a custom key mapping or not, the => operator is required.
In the dialplan, you would assign this application map grouping
with the Set() application:
Set(__DYNAMIC_FEATURES=shifteight) ; use the double underscore if you want to ensure
; both call legs have the variable assigned.
Parking Lots
A parking lot allows a call to be held in the system without being associated with a particular extension. The call can then be retrieved by anyone who knows the park code for that call. This feature is often used in conjunction with an overhead paging system (PA system, or Tannoy, for our UK readers). For this reason, it is often referred to as park-and-page; however, it should be noted that parking and paging are in fact separate.
To park a call in Asterisk, you
need to transfer the caller to the feature code assigned to parking,
which is assigned in the features.conf file with the parkext directive. By default, this is
700:
parkext => 700 ; What extension to dial to park (all parking lots)
You have to wait to complete the
transfer until you get the number of the parking retrieval slot from the
system, or you will have no way of retrieving the call. By default the
retrieval slots, assigned with the parkpos directive in features.conf, are numbered from
701–720:
parkpos => 701-720 ; What extensions to park calls on (defafult parking lot)
Once
the call is parked, anyone on the system can retrieve it by dialing the
number of the retrieval slot (parkpos) assigned to that call. The call will
then be bridged to the channel that dialed the retrieval code.
There are two common ways to define
how retrieval slots are assigned. This is done with the findslot directive
in the features.conf
file. The default method (findslot
=> first) always uses the lowest-numbered slot if it is
available, and only assigns higher-numbered codes if required. The
second method (findslot => next)
will rotate through the retrieval codes with each successive park,
returning to the first retrieval code after the last one has been used.
Which method you choose will depend on how busy your parking lots are.
If you use parking rarely, the default findslot of first will be best (people will be used to
their parked calls always being in the same slot). If you use parking a
lot (for example, in an automobile dealership), on the other hand, it is
far better for each successive page to assign the next slot, since you
will often have more than one call parked at a time. Your users will get
used to listening carefully to the actual parking lot number (instead of
just always dialing 701), and this
will minimize the chance of people accidentally retrieving the wrong
call on a busy system.
If you are using parking, you are probably also going to need a way to announce the parked calls so that the intended parties know how to retrieve them. While you could just run down the hall yelling “Bob, there’s a call for you on 701!,” the more professional method is to use a paging system (more formally known as a public address system), which we will discuss in the next section.
Overhead and “Underchin” Paging (a.k.a. Public Address)
In many PBX systems, it is desirable to be able to allow a user to send his voice from a telephone into a public address system. This normally involves dialing a feature code or extension that makes a connection to a public address resource of some kind, and then making an announcement through the handset of the telephone that is broadcast to all devices associated with that paging resource. Often, this will be an external paging system consisting of an amplifier connected to overhead speakers; however, paging through the speakers of office telephones is also popular (mainly for cost reasons). If you have the budget (or an existing overhead paging system), overhead paging is generally better, but set paging (a.k.a. “underchin” paging) can work well in many environments. What is perhaps most common is to have a mix of set and overhead paging, where, for example, set-based paging might be in use for offices, but overhead paging would be used for warehouse, hallway, and public areas (cafeteria, reception, etc.).
In Asterisk, the Page() application is used for paging. This application simply takes a list of
channels as its argument, calls all of the listed channels simultaneously,
and, as they are answered, puts each one into a conference room. With this
in mind, it becomes obvious that one requirement for paging to work is
that each destination channel must be able to automatically
answer the incoming connection and place the resultant audio
onto a speaker of some sort (in other words, Page() won’t work if all the phones just
ring).
So, while the Page() application itself is painless and simple
to use, getting all the destination channels to handle the incoming pages
correctly is a bit trickier. We’ll get to that shortly.
The Page() application takes three arguments,
defining the group of channels the page is to be connected to, the
options, and the timeout:
exten => *724,1,Page(${ChannelsToPage},i,120)The options (outlined in Table 11.3, “Page() options”) give you some flexibility with
respect to how Page() works, but the
majority of the configuration is going to have to do with how the target
devices handle the incoming connection. We’ll dive into the various ways
you can configure devices to receive pages in the next section.
Table 11.3. Page() options
Because of how Page() works, it is very resource-intensive. We
cannot stress this enough. Carefully read on, and we’ll cover how to
ensure that paging does not cause performance problems in a production
environment (which it is almost certain to do if not designed
correctly).
Places to Send Your Pages
As we stated before, Page() is in and of itself very simple. The
trick is how to bring it all together. Pages can be sent to different
kinds of channels, and they all require different configuration.
External paging
If a public address system is installed in the building,
it is common to connect the telephone system to an external amplifier
and send pages to it through a call to a channel. One way of doing
this is to plug the sound card of your server into the amplifier and
send calls to the channel named Console/DSP, but this assumes that the sound drivers on your server
are working correctly and the audio levels are normalized correctly on
that channel. Another, potentially simpler, and possibly more robust
way to handle external paging is to use an FXS device of some kind
(such as an ATA), which is connected to a paging interface such as a
Bogen UTI1,[100] which then connects to the paging amplifier.[101]
In your dialplan, paging to an
external amplifier would look like a simple Dial() to the device that is connected to
the paging equipment. For example, if you had an ATA configured in
sip.conf as [PagingATA], and you plugged the ATA into a
Bogen UTI1, you would perform paging by dialing:
exten => *724,1,Verbose(2,Paging to external amplifier) ; note the '*' in the
; extension is part of
; what you actually dial
same => n,Set(PageDevice=SIP/PagingATA)
same => n,Page(${PageDevice},i,120)Note that for this
to work you will have had to register your ATA as a SIP device under
sip.conf, and in this case we
named the device [PagingATA]. You
can name this device anything you want (for example, we often use the
MAC address as the name of a SIP device), but for anything that is not
a user telephone, it can be helpful to use a name that makes it stand
out from other devices.
If you had an FXS card in your
system and you connected the UTI1 to that, you would Dial() to the channel for that FXS port
instead:
same => n,Dial(DAHDI/25)
The UTI1 answers the call and opens a channel to the paging system; you then make your announcement and hang up.
Set paging
Set-based paging first became popular in key telephone
systems, where the speakers of the office telephones are used as a
poor-man’s public address system. Most SIP telephones have the ability
to auto-answer a call on handsfree, which accomplishes what is
required on a per-telephone basis. In addition to this, however, it is
necessary to pass the audio to more than one set at the same time.
Asterisk uses its built-in conferencing engine to handle the
under-the-hood details. You use the Page() application to make it happen.
Like Dial(), the Page() application can handle several
channels. Since you will generally want Page() to signal several sets at once
(perhaps even all the sets on your system) you may end up with lengthy
device strings that look something like this:
Page(SIP/SET1&SIP/SET2&SIP/SET3&SIP/SET4&SIP/SET5&SIP/SET6&SIP/SET7&...
Warning
Beyond a certain size, your Asterisk system will be unable to page multiple sets. For example, in an office with 200 telephones, using SIP to page every set would not be possible; the traffic and CPU load on your Asterisk server would simply be too much. In cases like this, you should be looking at either multicast paging or external paging.
Perhaps the trickiest part of SIP-based paging is the fact that you usually have to tell each set that it must auto-answer, but different manufacturers of SIP telephones use different SIP messages for this purpose. So, depending on the telephone model you are using, the commands needed to accomplish SIP-based set paging will be different. Here are some examples:
exten => *724,1,Verbose(2,Paging to Aastra sets) same => n,SIPAddHeader(Alert-Info: info=alert-autoanswer) same => n,Set(PageDevice=SIP/00085D000000) same => n,Page(${PageDevice},i)exten => *724,1,Verbose(2,Paging to Polycom sets) same => n,SIPAddHeader(Alert-Info: Ring Answer) same => n,Set(PageDevice=SIP/0004F2000000) same => n,Page(${PageDevice},i)exten => *724,1,Verbose(2,Paging to Snom sets) same => n,Set(VXML_URL=intercom=true) ; replace 'domain.com' with the domain of your system same => n,SIPAddHeader(Call-Info: sip:domain.com\;answer-after=0) same => n,Set(PageDevice=SIP/000413000000) same => n,Page(${PageDevice},i)For Cisco SPA (the former Linksys phones, not the 79XX series):
exten => *724,1,Verbose(2,Paging to Cisco SPA sets -- but not Cisco 79XX sets) same => n,SIPAddHeader(Call-Info:\;answer-after=0) ; Cisco SPA phones same => n,Set(PageDevice=SIP/0004F2000000) same => n,Page(${PageDevice},i)
Assuming you’ve figured that out, what happens if you have a mix of phones in your environment? How do you control which headers to send to which phones?[102]
Any way you slice it, it’s not pretty.
Fortunately, many of these sets support IP multicast, which is a far better way to send a page to multiple sets (read on for details). Still, if you only have a few phones on your system and they are all from the same manufacturer, SIP-based paging could be the simplest, so we don’t want to scare you off it completely.
Multicast paging via the MulticastRTP channel
If you are serious about paging through the sets on your system, and you have more than a handful of phones, you will need to look at using IP multicast. The concept of IP multicast has been around for a long time,[103] but it has not been widely used. Nevertheless, it is ideal for paging within a single location.
Asterisk has a channel (chan_multicast_rtp) that is designed to create an RTP multicast. This stream is then subscribed to by the various
phones, and the result is that whenever media appears on the multicast
stream, the phones will pass that media to their speakers.
Since MulticastRTP is a channel driver, it does
not have an application, but instead will work anywhere in the
dialplan that you might otherwise use a channel. In our case, we’ll be
using the Page() application to
initiate our multicast.
To use the multicast channel, you simply send a call to it the same as you would to any other channel. The syntax for the channel is as follows:
MulticastRTP/<type>/<ip address:port>[/<linksys address:port>]
The type can be either basic or linksys. The basic syntax of the MulticastRTP channel looks like this:
exten => *723,1,Page(MulticastRTP/basic/239.0.0.1:1234)
Not all sets support IP multicast, but we have tested it out on Snom,[104] Linksys/Cisco, and Aastra, and it works swell.[105]
VoIP paging adaptors
Recently, there have been some VoIP-based paging speakers introduced to the market. These devices are addressed in the dialplan in the exact same way as a SIP ATA connected to a UTI1, but they can be installed in the same manner as overhead speakers would be. Since they auto-answer, there is no need to pass them any extra information, the way you would need to with a SIP telephone set.
For smaller installations (where no more than perhaps half a dozen speakers are required), these devices may be cost-effective. However, for anything larger than that, (or installation in a complex environment such as a warehouse or parking lot), you will get better performance at far less cost with a traditional analog paging system connected to the phone system by an analog (FXS) interface.
We don’t know if these devices support multicast. Keep this in mind if you are planning to use a large number of them.
Combination paging
In many organizations, there may be a need for both
set-based and external paging. As an example, a manufacturing facility
might want to use set-based paging for the office area but overhead
paging for the plant and warehouse. From Asterisk’s perspective, this
is fairly simple to accomplish. When you call the Page() application, you simply specify the various resources you want to
page, separated by the &
character, and they will all be included in the conference that the
Page() application creates.
Bringing it all together
At this point you should have a
list of the various channel types that you want to page. Since
Page() will nearly always want to
signal more than one channel, we recommend setting a global variable
that defines the list of channels to include, and then calling the
Page() application with that
string:
[global]
MULTICAST=MulticastRTP/linksys/239.0.0.1:1234
;MULTICAST=MulticastRTP/linksys/239.0.0.1:1234/239.0.0.1:6061 ; if you have SPA
; (Linksys/Cisco)
; phones
BOGEN=SIP/ATAforPaging ; This assumes an ATA in your sip.conf file named
; [ATAforPaging]
;BOGEN=DAHDI/25 ; We could do this too, assuming we have an analog
; FXS card at DAHDI channel 25
PAGELIST=${MULTICAST}&${BOGEN} ; All of these variable names are arbitrary.
; Asterisk doesn't care what you call these strings
[page_context] ; You don't need a page context, so long as the extension you
; assign to paging is dialable by your sets
exten => *724,1,Page(${PAGELIST},i,120)This example offers several
possible configurations, depending on the hardware. While it is not
strictly required to have a PAGELIST variable defined, we have found that this will tend to simplify
the management of multiple paging resources, especially during the
configuration and testing process.
We created a context for paging
for the purposes of this example. In order for this to work, you’ll
need to either include this context
in the contexts where your sets enter the dialplan, or code a Goto() in those contexts to take the user to
this context and extension (i.e., Goto(page_context,*724,1)) Alternatively,
you could hardcode an extension for the Page() application in each context that
services sets.
Zone Paging
Zone paging is popular in places such as automobile dealerships, where the parts department, the sales department, and perhaps the used car department all require paging, but have no need to hear each other’s pages.
In zone paging, the person sending
the page needs to select which zone she wishes to page into. A zone
paging controller such as a Bogen PCM2000 is generally used to allow
signaling of the different zones: the Page() application signals the zone
controller, the zone controller answers, and then an additional digit is
sent to select which zone the page is to be sent to. Most zone
controllers will allow for a page to all zones, in addition to combining
zones (for example, a page to both the new and used car sales departments).
You could also have separate extensions in the dialplan going to separate ATAs (or groups of telephones), but this may prove more complicated and expensive than simply purchasing a paging controller that is designed to handle this. Zone paging doesn’t require any significantly different technology, but it does require a little more thought and planning with respect to both the dialplan and the hardware.
Conclusion
In this chapter we explored the features.conf file, which contains the functionality for enabling DTMF-based transfers, enabling the recording of calls during a call, and configuring parking lots for one or more companies. We also looked at various ways of announcing calls and information to people in the office using a multitude of paging methods, including traditional overhead paging systems and multicast paging to the phone sets on employees’ desks. This exploration of the various methods of implementing the traditional parking and paging methods in a modern way will hopefully show you the flexibility Asterisk can offer.
[97] Yes, we realize that a SIP INFO message is in fact a SIP message, and is not technically part of the audio channel, but the point is that you can’t use the “transfer” or “park” button on your SIP phone to access these features while on a call. You’ll have to send DTMF.
[98] We hope you realize that the actual extension will be
related to the channel name that parked the call, and will not be
SIP_0004F2040808 (unless Leif
sells you the Polycom phone from his lab).
[99] There is some flexibility in the syntax (you can look at the sample file for details), but our example uses the style we recommend, since it’s the most consistent with typical dialplan syntax.
[100] The Bogen UTI1 is useful because it can handle all manner of different kinds of incoming and outgoing connections, which pretty nearly guarantees that you’ll be able to painlessly connect your telephone system to any sort of external paging equipment, no matter how old or obscure.
[101] In this book we’re assuming that the external paging equipment is already installed and was working with the old phone system.
[102] Hint: the local channel will be your friend here.
[103] It even has its own Class D reserved IP address space, from 224.0.0.0 to 239.255.255.255 (but read up on IP multicast before you just grab one of these and assign it). Parts of this address space are private, parts are public, and parts are designated for purposes other than what you might want to use them for. For information about multicast addressing, see http://en.wikipedia.org/wiki/IP_multicast#IP_multicast_addressing_assignments.
[104] Very loud, and no way to adjust gain.
[105] So far as we can tell, Polycom sets do not support multicast. We certainly were not able to find a way to use it.








