The Problem : Record calls from selected Call Manager (CUCM) phones.
The Solution : Setup a recording server that will receive copies of calls from these handsets.

Details : Since call recording isn’t built into Cisco Call Manager, we’ll need a secondary server to send a copy of each call to. We’ll then use the Call Manager built in bridge to fork calls to this new server. Since call recording is built into the open source PBX Asterisk, we’ll be using that as our recording server.

The built-in-bridge is a feature of Call Manager 7 and up that allows a modern IP phone to fork it’s audio – essentially send a separate copy of the phone call to a third party recording server.

To get started, you’ll need to configure the Asterisk server, and and The Call Manager. Install of an Asterisk server and UCUM is outside the scope of this tutorial.

On the Asterisk Server

FYI, this article applies to an Asterisk server running on Centos 6.4.

Configure an extension on the Asterisk server to be recorded. In this case we used extension 1111200, which will be auto answered by the Asterisk server, and recorded.  You’ll need a DN that works with your dial plan (we use 7 digits)

You’ll need to create the folders:
/var/spool/asterisk/monitor/active-calls
/var/spool/asterisk/monitor/completed-calls

the edit /etc/asterisk/extensions_custom.conf

[from-trunk]
exten => 1111200,1,Answer
exten => 1111200,n,Noop( SIPCALLID  ${SIPCALLID})
exten => 1111200,n,Noop( UNIQUEID ${UNIQUEID})
exten => 1111200,n,Noop( SIPHEADER From = _${SIP_HEADER(From)}_)
exten => 1111200,n,Noop( SIPHEADER From = _${CUT(CUT(SIP_HEADER(From),\;,7),>,1)}_)
exten => 1111200,n,Set(remotedid=${CUT(CUT(SIP_HEADER(From),=,6),>,1)})
exten => 1111200,n,Set(pseudodidi2=${CUT(SIP_HEADER(From),x-farendaddr,1)})
exten => 1111200,n,Noop( ${remotedid})
exten => 1111200,n,Set(File_Record=${CALLERID(num)}_${remotedid}_${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}_${CUT(SIPCALLID,-,1)}_${CHANNEL:-2}%d:wav)
exten => 1111200,n,Record(/var/spool/asterisk/monitor/active-calls/${File_Record})
exten => 111200,n,Hangup()
#exten => h,1,Set(result=${SHELL(bash /var/spool/asterisk/tmp/script.sh ${File_Record})})
exten => h,1,System(/bin/mv /var/spool/asterisk/monitor/active-calls/${CALLERID(num)}_${remotedid}_*_${CUT(SIPCALLID,-,1)}* /var/spool/asterisk/monitor/completed-calls/)
exten => h,2,NoOp(result is ${result})

Once this is completed, you should be able to call the extension from your cisco phone and see files being generated in the /var/spool/asterisk/monitor/active-calls/ folder of the asterisk server. You’ll notice that there are two files generated for each call, this is because Asterisk records each side of the conversation as a separate wave file. We use a linux command line program called lame to mix these two files together. I use a special version that includes mp3 support (be aware that mp3 support was pulled from the main version of lame for licensing issues).

Install repository with Lame, then install lame using yum. Lame will be used to convert the wav files produced by Asterisk

rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm
yum install lame

Now, we’ll need to make a script to combine the two wav files into one, then use lame and convert to MP3. This script is also setup to copy the files out to another reporting server, Then delete the local files – if you don’t want that, you’ll need to remove the final IF statement.

So, from command line:

vi /var/spool/asterisk/monitor/merge_wav.bash

and paste this script

#!/bin/bash
#
# Script to merge 2 linked wav files with similar ids
#
# $1 - Input directory to search
#
# Written by the guys at UC Guru - http://www.ucguru.com
#

# Local variables just used within script
progname=`basename $0`
monitordir="/var/spool/asterisk/monitor/completed-calls"
workdir="/tmp"

# Location for output wav file
WAVOUTDIR1="/var/spool/asterisk/monitor/mixed-calls"
# Remote ip/directory for scp to send to
DESTSCPLOC1="NAME@SERVER:/var/www/recordings/incoming"

INPUT1="$1"

# First find files with matching ids, display them, and put them in a workfile to be processed after

echo "Items we will join : "
echo "-----"
ls "$INPUT1" | sed "s/_...\.wav//" | sed "s/-...\.wav//" | uniq -c | awk '{print $1,$2}' | grep "^2" | tee ${workdir}/$progname.$$
echo "-----"

echo " "

# Now display error items

# *** NOTE : on next lines where it says "cat $INPUT1" should be changed to "ls $INPUT1" to read files in directory

echo "Error items : "
echo "-----"
ls "$INPUT1" | sed "s/_...\.wav//" | sed "s/-...\.wav//" | uniq -c | awk '{print $1,$2}' | grep -v "^2"
echo "-----"
echo " "

# Now lets join them
cat $workdir/$progname.$$ | awk '{print $2}' | sort | while read LINE ; do

  WAV_OUTFILE="${WAVOUTDIR1}/${LINE}_merged.wav"
  MP3_OUTFILE="$WAVOUTDIR1/${LINE}_processed.mp3"

  # Get the 2 sctual filenames and put them into a file for sox

  ls ${monitordir}/${LINE}* | while read LINE2 ; do
    printf "${LINE2} " >> ${workdir}/$progname.2.$$
  done
  # Next line will change to (for display purposes only now) :
  echo "sox -m `cat $workdir/$progname.2.$$` ${WAV_OUTFILE}"
  sox -m `cat $workdir/${progname}.2.$$` ${WAV_OUTFILE}
  # Now check output of sox and remove original files
  if [ $? -eq 0 ]
  then
    # echo "Removing `cat $workdir/$progname.2.$$`"
    rm -f `cat $workdir/$progname.2.$$`
  fi
  #echo " "
  rm -f $workdir/$progname.2.$$

  # convert wav to mp3 :
  # echo "--resample 16 --silent  $WAV_OUTFILE $MP3_OUTFILE"
  lame --resample 16 --silent $WAV_OUTFILE $MP3_OUTFILE
  # Now check output of lame and remove original files
  if [ $? -eq 0 ]
  then
    #echo "Removing ${WAV_OUTFILE}"
    rm -f ${WAV_OUTFILE}
  fi
  #echo " "

done

rm -f $workdir/$progname.$$

if [ "$(ls -A $WAVOUTDIR1)" ]; then
   echo "SCP files to remote location"
   scp $WAVOUTDIR1/*_processed.* $DESTSCPLOC1
   echo "Deleting merged files"
   rm -f ${WAVOUTDIR1}/*_processed.*
else
   echo "$WAVOUTDIR1 is Empty"
fi

Recording Crontab – you’ll need to add a cron job on the Asterisk server to process the files (join, and copy offbox if requested). Here I’ve go one running every 5 minutes. If there is any output (errors) they will be appended to the file /var/spool/asterisk/monitor/merge.log

At the command prompt type:
crontab -e

then add this:

*/5 * * * * /var/spool/asterisk/monitor/merge_wav.bash /var/spool/asterisk/monitor/completed-calls/ >> /var/spool/asterisk/monitor/merge.log

Setup NTP on all servers (Call Manager, Asterisk, and any other servers). Since these calls are linked to records by timestamp, it’s important that everyone have the same time. You’ve likely already setup NTP on your Call Manager (it’s required during install), so this should do the trick for then Asterisk and reporting servers:

Type the following command to install ntp

# yum install ntp

Turn on service

# chkconfig ntpd on

Synchronize the system clock with 0.pool.ntp.org server (or better yet, the same server used by CUCM)

# ntpdate pool.ntp.org

Start the NTP:

# /etc/init.d/ntpd start

On the CUCM server:

  1. You’ll need to configure a SIP trunk to the Asterisk server
  2. You’ll need to configure a Route Pattern that points a DN to the Asterisk SIP trunk.  Once this is done you should be able to call that DN from your phone, and have Asterisk answer and record the call.
  3. Create a Recording Profile (Device -> Device Settings -> Recording Profile).  Sepcify the DN from step 2 as the Recording Destination Address.
  4. On each line that you want to record (you add this to the line, not the device) you’ll need to change the Recording Option to always (or automatic), and choose the Asterisk Recording Profile.

Some things to keep in mind:

  • When asterisk writes the recording files, the internal phone that is sending the audio to asterisk is always seen as the caller, and the second number is referred to as the remote phone.  The end result is that your files will be in the format internal_remote_date-time_randomNumber-channel.wav.

 

My thoughts:

This is a pretty labor intensive solution, and not for the faint of heart.  At the end of this exercise you’ll have a directory full of recordings that will continue to grow, so you’ll need to prune this directory occasionally.  I used these recordings to pull into an in-house CDR tool that I developed, but you may just want to keep recordings for some sort of compliance.  Be sure to check your local laws to make sure that recording calls is allowed.

Recording Call Manager using Asterisk

2 thoughts on “Recording Call Manager using Asterisk

  • January 21, 2015 at 7:41 am
    Permalink

    Very useful Article. Only one question about this. How do you know who makes the call and who receive in the Asterisk? I need to know who is the caller and who is the called. Sometimes the SIPCALLID are different, then the mix fails. The SOX is used to mix and LAME is used to convert to mp3.

    • August 9, 2016 at 3:36 am
      Permalink

      Hi Cahzca, I’ve used the same script (with some changes to update the content of CDR and use the native web report) and never found issue on retrieving the caller and called informations. I’m in a tuning operation of my recording appliance (Vmware VM), I can share with you if you want as I’m happy to test it on other environment.

Leave a Reply