Installing VoipMonitor on Trixbox and Elastix

Using Internet SIP trunking services with a VOIP phone system is incredibly cost effective. The only problem is the unreliability of the Internet. We’ve been expreimenting with several tools for monitoring phone call quality but VoipMonitor has been the most useful. Some of the most useful features are:

  • Creates packet capture of each phone call. This is really useful because you get more┬ámanageable┬ácapture files, not one monster files containing all calls.
  • It logs all calls to a MySQL database and calculates several important metrics like MOS. If you need an example of a bad quality call to send to your provider you can just sort the call table by MOS. Anything under 4.0 probably has some jitter or lag in the audio.
Here are the steps to install VoipMonitor (these are just slightly modified from http://www.voipmonitor.org/):
Install all dependencies through yum.
yum install subversion libmysql++-dev libvorbis-devel mysql-devel libpcap-devel php5-mysql php5-gd
Install libpcap. You need a version > 1.0 so the version in the yum repo is not current enough.
wget http://www.tcpdump.org/release/libpcap-1.1.1.tar.gz
tar xzf libpcap-1.1.1.tar.gz
cd libpcap*
./configure
make
make install
Install the mysql client that VoipMonitor uses to connect to MySQL
wget http://tangentsoft.net/mysql++/releases/mysql++-3.0.9.tar.gz
tar xzf mysql++-3.0.9.tar.gz
cd mysql++-3.0.9
./configure
make install
ldconfig
cp /usr/local/lib/libmysqlpp.so.3 /usr/lib/
Install VoipMonitor
wget http://dl.nvthost.com/downloads/voipmonitor-3.0.1.tar.gz
tar zxf voipmonitor-2.0.tar.gz
cd ../voipmonitor-2.0
make
make install
cp /usr/local/lib/libpcap.* /usr/lib
Next you need to create the MySQL database. Here we use the mysql command line client. You can also use phpMyAdmin or Webmin if you have access to it.
We always specify a MySQL root user password during the installation of Trixbox and Elastix so we just log in as the root user. Use mysql -u root and then you will be prompted for a password.
mysql
     mysql> create database voipmonitor;
     mysql> exit
Create the database tables.
cat cdrtable.sql | mysql voipmonitor

Start up VoipMonitor. The u and p switches are for the MySQL username and password. Call VoipMonitor with no arguments to see a list of possible command line switches.

voipmonitor -i eth0 -SRG -h localhost -b voipmonitor -u root -p passw0rd

Asterisk AMI via HTTP Intro

The Asterisk Manager Interface can be accessed in two ways. The first is through TCP port 5038 using the AMI protocol and the second is through the HTTP protocol on port 8088. Both of these ports can be change in the manager.conf or http.conf config files.

Once Asterisk is configured properly for AMI access, you can issue standard AMI commands through a HTTP query string interface and have results returned as text, html, or xml.

To configure AMI over HTTP, the following line needs to be added or modified in the manager.conf file:

webenabled = yes

The following lines need to be added or modified in the http.conf file:

enabled = yes
bindaddr = 0.0.0.0 ;to allow connections from any IP address.
bindport = 8088
prefix = asterisk ;the virtual directory to be used for the interface, ie. http://asteriskserver:8088/asterisk/

Reload the config files with the reload command at the CLI and the webserver should be running. In asterisk 1.6 you can run the command http show status to see the status of the server. It will also show you the paths to use to return the desired results.

HTTP Server Status:
Prefix: /asterisk
Server Enabled and Bound to 0.0.0.0:8088
Enabled URI’s:
/asterisk/httpstatus => Asterisk HTTP General Status
/asterisk/phoneprov/… => Asterisk HTTP Phone Provisioning Tool
/asterisk/manager => HTML Manager Event Interface
/asterisk/rawman => Raw HTTP Manager Event Interface
/asterisk/static/… => Asterisk HTTP Static Delivery
/asterisk/mxml => XML Manager Event Interface

You can view the HTML interface to AMI at the following path http://asteriskserver:8088/asterisk/manager. Keep in mind that asteriskserver is the hostname or IP of your particular server. Each command issued should have an action argument. So, it would look like http://asteriskserver:8088/asterisk/manager?action=actionname. If the action has any arguments, pass them along with argumentname=argumentvalue.

For every method of issuing AMI commands, the authenticated session information is stored in a cookie in the browser or in whatever client you use to access AMI. The cookie is called mansession_id and, after login, should be passed back to the server for every subsequent command.

To login to the HTML interface, go to http://asteriskserver:8088/asterisk/manager?action=login&user=admin&secret=amp111 and make sure you are able to accept the mansession_id cookie.

The above login action uses the default manager username and password from a trixbox installation. In other asterisk installations, you can add or modify users in the manager.conf config file.

The complete list of AMI commands can be found here: http://www.voip-info.org/wiki/view/Asterisk+manager+API

Trixbox Asterisk Dynamic Agent Toggle

Using dynamic agents on any asterisk based system can be a struggle. First, the phone digit maps or dial plans have to allow the login/logout commands like queue*extension# for logging in and queue**extension# for logging out.

Also, asterisk allows you to log into a queue with any extension, including system extensions. We’ve seen people log into a queue with extension 2 which ends up causing calls into that queue to go into an infinite loop.

The following code was originally found here: http://fonality.com/trixbox/forums/trixbox-forums/open-discussion/howto-dynamic-agents-login-logout-auto-loggoff but since it seems like they’ve locked the thread i’ll post my changes here.

[custom-agent-inout]
exten => s,1,Wait(1)
exten => s,n,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,n,AddQueueMember(queue1,Local/${CALLBACKNUM}@from-internal/n)
;If they’re already logged in, log off
exten => s,n,GotoIf($[“${AQMSTATUS}” = “MEMBERALREADY”]?a2)
exten => s,n,Playback(non-crisis-login)
exten => s,n,UserEvent(Agentlogin,Agent: ${CALLBACKNUM})
exten => s,n,Hangup()
exten => s,n(a2),RemoveQueueMember(queue1,Local/${CALLBACKNUM}@from-internal/n)
exten => s,n,UserEvent(Agentlogoff,Agent: ${CALLBACKNUM})
exten => s,n,Playback(non-crisis-logoff)
exten => s,n,Hangup()

The only thing we’ve changed was AddQueueMember(${ARG1}) to AddQueueMember(queue1,Local/${CALLBACKNUM}@from-internal/n).

This caused the correct trixbox interface to be added to the queue. Just passing the extension number to AddQueueMember caused the extension to ring but would not follow any of the queue rules such as skip busy agents.

We’ve also expanded on this to log agents into multiple queues at the same time. This was necessary since for some calls, we’ll allow the caller to wait in a queue for a little bit, then direct them to an IVR for the chance to leave a message, then back into a second queue with music to hold for an agent.

[custom-agent-inout-multiple]
exten => s,1,Wait(1)
exten => s,n,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,n,AddQueueMember(queue1,Local/${CALLBACKNUM}@from-internal/n)
;If they’re already logged in, log off
exten => s,n,GotoIf($[“${AQMSTATUS}” = “MEMBERALREADY”]?a2)
exten => s,n,AddQueueMember(queue2,Local/${CALLBACKNUM}@from-internal/n)
exten => s,n,Playback(crisis-login)
exten => s,n,UserEvent(Agentlogin,Agent: ${CALLBACKNUM})
exten => s,n,Hangup()
exten => s,n(a2),RemoveQueueMember(queue1,Local/${CALLBACKNUM}@from-internal/n)
exten => s,n,RemoveQueueMember(queue2,Local/${CALLBACKNUM}@from-internal/n)
exten => s,n,UserEvent(Agentlogoff,Agent: ${CALLBACKNUM})
exten => s,n,Playback(crisis-logoff)
exten => s,n,Hangup()