Kill roaming fees with open source

December 19, 2013

Recently I have been relocated to another country to work and live. This has obviously introduced various problems, one of those being the fact that I had to change mobile number.

International roaming fees are actually not so convenient, there are some “europe” packages - seems that from july 2014 roaming in europe country could become a thing from the past - but I did not found any that could satisfy my needs. In the past I read about people using Raspberry Boards and huawei dongle to build gsm gateways, so I tought to use the “becoming expat” affair as an excuse to improve my technical knowledge and get the hands dirty on Asterisk (I never done an Asterisk setup) and on VOIP setup.

Primary goals to accomplish:

  • Keep the same phone number [For the people that knows me already in my homecountry, like my parents and friends];
  • Receive/Make calls from/to homecountry to/from foreign country using a GSM phone, paying like a local homecountry to homecountry phone;
  • All VOIP traffic routed over Internet must transit encrypted, avoid sending conversations through clear channels;
  • Receive/Send SMS from/to home country to/from foreign country at local rates;
  • Receive/Make calls from/to homecountry to/from whatever world internet connected VOIP phone;

The (almost) open source recipe:

General implementation idea - Birdview

Here you can see a schema of the current implemented setup:

Schema of connections between various pbxes

WARNING Probably - surely - this is not the best setup, this is just what I were able to conceive. You have been warned. If someone else with more experience on the field could give me some advice to improve, well, I'm here!

The main idea is to have 2 raspby powered PBXs with the gsm dongle, one in my homecountry - Country A - and another one in the country where I now live as an expat. - Country B -. Another PBX, on the cloud, - Central PBX - will manage connections between both countries.

When someone calls me on my homecountry number (Country A), the system immediatly contact the central PBX; Once contacted, it is instructed to contact Country B remote PBX and at the same time to dial a SIP remote client.

On country B the PBX will find instructions to dial the country B mobile phone. Instead, when I want to call Country A from Country B mobile phone, I call Location B [calls to location B are allowed to be answered only from the mobile number of country B mobile phone, all other numbers will be hanged up], call is answered on location B and location B PBX asks what to do with the call to the central PBX.

At this point, an IVR configured on Central PBX asks the caller which number wants to be dialled on country A. Caller now has to send a DMTF code that corresponds to a frequently called number, or to enter directly the number to be called sending DMTF tones. After selection, central PBX asks the country A pbx to dial selected number, and hopefully, the roamingless call between countries could start.

More details

Setting up Raspbys PBX

At first, I tought just to pick up raspbian and install asterisk on it. But I had problems when trying to build chan_dongle driver on it, so I went on raspbx, that has everything I needed - more than I needed, actually - already installed. The distro contains the freepbx package, but honestly, for my needs it seemed overkill, so I did not used it. I wrote the configuration using vim on asterisk files.

The 3G dongles

I wasted a lot of time on this - apparently simple - part, not because there is something hard to do, but just because at first I bought two dongles that did not worked.

This ones:

Picture of huawei dongles

I found them new and at a good price, so I bought two of them, quite confident that they will work, because model seemed to be one of those compatible with chan dongle driver. See that E156 seems compatible? Nope.

Well, maybe E156 is compatible, but the E156G No.

At first I unlocked them - They come locked on the operator network -, and it was simple. You need a Software that generates a key, and then you have to upload it - Essentially sending a particular AT command, ‘manually’ or through a software -, and then you dongle is network free.

Finding the software was a bit complicated, cause there is a lot of people that asks money for the unlock. For the code generator you can search for Universal MasterCode

WARNING Be aware, this kind of things could attract scammers, so take your safety measurements before running the downloaded binary: You cannot know what it can do for real.

If you want to enter the code using the command, you can check this post. Or if you can download a tool like huawei code writer.

WARNING I already told you, keeps eye opened

I forget to mention, but for running those tools you need Windows. Or you could try to run them under linux with wine.

In the end, the problem with this dongle model seems to be that the firmware doesn’t support the voice mode. I tried different firmwares, without success. After a few days of struggling, I gave up, and searched for other dongles. This time I searched for already unlocked and VOICE ENABLED dongles. I found on ebay a seller offering two huwaei E1762/K3765, I bought them for almost 35€. They still work without problems.

Avoiding voice over clear channel

You could choose to use different protocols for establish communications between PBXs - voip trunks - on asterisk . Most popular are SIP and IAX2, and both of them supports encryption.

I choose to use IAX2 protocol - Why? It seems better - without enabling encryption directly. Maybe this was a dumb decision, but I opted to estabilish a VPN between all the various machines involved in the system. A vpn implemented using OpenVPN.

By this way, all three PBX can exchange data on an encrypted channel. The same channel could be used by other applications or whatever I will need in the future. And also I don’t have PBX services ports exposed directly on public network.

Installing openvpn has been simple. Just follow this simple debian howto. I set up the central PBX as the openvpn server, then I generated all the keys needed for the client machines - country A PBX, country B PBX, remote SIP client, my laptop.

Managing the calls, writing the configuration

You can find lot of documentation on Asterisk on the internet. AFAIK, the best source is the definitive guide. You can use the free live version or buy a updated copy of it.

For every raspby I cleared completely the provided asterisk extensions.conf files, then I configured chan dongle and next I wrote a simple dialpan entry for testing:

[dongle-trunk-context] ;Context reserved to calls coming from 3G dongle
exten => PHONENUMBERSIMINSIDEDONGLE,1,Verbose(Receiving call from ${CALLERID(num))
	same => n,Playback(asterisk-friend)
   		same => n,Hangup()

Save the file, reload asterisk, and if all is working good, you can now hear the asterisk voice, dialling for PHONENUMBERSIMINSIDEDONGLE. Now that we are sure that the dongle and asterisk are working, we can setup the iax trunks:

COUNTRY A iax.conf

[general]
autokill=yes
srvlookup=no
bindaddr=IPADDRESS.PBXAON.VPN

[inter-pbx-trunk](!)
delayreject=yes   ; delay authentication reject (limit brute force attacks)
disallow=all      ; reset the available voice codecs
allow=gsm        ; allow gsm codec

[central](inter-pbx-trunk)
host=IPADDRESS.CENTRAL.ON.VPN
type=friend
context=incoming_central
secret=SECRETKEYA
deny=0.0.0.0/0.0.0.0
permit=IPADDRESS.CENTRAL.ON.VPN/255.255.255.255

COUNTRY B iax.conf

[general]
autokill=yes
srvlookup=no
bindaddr=IP.ADDRESS.PBXBON.VPN

[inter-pbx-trunk](!)
delayreject=yes   ; delay authentication reject (limit brute force attacks)
disallow=all      ; reset the available voice codecs
allow=gsm        ; prefer the gsm codec

[central](inter-pbx-trunk)
host=IPADDRESS.CENTRAL.ON.VPN
type=friend
context=incoming_central
secret=SECRETKEYB
deny=0.0.0.0/0.0.0.0
permit=IPADDRESS.CENTRAL.ON.VPN/255.255.255.255

CENTRAL PBX iax.conf

[general]
autokill=yes
srvlookup=no
bindaddr=IPADDRESS.CENTRAL.ON.VPN

[inter-pbx-trunk](!)
type=friend
delayreject=yes   ; delay authentication reject (limit brute force attacks)
disallow=all      ; reset the available voice codecs
allow=gsm         ; prefer the gsm codec

[countrya](inter-pbx-trunk)
context=incoming_countrya
host=IP.ADDRESS.PBXAON.VPN
secret=SECRETKEYA
deny=0.0.0.0/0.0.0.0
permit=IP.ADDRESS.PBXAON.VPN/255.255.255.255

[countryb](inter-pbx-trunk)
context=incoming_countryb
secret=SECRETKEYB
host=10.9.8.11
deny=0.0.0.0/0.0.0.0
permit=IP.ADDRESS.PBXBON.VPN/255.255.255.255

Ok. That’s all for this post. Stay tuned for the next part.