Fixing FusionPBX Call Intercept

With FusionPBX it's easy to set up a call intercept + BLF so you get the nice blinking key on the phone which allows you to intercept the call if press on the button, but there is a case where it will fail

Fixing FusionPBX Call Intercept

I kind of have a déjà vu about this one, somehow I feel like I documented this somewhere already but I can't find it so here we go again.

Test setup

Configure three extensions, let's say 10,20 and 30. They can be a soft phone, you don't really need to have keys and BLF for this test.

Now from extension 10 call extension 20, as soon as it rings on extension 30 dial **20 which should intercept the call ringing on extension 20 and send the call to your extension 30. If it works, you're all good and you can stop reading. However, if you are using PostgreSQL you might run into this issue once in a while that the 'intercept call' (where you dialed **20)  just terminates and no call will be intercepted.

How to debug

A good start is to enable some debug parameters in /etc/fusionpbx/config.lua These two are a good start

        debug.params = true;
        debug.sql = true;

Now try again and look at your fs_cli and you will find something like this in the debug output:

SELECT uuid, call_uuid, hostname, direction, presence_id FROM channels WHERE callstate IN ('RINGING', 'EARLY') AND (1 <> 1 OR direction = 'outbound' ) AND (1<>1 OR presence_id = :presence_id_1 ) AND call_uuid IS NOT NULL LIMIT 1 ;
intercept SQL

and also the parameters part

params: {"presence_id_1":"35@foo.example.net"}
intercept params

Which then would result in the SQL

SELECT uuid, call_uuid, hostname, direction, presence_id FROM channels WHERE callstate IN ('RINGING', 'EARLY') AND (1 <> 1 OR direction = 'outbound' ) AND (1<>1 OR presence_id = '35@foo.example.net' ) AND call_uuid IS NOT NULL LIMIT 1 ;
final intercept SQL

If you connect to your PostgreSQL and try this select while it rings you should get some results, but looking at the intercept.lua and comparing with the debug output it looks like the SQL yielded no result.

2019-07-09 13:43:47.974684 [NOTICE] switch_cpp.cpp:1365 [intercept] Hostname: fpbx-ix Call Hostname:

Notice the empty Hostname in the output? ☝️

Ok so we really seem to be getting no results from the database even though selecting manually does give us data.

Which DB does it connect to?

Honestly, I didn't find an easy way to write some log output telling me which database it actually connected to, but while looking at the Lua scripts at some point I reached /usr/share/freeswitch/scripts/resources/functions/database/native.lua and here I found this piece of code:

  if type(name) == 'string' then
    if name == 'switch' and file_exists(database_dir.."/core.db") then
      dbh = freeswitch.Dbh("sqlite://"..database_dir.."/core.db")
    else
      dbh = database_handle(name)
    end
  end

can you spot the problem?

The intercept.lua is one of the few Lua scripts that connect to the FreeSWITCH database and not the FusionPBX database

--connect to FS database
local dbh = Database.new('switch')

But what was that in native.lua? if name == 'switch' and file_exists(database_dir.."/core.db") wait a minute ...

ls -l /var/lib/freeswitch/db/core.db
-rw-r----- 1 www-data www-data 73728 Jan 24 07:55 /var/lib/freeswitch/db/core.db

so here, apparently fusionpbx judging by the file owner created a core.db SQLite file which native.lua interprets as

I'm going to ignore the DSN you gave me and just go ahead and use the local SQLite file I just found

The fix

You can remove the /var/lib/freeswitch/db/core.db file or comment out the part checking for it existence, but be careful as it will be overwritten with next fusionpbx upgrade where this code still exists in this form. I really really think I wrote a Github issue about this.

  if type(name) == 'string' then
--    if name == 'switch' and file_exists(database_dir.."/core.db") then
--      dbh = freeswitch.Dbh("sqlite://"..database_dir.."/core.db")
--    else
      dbh = database_handle(name)
--    end
  end

This will just ignore the core.db file, at least for the Lua part, it might still be used via the web interface (hence the owner www-data) so I would recommend removing that file.

First, check if someone has this file open

lsof |grep core.db

if not, move it away or delete it. I would also recommend that you set up monitoring to check for the existence of this file and alert you if it somehow appears again as it will break call intercept!

Some useful tools

During my debugging of the issue I cam across inspect.lua which was very useful to see into those Lua tables.

Wrapping it up

If you have issues with intercept and use PostgreSQL for FreeSWITCH then check if the file /var/lib/freeswitch/db/core.db exists, removing it might solve your issue.