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:
- You’ll need to configure a SIP trunk to the Asterisk server
- 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.
- Create a Recording Profile (Device -> Device Settings -> Recording Profile). Sepcify the DN from step 2 as the Recording Destination Address.
- 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.
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.
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.