Fight the roaming costs with FreeSWITCH

Roaming costs in Europe are quite high, and one can easily spend ~EUR100 for a one-hour call (I did it myself, but my time was paid :-)). This scenario is built to bring down those costs to the price of local calls.

This example assumes that I travel through Germany with a German SIM card with cheap Internet data plan enabled (, for example). My home FreeSWITCH server is connected to a SIP provider that allows me to set the Caller ID to an arbitrary phone number. Also calls from FreeSWITCH to German numbers are assumed to be cheap.

#### User directory in conf/directory/users/ssinyagin.xml

 <user id="7016">
      <param name="a1-hash" value="b7bfbba6fc6e46cf666ceab54b843e79"/>
      <variable name="user_context" value="callback"/>
      <variable name="originate_aleg_number" value="7017"/>
      <variable name="outbound_caller_id_number" value="0794070224"/>

  <user id="7017">
      <param name="dial-string" value="[group_confirm_key=1]loopback/00491637743380/default"/>

Here the user 7017 is an alias for my temporary number in Germany. It also asks to press 1 to answer the call, so that the call never lands into a voicemail or the operator’s message that the user is unavailable.

The user 7016 is a SIP user that is used to initiate the call-back. So, on my Android phone with a German SIM card, I can use SIPdroid application to dial numbers from the standard address book and the call log.

The calls from the user 7016 go into the “callback” context, and this context has only one extension that matches all numbers. It schedules an API call in 2 seconds, plays an ugly tone for 1 second, and then hangs up. The API call executes a Lua script. It uses my Swiss mobile number as the Caller ID when it calls the destination number.

#### conf/dialplan/callback.xml
  <context name="callback">    
    <extension name="callback_hung_and_originate">
      <condition field="destination_number" expression="^(\+?\d.+)$">
        <action application="info"/>
        <action application="answer"/>
        <action application="set" data="api_result=${sched_api(+2 none lua callback.lua ${originate_aleg_number} ${destination_number} ${outbound_caller_id_number})}"/>
        <action application="gentones" data="%(1000,0,430,450,550)"/>
        <action application="hangup" data="NORMAL_CLEARING"/>        

The Lua script follows. It’s pretty simple, it originates a session to my German mobile number, then bridges it with the initial destination number.

#### scripts/callback.lua

aleg_num = argv[1];
bleg_num = argv[2];
caller_id = argv[3];
t_started = os.time();

session1 = freeswitch.Session(string.format("{origination_caller_id_number=%s,call_timeout=30}loopback/%s/default",
                                            caller_id, aleg_num));

while (session1:ready() and not session1:answered()) do
  if os.time() > t_started + 30 then 
    freeswitch.consoleLog("info", "callback.lua timed out for " .. aleg_num .. "\n");
    freeswitch.consoleLog("debug", "callback.lua: session is not yet answered for " .. aleg_num .. "\n");

if session1:ready() and session1:answered() then
   session1:setVariable("outbound_caller_id_number", caller_id);
   session1:transfer(bleg_num, "XML", "default");
   freeswitch.consoleLog("info", "callback.lua: session is not functional for " .. aleg_num .. "\n");

Why didn’t I use the built-in “originate” application in FreeSWITCH? Because it copies all variables from A-leg to B-leg, but I want to set the caller ID differently for the two legs.

The “outbound_caller_id_number” variable is not a standard FreeSWITCH variable, and it’s used in my PSTN outgoing extension to set the SIP header with the desired Caller ID.

Also calls to my home mobile number are forwarded to the same FreeSWITCH PBX, and it forwards the calls to my German mobile number.


, ,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: