Friday, September 28, 2012

How to call for free with Google Voice, Android phone and Asterisk

Phone service is pretty expensive in US compared to many other countries. So instead of paying lets use Asterisk+GVoice+CSipSimple. Since most of my time I spend at the office or at home, I am rarely outside of WiFi coverage. This way I get away with paying $2-3 per month for prepaid when I need to make/receive calls when you are outside of Wifi.

You will need the following things:
  1. Google Voice account
  2. Android phone (CyanogenMod is recommended)
  3. Some Linux server, for Asterisk1.8. (Recommended: VPS. You can get OpenVZ hosting for as low as $3/mnth)
  4. Some WiFi coverage
  5. Some prepaid SIM card, for emergency situations when you are out of WiFi coverage. (I use T-Mobile prepaid)

How it works

Google Voice allows free incoming and outgoing calls in US and Canada. They do not provide any SIP service though. However, Asterisk provides SIP server and it can use XMPP channels to make/receive calls.
When phone losts WiFi coverage, Asterisk detects it and routes incoming calls to a regular cell phone number you provide. This solution does not use any data over 3G.

Installation & configuration

Google Voice account

  1. Set up Google Voice as normal.
  2. On your Settings page, make sure the only forwarded phone is your google account.
  3. On your "Calls" page, make sure:
    "call screening" is diabled
    "call id(incoming)" says "Display callers' number"
    "call id(outgoing)" says "Display my google voice number"
  4. Modify the rest to your liking

Asterisk Server

First lets install asterisk and download reference configuration files
# apt-get install asterisk
# cd /etc/asterisk
# wget -nd -p embeddedwits.com/asterisk/extensions.conf
# wget -nd -p embeddedwits.com/asterisk/sip.conf
# wget -nd -p embeddedwits.com/asterisk/gtalk.conf
# wget -nd -p embeddedwits.com/asterisk/jabber.conf
# wget -nd -p embeddedwits.com/asterisk/codecs.conf
 Then:

  1.  edit gtalk.conf and put your username
  2.  edit jabber.conf and replace your username and secret fields. 
  3.  edit extensions.conf and put your backup SIM number in line 25
  4.  edit sip.conf and update your secret field.

When you are done, issue:
# service asterisk restart

Android phone

  1. Go to Google Play and install CSipSimple application.
  2. Run the application
  3. Menu->Settings->Activate Expert mode
  4. Easy configuration-> check "always available"
  5. Network-> check "Lock WiFi".
    Check "UDP"
    Uncheck "TCP"
    check "Disable TCP switch".
    Connection Keepalive->Wifi UDP keep alive -> enter 15
    Network->For incoming calls - check all
    Network->For outgoing calls- check all
  6. Media settings:
    Check "echo cancellation"
    Echo mode - select "speex"
    Voice audio detection - uncheck
    Clock rate - select 8khz
    Codec priority list per bandwidth - uncheck
    Codecs - select "speex 8khz"
    Micro amplification - change to 8dB
    Speaker amplification - leave at 1dB
  7. Settings->user interface:
    Check "use partial wake lock"
  8. Now you need to add sip server.
    Go to main menu and click on the key icon.
    Click "Add account"
    Select "Expert",
    type some account name, account id, server ip and, username and password.
    Type * as "Realm"
    Select "UDP" as transport.
  9. Decide how you want the app to integrate with your dialing. This is up to you.
  10. Now CSipSimple should be able to register with your SIP server.

This is not enough. You also probably want to make sure your Android phone keeps on looking for WiFi when the screen is off. So you need to:

  1. Install "Advanced Wifi Lock Free" application 
  2. Run the app, click "enabled" in settings
  3. Untick "enable timeout"
  4. Untick "Auto Wifi disable"
  5. Tick "foreground service"
In addition, you might want to install "Google Voice" application itself, so that you can send/receive text messages with ease.

Testing it out

Now you should be able to make and receive calls.

  • One of the most important things is to make sure CSipSimple stays connected all the time. First, make sure your connection is not dropped. This usually happens due to NAT routers tables expiration.
    On your VPS type:
    # asterisk -r
      android/android   66.201.46.98   D   N       31965    OK (404 ms) 
      1 sip peers [Monitored: 1 online, 0 offline Unmonitored: 0 online, 0 offline]
    
  • You might want to call echo test service to test your call quality. Echo service just echos everything you say back to you.
    Add this line in your extensions.conf in [outbound] context :
    exten => 107, 1, Dial(SIP/echo@iptel.org,,r)
    Then dial "107" from your phone and check quality.

Unresolved issues

When making calls without Wifi coverage, your callerid is not your GV number

Unfortunately if you need to make a call outside of wifi coverage, you will obviously have to pay. Also, the called party will not see your google voice number, but your callid will be of your SIM card. You can somewhat mitigate that issue by hiding your caller id with your cell phone, but that is ugly. Somehow Google Voice Android application manages to make calls on "fake" numbers which google reroutes to the number you wanted and makes it show your google vocie caller id. I do not know how it works and if data connection is needed for that.

Battery usage

Now, battery usage is a problem.
This happens because of the following:
  • WiFi radio never sleeps
  • Android system itself does not sleep
  • When WiFi is lost, WiFi keeps on scanning
  • When WiFi is connected, 3G connection is still kept unnecessary. 
We do that only to be able to send UDP keepalives every 15 sec and answer asterisk's ping every 30 seconds. Perhaps we could in fact go to sleep at least for 10 seconds. This needs further investigation.

In my next post I will discuss  the following issues: 
  • Asterisk 11 and improved google voice support 
  • SILK (skype) codecs.
I hope this post was useful. I would appreciate any comments and some ideas how known problems can be workarounded. Feel free to comment if you run into issues with installation or operation.