FusionPBX for ex-Trixbox users

This blog is intended to be read in sequential order as it is a series of steps that I followed to build a fully functioning fusionpbx phone system. However you might just need to find out how to do a particular thing so you might want to use the search box below to find that specific step. Please give feedback - if you know a better way to do something share it!

Tuesday, August 2

fail2ban

To install fail2ban you can refer to http://wiki.fusionpbx.com/index.php?title=CentOS_Install#Fail2ban and http://wiki.freeswitch.org/wiki/Fail2ban.

Unfortunately though, if you are installing on an existing system as I was, you'll run into problems following those instructions, so here is a summary.

Use cat /etc/redhat-release to find out the release version of your system.  In my case it was CentOS release 5.4 (Final) and if you installed from the same ISO as me then you'll have the same release.  You need to know this for the next instruction
rpm -ivh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm


If you aren't using version 5.4 like me then you would need to modify that last instruction for your release.  Next we download the fail2ban package.
yum install fail2ban

If you get an error like this:
Could not retrieve mirrorlist http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=i386 error was[Errno 4] IOError: urlopen error (101, 'Network is unreachable')

Then check that your DNS information is correct in system-network-config.  I changed my DNS to the Google DNS of 8.8.8.8 and then tried yum again and it worked properly.

After it is sucessfully installed:
cd /etc/init.d
/sbin/chkconfig fail2ban on

Then you have to configure fail2ban.  The instructions for configuring it to protect your system against hacking login attempts to the fusionpbx administrative web interface are: http://wiki.fusionpbx.com/index.php?title=Fail2Ban

Note that if you find that there are no files in /etc/fail2ban/ just re-run the yum command.  I have seen this once but couldn't work out why.

In brief, to configure fail2ban to protect fusionpbx you need to add the following to /etc/fail2ban/jail.local
[fusionpbx]  
enabled = true 
port = 80,443 
protocol = tcp 
filter = fusionpbx 
logpath = /var/log/auth.log 
action = iptables-allports[name=fusionpbx, protocol=all] 
# sendmail-whois[name=FusionPBX, dest=root, sender=fail2ban@example.org] #no smtp server installed

Note that unless you are running release 794 of FusionPBX you will not get anything logged in /var/log/auth.log and therefore fail2ban will not be able to protect your FusionPBX webpage.

You also need to create the file /etc/fail2ban/filter.d/fusionpbx.conf containing the following lines:
# Fail2Ban configuration file 

# Author: soapee01 
#  
[Definition]  
# Option: failregex 
# Notes.: regex to match the password failures messages in the logfile. The 
# host must be matched by a group named "host". The tag "" can 
# be used for standard IP/hostname matching and is only an alias for 
# (?:::f{4,6}:)?(?P[\w\-.^_]+) # Values: TEXT 

#failregex = [hostname] FusionPBX: \[\] authentication failed 
#[hostname] variable doesn't seem to work in every case. Do this instead: 
failregex = .* FusionPBX: \[<HOST>\] authentication failed for
= .* FusionPBX: \[<HOST>\] provision attempt bad password for  
# Option: ignoreregex 
# Notes.: regex to ignore. If this regex matches, the line is ignored. 
# Values: TEXT 

ignoreregex =

Ensure you also follow the instructions to prevent you banning yourself too!  In brief, you need to add the following to /etc/fail2ban/jail.local
[DEFAULT]  
# "ignoreip" can be an IP address, a CIDR mask or a DNS host 
ignoreip = 127.0.0.1 X.X.X.X 
bantime = 600 
maxretry = 3
Note that you can put as many IP addresses as you want to ignore on that ignoreip line but at a minimum you need to put the address of the client you are using to administer the server instead of X.X.X.X

The instructions for configuring it to protect your system against hacking login attempts and denial of service attacks for the SIP interfaces on your system are: http://wiki.freeswitch.org/wiki/Fail2ban

In brief, to configure fail2ban to protect the SIP ports on your server you need to add the following to /etc/fail2ban/jail.local
[freeswitch-tcp]  
enabled = true 
port = 5060,5061,5080,5081 
protocol = tcp 
filter = freeswitch 
logpath = /usr/local/freeswitch/log/freeswitch.log 
action = iptables-allports[name=freeswitch-tcp, protocol=all]
#   sendmail-whois[name=FreeSwitch, dest=root, sender=fail2ban@example.org]  


[freeswitch-udp]  
enabled = true 
port = 5060,5061,5080,5081 
protocol = udp 
filter = freeswitch 
logpath = /usr/local/freeswitch/log/freeswitch.log 
action = iptables-allports[name=freeswitch-udp, protocol=all]
# sendmail-whois[name=FreeSwitch, dest=root, sender=fail2ban@example.org]

You also need to create the file /etc/fail2ban/filter.d/freeswitch.conf containing the following lines:
# Fail2Ban configuration file 

# Author: Rupa SChomaker 
# [Definition]  
# Option: failregex 
# Notes.: regex to match the password failures messages in the logfile. The 
# host must be matched by a group named "host". The tag "" can 
# be used for standard IP/hostname matching and is only an alias for 
# (?:::f{4,6}:)?(?P[\w\-.^_]+) 
# Values: TEXT 
# failregex = \[WARNING\] sofia_reg.c:\d+ SIP auth failure \(REGISTER\) on sofia profile \'\w+\' for \[.*\] from ip <HOST>
\[WARNING\] sofia_reg.c:\d+ SIP auth failure \(INVITE\) on sofia profile \'\w+\' for \[.*\] from ip <HOST>


# Option: ignoreregex 
# Notes.: regex to ignore. If this regex matches, the line is ignored. 
# Values: TEXT 

ignoreregex =


To configure fail2ban to protect the SIP ports against a denial of service attack on your server you need to create the file /etc/fail2ban/filter.d/freeswitch-dos.conf containing the following lines:
# Fail2Ban configuration file 

# Author: soapee01 
#  
[Definition] 
# Option: failregex 
# Notes.: regex to match the password failures messages in the logfile. The 
# host must be matched by a group named "host". The tag "" can 
# be used for standard IP/hostname matching and is only an alias for 
# (?:::f{4,6}:)?(?P[\w\-.^_]+) 
# Values: TEXT 

failregex = \[WARNING\] sofia_reg.c:\d+ SIP auth failure \(REGISTER\) on sofia profile \'\w+\' for \[.*\] from ip <HOST>
\[WARNING\] sofia_reg.c:\d+ SIP auth failure \(INVITE\) on sofia profile \'\w+\' for \[.*\] from ip <HOST>
# Option: ignoreregex 
# Notes.: regex to ignore. If this regex matches, the line is ignored. 
# Values: TEXT 

ignoreregex =


Now you need to add the following to /etc/fail2ban/jail.local
[freeswitch-dos] 
enabled = true 
port = 5060,5061,5080,5081 
protocol = udp 
filter = freeswitch-dos 
logpath = /usr/local/freeswitch/log/freeswitch.log 
action = iptables-allports[name=freeswitch-dos, protocol=all] 
maxretry = 50 
findtime = 30 
bantime = 6000

If you refer to http://wiki.freeswitch.org/wiki/Fail2ban you will see that they also suggest you consider an O'Reilly script to add as well.  I haven't done this yet.

Now edit /etc/fail2ban/fail2ban.conf and set logtarget = /var/log/fail2ban.log 
Unless you do this all the instructions on those websites that tell you to look at the fail2ban log will be irrelevant as you won't get any log created!

Once it is all configured you need to reboot your system or /etc/init.d/fail2ban start

Then you can look at /var/log/fail2ban to see what fail2ban is doing.  Also you can use the following commands to see the current status of IP addresses that are blocked.
iptables -n -L fail2ban-fusionpbx
iptables -n -L fail2ban-freeswitch-tcp
iptables -n -L fail2ban-freeswitch-udp

Presumably you can use a client with an IP address that is not configured as unable to be banned and fail to log in successfully to the fusionpbx web interface more than 3 times to see if it gets banned.  To test that SIP banning works you can configure a SIP client with an invalid login and let it try connecting and you can see if it gets banned.  As for testing the denial of service attack I'm not sure how you would do that so you might just have to trust the people that created those instructions that they got it right and you'll be protected!

Monday, July 4

FusionPBX 2.0!

FusionPBX 2.0 has just been released!  There are a heap of new features since the 1.0 version.  Hopefully I'll have some time soon and I'll install CentOS from scratch using the instructions now provided in the FusionPBX wiki (http://wiki.fusionpbx.com/index.php?title=CentOS_Install)  and get 2.0 up and running.

But first, I think I'm going to try to add fail2ban to my existing installation to prevent brute force attacks on it.

Stay tuned...

Thursday, April 7

Updating Freeswitch

[this blog entry has been revised 11-April-2011 after helpful comments from Yitzchok - thank you!]

So I explained in an earlier blog entry how to compile freeswitch.  But after you've done it the first time, how do you update it later?  If ever you need to get help from the Freeswitch team they will require you to be on the latest git.  The steps are similar but shorter.


cd /usr/local/src/freeswitch
git pull

This will bring down the latest git from the repository
make current
 
This will upgrade the freeswitch that is on your harddrive but will not touch the freeswitch instance currently running in memory.  When it has completed the upgrade you can schedule a time to restart FreeSWITCH so that it begins to run the freshly compiled version. 

You might get errors as I did - these were the errors I received:
make[5]: *** [mod_opal.lo] Error 1
make[4]: *** [all] Error 1
make[3]: *** [mod_opal-all] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

In my case, I wasn't too concerned about the opal module as I don't actually need that functionality, so I just edited modules.conf again and commented out the opal module.  If you can't comment out any modules you have an issue with then you might need to get help from the FreeSWITCH irc channel.  After correcting errors, you can try to make again in the same way as before.

Once it has completed successfully you can choose your time to restart freeswitch.

Friday, February 25

DTMF issues

One of the reasons that I stopped using Trixbox was because there was an ongoing problem with it as to how it handled DTMF codes.  If you were calling a remote service such as a conference bridge or an automated payment system that required you to enter DTMF codes it would not pass them through properly so that the remote system could handle them correctly.

FreeSWITCH does pass them properly.  However, this doesn't mean that you will avoid all problems.  Beyond this point there will mostly be problems with client configuration.

I have Linksys and Grandstream ATAs.  Linksys have an AUTO mode that selects the most appropriate method for DTMF handling (who knows how...) - it seems to work well.  Grandstream require you to select for DTMF to be sent in Audio or in RFC2833 or in SIP info packets.  If you select more than one of these options simultaneously you may cause yourself problems.

In early versions of FreeSWITCH it seems that the audio stream was somewhat muted while RFC2833 packets were being sent, however in recent builds this is not the case.  So in an earlier build my Grandstream worked happily with audio AND RFC2833 being sent simultaneously, but in a later build this resulted in the far end being unable to understand the DTMF signals - as it was getting extra digits due to hearing both the RFC2833 packets AND the audio DTMF.

So if you have problems with DTMF being understood by remote systems, check to see if you are using more than one method of sending it.

Tuesday, February 22

Compiling FreeSWITCH

This is something I was putting off doing as it seemed a little too complicated to learn to do.  But I can no longer put it off.  As you know if you've been reading my blog, I'm using a FusionPBX/FreeSWITCH build that came as an ISO and was created in April 2010.  That means it is getting old.  I keep FusionPBX up to date as that doesn't require re-compiles, but I've never learnt to compile FreeSWITCH.

Unfortunately, FusionPBX now relies on the presence of a module (valet park) that wasn't included in the ISO and therefore it is time to either build again using a currently available ISO (ie. UBUNTU) or to learn to recompile FreeSWITCH.  While I am interested in trying the Ubuntu ISO, I think it is ultimately going to be more worthwhile to learn to compile FreeSWITCH.  So here goes... But one extra note first - few of us have the luxury of a dedicated development box that we can compile on, so I'm going to be doing it on my live system.  This means that I need to compile it in another directory and when it is finished I'll need to swap the directory structures (with a brief outage of FreeSWITCH while I do that).  To do this, instead of using make install to compile FreeSWITCH, I'll be using make alone and delaying the install part.  If you do have the luxury of a development box go ahead and use that rather than placing unnecessary load on your live system - you could zip the directory structure and ftp it to your live system and have a brief outage while you unzip it into place (with freeswitch stopped at the time), however, I did try doing this and failed.  Having now tried the method below I'm convinced that this method below is the better option because it preserves your FreeSWITCH configuration files during the upgrade.

Be warned, compiling FreeSWITCH, although not difficult, will take time - there is lots of time spent waiting for your computer, so get a book or something else to do and then you can get started.

Before starting with FreeSWITCH, I'll need GIT - which wasn't included in the ISO.  The instructions for this are here http://wiki.freeswitch.org/wiki/Git_Install.  Follow them exactly - they are simple!

After that we need to follow a modified version of http://wiki.freeswitch.org/wiki/Installation_Guide.
First: get the prerequisites in place for building freeswitch.  If you are cutting and pasting these commands please do these two separately as you will have to respond "Y" to each one as it runs so that it can continue.
yum install autoconf automake gcc-c++ git-core libjpeg-devel libtool make ncurses-devel
yum install unixODBC-devel openssl-devel gnutls-devel libogg-devel libvorbis-devel curl-devel libtiff-devel libjpeg-devel

Next: download the source from git
cd /usr/local/src
git clone git://git.freeswitch.org/freeswitch.git

Next: switch to the source directory so we can start building (note that the following commands are all issued from that directory
cd /usr/local/src/freeswitch

Next: build the configuration files
./bootstrap.sh

Next: configure
./configure

Next: the next step in the instructions is to edit modules.conf - the best way to handle this in my opinion is to compare the modules list in your active FusionPBX system with the modules.conf file and edit the conf file to enable all the modules that FusionPBX requires.  Note that you will need to make quite a number of changes as FusionPBX uses a number of modules that are not enabled in the default FreeSWITCH configuration.  It is probably unnecessary to disable modules that FreeSWITCH has enabled by default, but just ensure that you enable FusionPBX required modules.  To do this use nano and when you are looking through the file you can use CTRL-W to search for a module and then to enable it, ensure that the start of the line it is on does not have a # (ie. a comment character - when it is commented the compiler ignores it).  Be aware that some modules might not be present in the default modules.conf file, if this happens you could search the FreeSWITCH wiki for the module name to see if it has been deprecated and replaced by a new module - you might want to start by looking here: http://wiki.freeswitch.org/wiki/FreeSwitch_Modules.  If you still can't find it, go to the #freeswitch irc channel and ask there (http://webchat.freenode.net/?channels=freeswitch).
nano modules.conf


Next: the moment of truth (and a long long moment) - we now make the new build
make

You might get errors as I did - these were the errors I received:
make[5]: *** [mod_opal.lo] Error 1
make[4]: *** [all] Error 1
make[3]: *** [mod_opal-all] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

In my case, I wasn't too concerned about the opal module as I don't actually need that functionality, so I just edited modules.conf again and commented out the opal module.  If you can't comment out any modules you have an issue with then you might need to get help from the FreeSWITCH irc channel.  After correcting errors, you can try to make again in the same way as before.

Once you have completed a successful make you will be told that you can install it using make install.  At this point you need to plan your outage.  When you do make install it will do a bunch of stuff (a couple of minutes) and then at the time that it starts copying files into the freeswitch directory structure it will kill your  running instance of freeswitch.  Once it completes (in my case under a minute later) a quick reboot of the system was all that was required to get it up and running again.  So your outage really only needs to be a few minutes long and then you are up and running again with a fresh install of freeswitch.

Just a note - if you had to substitute modules because ones you were previously using have been deprecated it is important after you have restarted your system to go to the modules page in fusionpbx and change the module entries to reflect the new names of modules that need to be started.  All the ones that aren't there anymore will show with a bold stopped so that you know they need to be fixed.

Monday, February 7

Double NAT

I wanted to put a phone for my phone system on someone else's home network.  This means that the FreeSWITCH/FusionPBX server is on my home network behind NAT and the phone is behind NAT on their home network.  ie. it is a double NAT scenario.

This worked for me - I created a doublenat sip profile following instructions in the FreeSWITCH wiki (http://wiki.freeswitch.org/wiki/General_NAT_example_scenarios).  If you want to save yourself some trouble you can upload this to your server in the freeswitch/conf/sip_profiles directory on your server.  Make sure you set the permissions on the new file to be the same as the existing profiles in that directory.  After this  you should be able to restart freeswitch and see the new profile there.  You will need to register the remote phone with your external IP address:5090.

Download the doublenat profile here.

Wednesday, January 12

Outbound failover

I have multiple VOIP provider accounts and I wanted to have failover so that if one provider is down it will automatically try the next provider.  This can be achieved in the outbound routes section of the dialplan by having your first and second actions being:
set continue_on_fail=true
set hangup_after_bridge=true

The first one says that if you fail to bridge the call to a provider on the first attempt then don't give up - continue to the next instruction - the default action would be to stop executing instructions after the first attempt.
The second one says that if you do successfully bridge the call, that will be the last instruction you execute - without this the continue on fail would cause each bridge instruction to be executed in order - so if you have 3 different voip providers this would mean that every call you make would be placed 3 times! (after you hang up the first time it would call them again).

After these actions you can have each of your bridge actions to each of your providers.

As an aside, I have a troublesome provider that will not route my call if the caller_id value I pass to them is not my registered VOIP number with them.  So in my outbound routes I have to set effective_caller_id_number=myvoipnumber before I bridge to them.  This overrides the normal setting I have of set effective_caller_id_number=${outbound_caller_id_number}.  I also have set effective_caller_id_name=${outbound_caller_id_name} but the provider doesn't mind what I set that to.

Wednesday, December 15

FusionPBX in a virtual machine

I've been playing around with virtual machines.  Ideally I'd like to try it with Proxmox VE or Vmware ESX however I don't have a machine with Hyper-Threading capability (see See which processors are supported on Intel's website) available to play with.  So I've been playing with VirtualBox.  More on that shortly.

Why would I want to do this?
- virtualisation is good for the environment - ok, I'm only half serious expressing it this way, but it is true, if I can virtualise my servers I can use less physical machines and therefore use less electricity.  I can also use less space for them.
- virtualisation gives you the capability of making snapshots - this is an image of your entire server at a moment in time.  This gives you somewhere to roll back to easily (someone is going to hate me for saying this, but it is a bit like using Windows System Restore and creating restore points).
- virtualisation makes backups easier - you can backup the harddrive container and you've backed up the entire server

So what did I do?
I installed TinyCoreLinux (TinyCoreLinux website) on my harddrive as it is a really stripped down version of linux.  Then I installed VirtualBox on top of that (VirtualBox OSE is available as a package to automatically install on TinyCore) and then I created a harddrive image of FusionPBX by installing the Centos ISO version of FusionPBX (see my first blog entry for the download link) into a virtual server in VirtualBox.  Note that if you use the Centos ISO you really should give it a minimum of 384Mb of RAM or you'll probably have issues with response time and sound quality.  I also set it up using a bridged ethernet adapter rather than the default NAT adapter as this will simplify life.

Then I copied the fusionpbx and freeswitch directories (and all their subdirectories) from my live FusionPBX server into the virtual server in order to give myself a real situation to test it with.  And then I turned off my live FusionPBX server and changed the IP address on the virtual server so that it was using the IP address of the real server and then I could use it with all my existing phones and configuration without any more work.

But does it work?
Would I be telling you this if it didn't?  (Actually I probably would tell you so that you wouldn't waste time trying the same thing)  The good news is that it works.  My usage of this is for a home VOIP phone system and it does this well.  I probably wouldn't use it in VirtualBox running on TinyCore for a real production phone system, but I'd be willing to try it on a PC that supported Hyper-Threading using Proxmox VE or Vmware ESX.

Sunday, December 5

Permissions again...

Ok, I've revised some of my earlier thoughts on permissions.   I encountered a strange problem that as long as you didn't restart the machine freeswitch would continue to run beautifully, but if you restarted the machine you had to manually restart freeswitch.  If you refer to the http://fusionpbx.blogspot.com/2010/11/this-may-be-better-approach-to.html section it has now been revised to reflect the fix for this.

Note though that if "/etc/init.d/freeswitch start" fails to start freeswitch it might be like me, that in trying to get it working I've started it once with root permissions and the pid file therefore has root permissions and can't be removed - "rm /usr/local/freeswitch/run/freeswitch.pid" resolved this and it was able to start after that.

Wednesday, November 10

Default functionality

FusionPBX comes preconfigured with powerful features.  There are some things you might want to disable or change though.

For instance.  If you have SIP phones (as opposed to using ATAs with traditional phones) they might do unexpected things.  One example of this is that *8 followed by an extension is the freeswitch preconfigured intercom function that is defined in the advanced dialplan.  Unfortunately on Yealink phones if this is enabled a person can call your phone with it and without you needing to accept the conversation the phone automatically answers the call and turns on your microphone - so they can hear everything that is being said in the presence of your phone without you having authorised it.  So you might want to disable this.  Actually, FusionPBX ships with intercom.lua in the freeswitch/scripts directory and if you set up this intercom it mutes the line of the person receiving the intercom call until they accept the call - a much safer option.

You might also want to disable the "eavesdrop" functionality provided in the advanced dialplan too.

Additionally, you might want to change the pin on the DISA dialplan entry (not in the advanced dialplan) - theoretically if you enable direct dialing from IVR and you left this as the default pin and someone knew you had a fusionpbx phone system they might be able to dial it from an IVR and make long distance phone calls at your expense because it was still using the default pin.  I'm not really sure if that is possible but is it worth the risk?

While I'm at it, if you do edit your advanced dialplan and make a mess of it you'll want to restore it.  For some reason my restore default button on the bottom of that screen didn't restore the default but instead left me with an empty file.  I had to copy the default from /var/www/fusionpbx/includes/install/dialplan/default.xml
However, I made a big error.  Before doing this I backed up my current default.xml file and left the old copy in the same directory with the extension .xml.  Unfortunately freeswitch still processed the backup because it had the extension .xml and therefore my error didn't go away!  So if you are going to make a backup in the same directory give it a different extension eg. .old

Note that if you to create a mess of your advanced dialplan you may generate errors when you apply settings.  eg. '+OK [[error near line 4968]: unclosed'.  To locate this use an editor such as nano to look at freeswitch/log/freeswitchxml.fsxml - this file is generated by freeswitch when it is processing your dialplan files.  In nano CTRL-_ will allow you to enter the line number from the error message.  When you have seen the line in that file you can then go back and look for the corresponding line in the advanced dialplan and fix the problem.  Note that the error might not be on that line - in my case it said it was near that line but it did enable me to locate the problem.

Thursday, November 4

This may be a better approach to permissions

One of the most common problems observed in the FusionPBX forum are permission issues.  The balance you have to achieve though is security vs. usability.

By default, the Centos ISO comes with freeswitch having an owner of freeswitch and a group of freeswitch and fusionpbx has an owner of apache and a group of daemon.  As a result there are problems of interoperability between the two that have to be solved by using chmod to set permissions for group and other and by using chgrp to change the group on some directories.

One solution to this dilemma is to set the owner and group on both to be the same as each other.  Accordingly you might want to try this:
chown -R apache:apache /usr/local/freeswitch
chown -R apache:apache /var/www/fusionpbx

Keep the chmod as 755 on /usr/local/freeswitch and /var/www/fusionpbx.  In fact you could even try 700 or 600 if you want.
CORRECTION: you can keep 755 on fusionpbx but you need 775 on /usr/local/freeswitch.  You also need to edit /etc/group and change the line "apache:x:48:" to "apache:x:48:freeswitch,apache".  With this change freeswitch is able to start without needing to be run by root.

Security experts might want to comment on why doing this would be a bad idea....?

NOTE: The instructions above assume that the owner of the fusionpbx directory on your server is apache. On ubuntu and other systems it might be www-data or something else.  Take a look at the existing owner of this directory and that is the owner to make use of in the instructions above.  It is basically your webserver's account.

Thursday, October 28

An issue with the default IVR behaviour

When you dial into a phone system and are greeted by an IVR, if you choose an option on the IVR that you expect to be answered by a human you expect to hear the phone ringing as you wait for a human to pick it up.  However, due to the way the Local_Extension is defined in the default FreeSwitch dialplan, it will instead play music on hold to the caller and there is nothing you can do to override that setting without altering the FreeSwitch dialplan.

Typically when a human transfers a call you expect to get music on hold while they do that for you (sometimes people like to make an exception for calls transferred by the receptionist, but even then, music on hold would be appropriate), but when an IVR transfers a call you do not expect to be placed on hold as the IVR is a computer and should be giving you its full attention, not placing you on hold while it does something else - therefore you expect to hear a ringing sound if the IVR transfers you to a human.

Accordingly the following steps allow you to alter this behaviour and override the music on hold in order to provide a ringing sound to the caller when transferring a call from an IVR.


1. you need to go to the FusionPBX System-Variables screen and create a new variable in the Music on Hold section (with an order higher than the hold_music variable - you could use 500 for example).  The new variable will be transfer_ringback and you should set it to $${hold_music} and enable it.
2. you need to go to the FusionPBX Dialplan-Dial Plan Manager and click on the advanced button.  Then once the XML edit window is displayed scroll down in the XML until you find "Local_Extension".  Note that if you press CTRL-F a search window will appear and you can search on that - include the " characters when you search or you will get another entry that isn't relevant.  The entry you should find is .  A few lines below that you will find .  You can either remove this line or comment it out - to comment it add !-- after the < at the start of the line and add -- before the > at the end of the line.

The reason that you need to make these changes is that the default config provided in freeswitch (and FusionPBX) is a demonstration config and is intended to be customised by people when it is implemented in a live system.  The problem with having the transfer_ringback entry in this section is that it prevents you overriding the default setting, as every time a call is transferred to an extension the transfer_ringback is set to music on hold.  Therefore step 1 here sets a default setting in vars.xml and step 2 removes the line that sets the variable every time a transfer happens.  

Now any time you prefer a ringing sound when you do a transfer from an IVR you can use one of two options:


1. set transfer_ringback=${us-ring} in a dialplan entry immediately prior to the IVR
2. add an extra entry to each option in your IVR, before the transfer but with the same option number and have it execute the line below
 menu-exec-app:set transfer_ringback=${us-ring}

This will replace the music on hold with ringing sounds when you are transferring from an IVR.

Sunday, October 3

Simple recording management in FusionPBX

I wanted to be able to play a message to callers and to make it easy for users of the phone system to update the message without needing to understand how to administer the phone system.  So I developed a javascript that can be used to do this.  If you want to use it, download the javascript from here: easyrecording.js  and save it in the scripts subdirectory of your freeswitch folder (on my system this is /usr/local/freeswitch/scripts).

This script is designed to allow you to setup a message that users can update directly from their phones without needing to do any administration of the phone system directly.  It uses four channel variables which must be set depending on the mode used, prior to calling the script:
    mode, filename, title, auth
Note that this script generally relies on speech synthesis to prompt the user as (a) the user is an administrator of the system and therefore prettiness is not important, (b) the script does not need to be supplied with any additional files.  Because speech synthesis is used, if you type a response while the speech is occurring the speech will not stop, however your response will be noted and processed at the end of the speech.  Accordingly the flite module will need to be enabled on your system in order to use this script.

It has six modes:
1. mode=play
    filename=the name of the file you want to play (without any extension as wav is assumed)
    In this mode, it will play the file from /usr/local/freeswitch/recordings/easyrecording/.  If the recording does not exist it will play an error message.  Moral of the story - record all your recordings before users get to hear them!
2. mode=record
    filename=the name of the file you want to record (without any extension as wav is assumed)
    title=an introductory heading for the recording menus that are used when the user is updating this recording
    optional: auth="permit" will result in authentication not being required to change recordings
    In this mode the user will first hear the current message and then be given the ability to re-record it and confirm that they are happy with it before replacing the original recording.  If auth is not set then the script will assume that the user is maintaining only the current recording and will prompt for the pin for that specific recording - in this case, no channel variable will be set when they authenticate.  Note that recordings that are no longer required can be manually deleted from /usr/local/freeswitch/recordings/easyrecordings.
3. mode=auth
    filename=the name of the menu structure that you are authenticating the user for.  This is not actually a filename but is simply used to represent the menu structure in the pin database.
    title=an introductory heading for the menu structure
    In this mode, the user will be authenticated and the auth channel variable will be set to "permit" if the user enters a valid pin.  This mode is intended to be used at the start of an IVR for maintaining multiple recordings.  Until they hangup, thus ending the authorised session, they will be able to update any recording listed in the IVR.
4. mode=pinreset
    In this mode the master pin can be used to change any other pin if someone forgets their pin.  It can also be used to remove obsolete pin registrations from the database as to change a pin it is simply deleted - which resets it to the default pin of 7777.
5. mode=setmasterpin
    This allows you to set the master pin.  It should only be known by the phone system administrator.  The dialplan entry you use to run this should be removed as soon as you have set the master pin.  Assuming you don't forget it you will never need to use this mode again.
6. mode=maintenance
    In maintenance mode you are presented with a list of all the recordings and you can choose to re-record any of them. This script is designed such that you can create an IVR to do this for specific recordings where you want to give one person responsibility to maintain a subset of recordings, but if you only have a small system then it may be simplest for one person or group of people to maintain all recordings and this is where this mode can be used.  You may still want to have a different individual maintain some recordings, and that is fine, you can set up an IVR for them to use.
The first time a recording is made or authorisation is required, the user will be asked to enter the default pin.  The default pin is 7777.  It cannot be used at any other time except to set a pin the first time the pin is used.  When the phone system administrator sets up a menu using the easy recording system they will need to inform the user who will be maintaining it that they must use this pin when they set the recording the first time but that they will get to set their own pin at that time.

As an example.  I am setting up a simple phone system for a small business.  They will have one person who maintains all recordings and I'm going to get them to do it using the built in maintenance mode.  To make the initial recordings I have set up a dialplan entry called "temporary" with the following definition:


TagTypeDataOrderadd
  condition  destination_number  ^1$  1edit delete
  action  set  title=Main menu choices I V R  0edit delete
  action  set  mode=record  3edit delete
  action  set  filename=../main_ivr  4edit delete
  action  javascript  easyrecording.js  13edit delete
You will see here that I have separated "I V R" into separate words so that the speech synthesiser will spell them out rather than trying to pronounce the word "ivr".  In my case here, I am recording the choices used to introduce an IVR on the system.  This simplifies my setup of the IVR as now I can just select this recording from the menu once I've recorded it using this temporary dialplan (by dialing 1 from a phone).

You will also note the little trick I've done to make sure that the recording can be used in an IVR - in the filename I have included "../" at the start of it.  This is because, by default, recordings made using easyrecording.js are kept in freeswitch/recordings/easyrecordings - this is perfect for when the recordings are intended to be played back using the easyrecording.js playback method, but if they need to be used with an IVR they will not work if they are in a subdirectory below the recordings directory.  Accordingly, the "../" tells the script to record it directly into the recordings directory rather than the subdirectory.   You would only do this if you need to use your recording with an IVR or something else in freeswitch where it needs it to be in the recordings directory.  The rest of the time you can just enter the filename on its own in this variable.

Note that if you want to use a recording with an IVR, apart from ensuring it is placed directly into the recordings subdirectory you may also want to update the default configuration of the recording in the Apps-Recordings screen in FusionPBX to give it a more meaningful name.  This isn't a necessary step as it will automatically be listed there already, but is required if you want to give the recording a better human readable name than the filename you set for the recording.

Note that even if you are going to do all your recording maintenance using maintenance mode, it is necessary to set a pin on each recording - this is because if you do not set a pin then no record is kept of the recording in the table that is used to operate maintenance mode.  In such a case, the only record of your recording is the recording itself (this would happen if you set auth=permit prior to making your recording - this can be used for doing one off recordings if you desire rather than using the FusionPBX built in recording function accessed by dialing *732673).

After creating this dialplan, apply the settings and dial the number for your dialplan (in my case 1), make your recording, then you can change the title and filename and apply the settings and record another recording - do this until you have an initial recording for each of the messages you want.  Then you can delete this dialplan entry (or disable it if you think you might want it again in the future) and do all your administration of the recorded messages using maintenance mode.

This is the dialplan entry that I've set up to enable them to maintain the recorded messages:

TagTypeDataOrderadd
  condition  destination_number  ^999990$  1edit delete
  action  set  mode=maintenance  3edit delete
  action  javascript  easyrecording.js  4edit delete

As you can see, there is nothing to it.

If you are going to play a recording from an IVR entry, you can actually do it with a built in function in the IVR that can play a WAV file for you.  The IVR entry you would need is menu-play-sound:../../../../recordings/easyrecordings/the_name_of_your_recording.wav

I hope this example helps you to experiment with this tool.  If you find this useful I'd love to get feedback.