SOLVED Phonebook on the Grandstream phone (and use the contacts list to fill the from-header)

Not open for further replies.


New Member
Nov 4, 2018
Hi all,

I was wondering if I could use the FusionPBX contacts and upload them to a Grandstream phone. Well, it doesn’t work out of the box.
As I have it working now and it took a lot of my time, I will share it with this forum. I’m using the latest FusionPBX 5.1 and Freeswitch 1.10.11, installed with the preferred script from

First of all, in the current firmware Grandstream doesn’t pass the mac address in the URL. Instead, it’s in the User-Agent string in the header. To pass the request, you have to add an extra rewrite rule in /etc/nginx/sites-available/fusionpbx:

rewrite "^.*/provision/phonebook\.xml$" /app/provision/?file=phonebook.xml;

In the Grandstream Phonebook XML server path, you can use the PBX URL followed by /provision, I use HTTPS.

FusionPBX: Do not forget to copy the default provision settings to the domain and modify them (if you have multiple domains), I used these settings, where the “http_ fields” and “enabled” are most important:


Luckily, the code to process the mac header is already present, so no further changes are necessary.

To test, I added a company and telephone number and uploaded this to the Grandstream. Unfortunately, I still got an empty phonebook, so after some debugging I found:
  • Grandstream needs at least a name field like First- or Last Name, only a company name doesn’t work
  • The number type must be Voice and the label must be filled, I used Work (a FusionPBX requirement)
Now we can start uploading the phone list. This also requires some knowledge:
  • The field separator has to be changed to “ ,” (in Europe, “;” or tab is used).
  • Special characters are not allowed and break import (like &)
  • The file import sometimes produces an error (SQLSTATE[08P01]: <>: 7 ERROR: bind message supplies 5 parameters, but prepared statement "" requires 6), but pasting the data on the screen works without errors
  • You can save a lot of work by adding a header with the real field names like “contact_name_given,phone_number,phone_type_voice,phone_label”
  • I added “,1,work” to the data to fill the last two fields, like Company X,01234567,1,work
  • The number must be in the same format as displayed on the phone
  • Memory in the phone is limited, but a late model like the 2614 accepts over 1500 numbers
  • Grandstream uses some reserved groups, like blacklist. Some phones didn’t upload the phonebook, but after a phone reset uploading works. Maybe some groups are conflicting, not sure yet.
Note: Some Grandstream phones do not have the right templates, the template from the grp2612 works for the 750 and the 2100 (both not working for the phonebook)

Fill the from-header to display the caller's name

Now this is working, I wondered if it’s possible to fill in the caller’s name from the contact list, as this is far less work and configuration, besides the phone book is not very practical for dialing numbers if it’s large (you have to type in a lot of letters on the numeric pad).

Searching the code, I found /usr/share/freeswitch/scripts/cidlookup.lua

You need to change the dial plan to use this script as specified in the header:

action set caller_id_name=${luarun cidlookup.lua ${uuid} ${domain_uuid}}

I tested the script, but it doesn’t work that well if one of the contact fields is empty. I also found that the SQL query tests for empty strings (line 85), but that doesn’t work for PLSQL (I think it should be “IS NULL”). Doing some debugging I found that also the database type wasn’t filled and the sql from the ELSE was executed, so it looks like this code is deserted.

I also found Freeswitch has also a build-in function cidlookup. It’s configured in /etc/freeswitch/autoload_configs/cidlookup.conf.xml and can be easily tested through the FS_CLI console and it works!

Start by enabling the module cidlookup and start it (from the menu). In the console you can type “cidlookup status” to check if it’s working. With “cidlookup <number>” you can search a number from the contacts. Unfortunately, it gives an error in mod_memcache. You can disable the cache (line 11) or install the package Memcached. I choose to install memcached.

After reloading (RELOADXML in the console), I get the result UNKNOWN for an existing number. As dsn_system is not known yet, it has to be added as a variable (advanced menu, under defaults). Add this value: “pgsql://hostaddr= port=5432 dbname=fusionpbx user=fusionpbx password=xxxxxxxxxxxxxxxxxxxx options=” without the quotes. The password can be copied from /etc/fusionpbx/config.conf

Now “cidlookup status” should display the odbc-dsn and the lookup of a known number should work.

Now enable cidlookup in the dialplan manager near the end of the list (order=870). You should also change the format of the caller_id_number to your local format.
I changed the format (allow numbers with length 6-12) and replaced the $1 with the caller_id_number. In the XML view it looks like this:

<extension name="cidlookup" continue="true" uuid="cb3ff364-ca6e-4c67-8ba6-129b4a5ac0f3">
<condition field="${user_exists}" expression="^true$" break="never"/>
<condition field="${call_direction}" expression="^inbound$" break="never"/>
<condition field="${module_exists(mod_cidlookup)}" expression="^true$" break="never"/>
<condition field="caller_id_number" expression="^\+?(\d{6,12})$" break="never">
<action application="set" data="cidlookup_caller_id_name=${cidlookup(${caller_id_number})}" inline="true"/>
<condition field="${cidlookup_caller_id_name}" expression="^(?!UNKNOWN)">
<action application="set" data="effective_caller_id_name=${cidlookup_caller_id_name}" inline="true"/>

The number in the contact list should match the incoming number format, or you can correct it with the regex above.
You can check the result with the logviewer and search for cidlookup.
Last edited:
  • Like
Reactions: matt
Not open for further replies.