Quality Assurance in Asterisk 1.6

Barrie Dempster

September 2009

The world has changed quite a bit in the last 150 years. Over this time, the telephone system has been invented, improved, and automated. Telephone switches no longer refer to people sitting in a large room connecting wires between the appropriate jacks. Flexible and powerful telephone service has moved from a dream to an expectation in large businesses, and for most of us it is a necessity.

Today, telephone systems are the lifeblood of business. They are how we take orders, acquire supplies, and even call for emergency assistance. With the increase in prominence of telephones, the expectations of telephone users have increased proportionally.

Not only have the technological expectations for telephone systems increased dramatically, but consumers are expecting more and more out of the businesses they call. Customers expect to be helped quickly and professionally. They want to know everything in a matter of minutes. Roads do not hold the only rage our society is facing today. As a business we have a variety of questions relating to our telephone system such as:

  • How are our personnel handling angry callers?
  • Are our employees answering the calls in a reasonable amount of time?
  • Do we have any workers using the phone system for personal calls when they should be doing their job?

We will never be able to make sure everybody does what they are supposed to do all of the time. What we will be able to do at the end of this article is perform spot-checks on how we are doing on customer service, and make sure our phone service isn't being used for unauthorized purposes. Ultimately, it comes down to a matter of trust; however, some people do not know better because they haven't been fully trained. Most will always act honorably; however, some just cannot and should not be trusted. We will try to find out who is who.

Call Detail Records

When we talk about security, what images come to mind? May be a big, burly guard? Perhaps a bunch of guys in green, carrying machine guns? Do we imagine a person with a metal-detecting wand? Or do we think of thick glass window panes?

All of these are security features. It is just that some are a little more intrusive than others. Each time we increase security, we become a little bit less friendly. We all have to decide how far we are willing (and able) to go.

In the continuum of security, Call Detail Records are the least intrusive. No special usernames or passwords have to be remembered. No fear of big brother breathing down your customers' and users' necks need be felt. We are simply doing the same thing telephone companies do—tracking what calls were made, when they were made, how long they lasted, where they came from, and a few other bits of information. This information is then available for us to review at our leisure.

Asterisk gives us a few options on how we track this information. The two major choices are flat-file logging and database logging.

Flat-file CDR logging

By default, Asterisk includes a module called cdr_csv. Right out of the box, Asterisk logs all calls coming in and going out. The information for these calls is placed in a Comma Separated Value (CSV) file. This CSV file is located in var/log/asterisk/cdr-csv. All information is available in Master.csv, and some channels can be configured to send some information to other files as well.

The benefit of using a CSV file is the simplicity. Right after compiling and installing Asterisk, this method will work. No additional configuration is required. Also, no additional network traffic is generated, and no additional services have to be installed on our server.

When using the CSV form of CDR, we will see lists and lists of values. They are not very easy to parse, so here is the format, in the order in which they appear:

  • account code: As determined by the channel (for DAHDI) or the user (for IAX and SIP)
  • source: The source of the call
  • destination: The destination of the call
  • destination context
  • caller ID
  • channel: The channel of the source
  • destination channel: If applicable
  • last application: The last application run on the channel
  • last application argument: The last argument to the last application on the channel
  • start time: The time the call commenced
  • answer time: The time the call was answered
  • end time: The time the call ended
  • duration: The difference between start time and end time
  • billable seconds: The difference between answer time and end time, which must be less than the duration
  • disposition: Either ANSWERED, NO ANSWER, or BUSY
  • amaflags: As set for the channel or user, like account code
  • uniqueid: A unique call identifier
  • userfield: A user field set by the SetCDRUserField command

We see that there are many items of information logged for each and every call. We can compare the billable seconds with our phone bill at the end of the month to make sure they're close. We can look at the destination and figure out if the calls were authorized. This gives us enough information to answer most questions we may have about a phone call.

While we have enough information to answer questions, finding that answer is not very easy. We would have to scan through the entire file to try to find anything. If we are going to use an accounting package or reporting software, CSV may be exactly what we need. However, if we wish to use it in a more ad hoc sort of way, it is not very readable.

Database CDR logging

If we wish to read our CDR logs, it is most easily accomplished when the records are sortable. The easiest way to do this is to store our CDR records in a database.

Even in this, Asterisk gives us choices. Included with Asterisk is support for PostgreSQL databases. In order to be able to install this, we must first have the postgresql-devel package installed on our system. If you have to install this package, you'll need to reinstall Asterisk. The automake system will automatically detect that we have the capability to use PostgreSQL and compile that module for us.

Aside from the development packages we have installed, we will also need a PostgreSQL server somewhere in our network. It can be the same machine as the Asterisk server, but it doesn't necessarily need to be. In fact, it probably makes sense to have only one such database server on our network, and we don't want to tie up too much of our PBX's resources with database maintenance and storage.

There is a script in /usr/src/asterisk/contrib/scripts/ called postgres_cdr.sql, which creates the correct table structure for us. This script should be run from the database server.

If we get an error message while rebuilding that says something like "cannot find-lz", then we need to install zlib-devel.

Now that we have set up our database and installed the CDR module, we must configure Asterisk to use the correct database. In order to do this, we need to edit /etc/asterisk/cdr_pgsql.conf. All of the configuration variables are in the global section. Our file should look like the following:


Once we have these variables set, the next time we restart Asterisk, all CDR records will be logged in the database.

If PostgreSQL is not our database of choice, we can use MySQL. This is not a part of the normal distribution of Asterisk. But as we have already installed asterisk-addons, we should already have the ability to use MySQL for CDR logging.

Before we compile, we need to make sure that we have mysql-devel installed. First, we need to decide which version we're going to use. Because of some license quibbles, MySQL version 4.0 and later is not in the automatic package distribution chain. Instead, if we do need to download it, we will have to get it directly from www.mysql.com. However, the older version (3.x) will work with Asterisk and hence, you may wish to take a look at the differences between what version 3 offered and what later versions give us.

Other than the development package mentioned, we will also need a MySQL server somewhere in our network. Just as with PostgreSQL, we can choose to have it on the same server as Asterisk, but for the same reasons, we probably shouldn't.

Next, on the database server, we need to create the database with a user and a table for the CDR data. We do this by running the following code:

# mysqladmin create database asteriskcdrdb 
# mysql
   -> ON asteriskcdrdb.*
   -> TO asteriskcdruser
   -> IDENTIFIED BY 'changethis2yourpassword';
mysql> USE asteriskcdrdb;
mysql> CREATE TABLE cdr (
   -> uniqueid varchar(32) NOT NULL default '',
   -> userfield varchar(255) NOT NULL default '',
   -> accountcode varchar(20) NOT NULL default '',
   -> src varchar(80) NOT NULL default '',
   -> dst varchar(80) NOT NULL default '',
   -> dcontext varchar(80) NOT NULL default '',
   -> clid varchar(80) NOT NULL default '',
   -> channel varchar(80) NOT NULL default '',
   -> dstchannel varchar(80) NOT NULL default '',
   -> lastapp varchar(80) NOT NULL default '',
   -> lastdata varchar(80) NOT NULL default '',
   -> calldate datetime NOT NULL default '0000-00-00 00:00:00',
   -> duration int(11) NOT NULL default '0',
   -> billsec int(11) NOT NULL default '0',
   -> disposition varchar(45) NOT NULL default '',
   -> amaflags int(11) NOT NULL default '0'
-> );

That's all there is to it! We only have to do this once, so it's really not so bad. Next, we have to modify the /etc/asterisk/cdr_mysql.conf file to correctly reflect our choices.


The next time we restart Asterisk, our CDR information will be stored in the MySQL database. What does that give us? We now have the ability to use a number of very powerful tools to search our CDR records to find trends and patterns.

Monitoring calls

Slightly less friendly than recording the information about a call is enabling the ability to monitor calls in real time. This allows us to listen in to a conversation as it happens, so that we may see how our customers are being treated.

The application to use to monitor a DAHDI channel is called DAHDIBarge. It can only accept one command-line argument, which is the number of the channel to listen in on. If we do not pass DAHDIBarge an argument, it will prompt us to enter one. The channel numbers it requests are the same channel numbers given in system.conf and chan_dahdi.conf.

Suppose we had four outgoing DAHDI channels, numbered 1 through 4. We could have something like this in our extensions.conf file:

exten => 8700,1,DAHDIBarge
exten => 8700,2,Hangup
exten => 8701,1,DAHDIBarge(1)
exten => 8701,2,Hangup
exten => 8702,1,DAHDIBarge(2)
exten => 8702,2,Hangup
exten => 8703,1,DAHDIBarge(3)
exten => 8703,2,Hangup
exten => 8704,1,DAHDIBarge(4)
exten => 8704,2,Hangup

This way, extension 8700 would give us access to any DAHDI channel; whether it is an FXO or FXS interface does not matter. Then, extensions 8701 through 8704 would give access to each of the outgoing interfaces.

Monitoring calls used to only be available via DAHDI (earlier known as Zaptel). However, in recent releases of Asterisk, call monitoring is now available for SIP channels. The application to use to monitor a SIP channel is called ChanSpy.

In order to use ChanSpy, the following format can be applied in your extensions.conf file: ChanSpy([<chanprefix>][,<options>]).

For example:

exten => 556,1,ChanSpy(scan)

The following are list of options available when executing ChanSpy:

  • - b: Only spy on channels involved in a bridged call.
  • - g(grp): Match only channels where their ${SPYGROUP} variable is set to contain grp in an optional, delimited list.
  • - q: Don't play a beep when beginning to spy on a channel, or speak the selected channel name.
  • - r[(basename)]: Record the session to the monitor spool directory. An optional base for the filename may be specified. The default is chanspy.
  • - v([value]): Adjust the initial volume in the range from -4 to 4. A negative value refers to a quieter setting.

Since 1.4:

  • - w: Enable 'whisper' mode, so the spying channel can talk to the spied-on channel.
  • - W: Enable 'private whisper' mode, so the spying channel can talk to the spied-on channel but cannot listen to that channel.

Since 1.6:

  • - o: Only listen to audio coming from this channel.
  • - X: Allow the user to exit ChanSpy to a valid single digit numeric extension in the current context or the context specified by the SPY_EXIT_CONTEXT channel variable. The name of the last channel that was spied on will be stored in the SPY_CHANNEL variable.
  • - e(ext): Enable 'enforced' mode, so the spying channel can only monitor extensions whose name is in the ext delimited list.

The following actions may be performed when using ChanSpy:

  • Dialing # cycles the volume level.
  • Dialing * will stop spying and look for another channel to spy on.
  • Dialing a series of digits followed by # builds a channel name to append to <chanprefix>. For example, run ChanSpy(Agent) and dial 1234# while spying to jump to channel Agent/1234.

While these extensions are useful, there is a danger, and we must consider security. Clearly, we do not want just any employee to be able to listen to calls that are in progress. And more than that, we really don't want our customers to be able to accidentally listen to calls that are in progress.

A good way to handle this problem is to create a separate context just for monitoring extensions. Then, designate a single telephone handset that will be able to do nothing but monitor extensions. This handset should be the only phone in the monitoring context, and the monitoring context should not be included in any other context. Keep that handset under lock and key. Not only will this keep people from overhearing embarrassing or confidential information, it will also go a long way towards fostering trust with the employees.

Recording calls

The last of all of the quality assurance methods we will discuss is the call recording capability of Asterisk. This is highest on the Big Brother chart because phone conversations can be archived forever and reviewed on demand. Therefore, an employee's entire telephone history can be called up at any time.

This feature can be accessed from a number of different sources. First, we can configure specific call queues to record calls. This is done in the queues.conf file, for each individual queue. We set it thus:

. . .
monitor-format = wav
monitor-join = yes

The first line tells Asterisk to record the conversation in the .wav format. This is the best choice because it is most compatible with other operating systems. As archived conversations can be burned to CDs, compatibility is a high priority. The second line tells Asterisk to join the two files (in and out) into one file. If we do not do this, we will only hear half of the conversation. In order to take advantage of this feature, we must have soxmix installed on our Asterisk server. The Red Hat packages that contain sox are missing soxmix. Therefore, in order to install soxmix on Red Hat Linux, we need to do so from source.

All calls coming into the queue will be recorded. The name of the file will be the unique ID that Asterisk generates for every call. If we wish to change this, we can do so by adding something like the following in extensions.conf:

exten => 100,1,SetVar(MONITOR_FILENAME=${DATETIME}-${CALLERID(num)})
exten => 100,2,Queue(100)

This will record all calls coming through the queue named 100 in .wav format. We are then free to encode them into MP3 format if we wish to save space.

Aside from recording calls in queues, we can also monitor arbitrary calls through the use of the dialplan. The name of the application that records a channel is Record. In order to start recording, we call the application as follows:

exten => 200,1,Record(${TIMESTAMP}${CALLERID(num)}-${EXTEN}.wav)
exten => 200,2,Dial(SIP/1001)

With just one line of code in our dialplan, we can start monitoring calls. If we want, we could even insert this line into our macro definitions for standard extension types. Or, we could do something like the following:

exten => _.,1,Record(${TIMESTAMP}${CALLERID(num)}-${EXTEN}.wav)
exten => _.,2,Playback(thiscallmaybemonitoredorrecorded)
exten => _.,3,Goto(default,${EXTEN},1)

In three lines of code, we have enabled recording for all incoming phone calls. We have even notified our customers that the call may be recorded. We have the power. Should we use it?

Legal concerns

This is not legal advice. Only a qualified attorney can advise you on your particular situation.

It is very important to note that, just because we can monitor calls, doesn't mean we should, or even that it would be legal to do so. Many states in the United States of America are two-party or all-party states. This means that all parties to a conversation must know that a call is being recorded for it to be admissible in court.

More than that, there are privacy laws in place to protect everyone. Only a careful study of all applicable laws can tell us if we are in the clear. We should never record any phone calls until we have spoken to a lawyer.

For those of you hosting a PBX server, you might just want to play it safe and restrict call recording or monitoring. However, there are alternative solutions for those who wish to individually record conversations independent of the Asterisk server. Counterpath softphone products such as X-Lite has a call recording option, which will save the recordings to your local computer and in WAV format. There is also a hard phone solution through the Polycom 650/670 IP phone where you can plug in a USB memory stick into the phone. Once plugged in you can enable call recording and your conversation will be saved directly to the memory stick.

But aside from the legal issues, there are also moral issues. Maybe it depends on our intent when we call. Are we recording the calls to help our employees improve? Are we recording the calls so that we have an accurate representation of what was agreed upon? Or are we recording calls to try to trap someone, or to pull information out of calls to be used out of context later?


As we have seen in this article, Asterisk gives us the power to:

  • Record call information (CDR)
  • Monitor conversations (ChanSpy)
  • Record the conversations themselves

The purpose of these capabilities is to provide us with options for using our system effectively. It is our responsibility to use these powers appropriately.

There is no point recording all calls if you are never going to use those recordings. Similarly, a database is an overkill if you have no real interest in your calling history.

However, there are many reasons to use these features. For instance, to produce reports or answer questions that other users or departments have regarding the telephone system. The users of the system will know more about what they will need in order to carry out their day-to-day duties, which is why we spend time figuring out exactly what they need early in the deployment plan—to ensure the system provides everything that is needed.

If you have read this article you may be interested to view :


You've been reading an excerpt of:

Asterisk 1.6

Explore Title