Roll Your Own: Asterisk + Google Voice = Free Calling

In an earlier post I promised a how-to for how I used Asterisk and Google Voice to get a Home Phone, so here goes…

First of all, if you’re not much of the command-line tinkering type, and you have an internet-accessable box you can start from scratch with, you really might want to check out the Nerd Vittles solution that inspired and guided me in rolling my own.

If you’re not a tinkerer, but you don’t have a start-from-scratch box available, you can probably get away with following along through the installation of Asterisk here, and then pop FreePBX on to your Asterisk install to get a nice GUI for doing your configuration. I’ve personally never used FreePBX, so I can’t speak to how easy it would make things, etc.

If you’re still reading, we need to make sure you have a few things before we go forward.

Prerequisites

  • Root-access to an Internet-Accessable *nix box*1,2
  • A free sipgate one account
  • A free Google Voice account
  • A SIP Phone of some sort. (More on this later, but know free software phones are available for any OS you might be using)

1 – Concerning Internet-Accessability: Your best bet is a box with a public IP (i.e. no NAT). SIP and NAT don’t play well at all, so it’s best to just avoid the mess as much as possible. There are work-arounds, but nothing that’s really great.
2 – Concerning *nix flavours: This how-to is written from my experiences using Gentoo Linux. I’ve also run Asterisk on Ubuntu and Debian, and many people run it on CentOS. It can also run on Mac OS X, but will require the Developer Tools, and probably some packages not included with OS X by default.

Now that we know what we need to get going, here’s a quick overview of what we’re going to do:

  1. Install Asterisk and other tools
  2. Configure sipgate and Google Voice
  3. Configure Asterisk for Google Voice calling
  4. Verify

Let’s get started… (continue)

Posted in Computers and other Gadgety-Type Things | 1 Comment

Quick Thought on the Flash Wars

This (very slightly modified) excerpt from an open letter by one of the clashing companies’ executives, is a perfect example of how both sides are trying to use the same basis for their arguments against the other side. Unless you know already, who wrote this (and assuming you’ve been following the mess at all), I doubt you could tell me which company this came from:

The genius of the Internet is its almost infinite openness to innovation. New hardware. New software. New applications. New ideas. They all get their chance.

[We] believe open markets are in the best interest of developers, content owners, and consumers. Freedom of choice on the web has unleashed an explosion of content and transformed how we work, learn, communicate, and, ultimately, express ourselves.

If the web fragments into closed systems, if companies put content and applications behind walls, some indeed may thrive — but their success will come at the expense of the very creativity and innovation that has made the Internet a revolutionary force.

We believe that consumers should be able to freely access their favorite content and applications, regardless of what computer they have, what browser they like, or what device suits their needs. No company — no matter how big or how creative — should dictate what you can create, how you create it, or what you can experience on the web.

When markets are open, anyone with a great idea has a chance to drive innovation and find new customers.

It’s actually from the Adobe Open Letter, but can’t you see the same message coming out of Cupertino just as easily?

Myself, I lean more toward Apple, not out of any fanboyism, but because, IMO, they are only trying to exert reasonable control over their own products – rather than Adobe’s approach of wanting everyone to use their product. Regardless, this common philosophical ground should be the foundation of some sort of compromise to end the fighting.

Posted in Life in General | 1 Comment

Roll Your Own: Part 4 – Testing/Conclusion

(previous)

Testing

Now that we’ve got everything configured, all we need to do is test our setup.

  1. Dial your Google Voice number from a land-line or cell phone. This should ring your SIP phone. Try this a few times and:
    • Answer the call
    • Let the call ring through to voicemail (unavailable greeting)
    • Reject the call (busy greeting)
  2. Dial 1002 from your SIP phone. This should give you an error message.
  3. Dial 1009 from your SIP phone. This should connect you to the voicemail system. Enter 1000 for the mailbox number, and 1234 for the password. Try recording greetings and playing any messages you’d left earlier.
  4. Call a land-line or cell phone from your SIP phone.
  5. Dial 1010 from your SIP phone, this should ring the phone number you specified in extensions.conf
  6. Dial 3000 from your SIP phone, this should playback a test message.
  7. Dial 911 from your SIP phone, this should playback an error message.

Conclusion

Now that you’ve got started with Asterisk, you can customize your setup to do any number of things, all it takes is a little creativity and ingenuity.

Posted in Computers and other Gadgety-Type Things | 2 Comments

Roll Your Own: Part 3.2 – Asterisk Configuration Continued

(previous)

Now the final, most involved part of the process: Configuring the dialplan. We’ll take this bit by bit, but if you’re not sure about what a particular line does, check out the Wiki at Voip-Info.org.

Dialplan Basics
First we’ll get the basics of our dialplan configuration in place.

  1. Create /etc/asterisk/extensions.conf with your favorite text editor.
  2. Add the following block to the new extensions file
    [general]

    [globals]

    This gives us some general structure for the extensions configuration.

  3. Next, we will add a subroutine for handling calls to internal extensions. This will simplify the dialplan later on.
    [internal-call]
    exten => s,1,Verbose(====> Processing Internal Call)
    exten => s,n,Set(DIALEXT=${ARG1})
    exten => s,n,Verbose(====> Call is from ${CALLERID(all)} to ${DIALEXT})
    exten => s,n,Dial(SIP/${DIALEXT},15,tT)
    exten => s,n,GotoIf($["${SIPPEER(${DIALEXT},status)}" = ""]?badext:vmsw)
    exten => s,n(vmsw),GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
    exten => s,n(unavail),Verbose(====> Extension ${DIALEXT} is unavailable)
    exten => s,n,Voicemail(${ARG1}@default,u)
    exten => s,n,Hangup()
    exten => s,n(busy),Verbose(====> Extension ${DIALEXT} is busy)
    exten => s,n,Voicemail(${ARG1}@default,b)
    exten => s,n,Hangup()
    exten => s,n(badext),Verbose(====> Extension dialed does not go to a valid SIP channel)
    exten => s,n,Playback(pbx-invalid)
    exten => s,n,Hangup()
    exten => s,n,Return

    exten => h,1,Verbose(====> Ending Internal Call Processing - call was hung up)
    exten => h,n,Return

    This subroutine take an extension as an argument and dials it. If the extension doesn’t exist, an error message is played. If the extension is busy or unavailable, the call is transferred to Voicemail, which plays the appropriate greeting. s and h are special extensions in Asterisk. s acts as a placeholder for calls entering the context, while h defines actions that should be taken when a call in the context is hung up.

  4. Now we’ll add a subroutine to handle making the outgoing calls using Google Voice
    [gv-out]
    exten => s,1,Verbose(====> Exexution passed to Google Voice Handler)
    exten => s,n,Set(CALLING=${ARG1})
    exten => s,n,Set(GVUID=googlevoiceusername)
    exten => s,n,Set(GVPASS=googlevoicepassword)
    exten => s,n,Set(SGNUM=5555550000)
    exten => s,n,Set(PARKEXT=7100)
    exten => s,n,Playback(pls-wait-connect-call)
    exten => s,n,Set(PARKINGEXTEN=${PARKEXT})
    exten => s,n,Park()

    exten => h,1,Verbose(====> Call Parked - Initiating Google Voice Call)
    exten => h,n,System(gvoice -e ${GVUID} -p ${GVPASS} call ${CALLING} ${SGNUM})
    exten => h,n,Verbose(====> GV Call initated)

    This subroutine takes a single argument: the 11-digit number to call out to. You’ll need to change GVUID, GVPASS, and SGNUM to be your Google Voice username, Google Voice password, and sipgate phone number.

  5. Now we’ll add the [incoming] context. This is where all calls coming in from sipgate end up.
    [incoming]
    exten => 9999999e1,1,Verbose(====> Processing incoming sipgate call from ${CALLERID(num)})
    exten => 9999999e1,n,Set(GVCID=5555555555)
    exten => 9999999e1,n,Set(RINGEXT=1000)
    exten => 9999999e1,n,Set(PARKEXT=7100)
    exten => 9999999e1,n,GotoIf($[${CALLERID(num)}=${GVCID}]?gvringback:incoming)
    exten => 9999999e1,n(gvringback),Verbose(====> Call is a Google Voice Ringback)
    exten => 9999999e1,n,Answer()
    exten => 9999999e1,n,ParkedCall(${PARKEXT})
    exten => 9999999e1,n,Verbose(====> Ringback Connected)
    exten => 9999999e1,n,Return
    exten => 9999999e1,n(incoming),Verbose(====> Call is a regular incoming call)
    exten => 9999999e1,n,Gosub(internal-call,s,1(${RINGEXT}))
    exten => 9999999e1,n,Verbose(====> Execution returned to incoming)
    exten => 9999999e1,n,Return

    exten => h,1,Verbose(====> End processing incoming sipgate call - call was hung up)
    exten => h,n,Return

    You’ll need to change 9999999e1 to your sipgate SIP-ID and GVCID to your 10-digit Google Voice number

  6. Finally, we’ll add the [internal] extension, where calls from any of our phones end up.
    [internal]
    ; Internal Calls
    exten => _100[1-8],1,Verbose(====> Internal call)
    exten => _100[1-8],n,GoSub(internal-call,s,1(${EXTEN})
    exten => _100[1-8],n,Verbose(====> End internal call)

    exten => 1009,1,Verbose(====> Dialing voicemail)
    exten => 1009,n,VoiceMailMain(@default)
    exten => 1009,n,Verbose(====> End dialing voicemail)

    exten => 1010,1,Verbose(====> Speed dial 15555557777)
    exten => 1010,n,GoSub(gv-out,s,1(15555557777))
    exten => 1010,n,Verbose(====> End speed dial 15555557777)

    exten => 3000,1,Verbose(====> Play a test message)
    exten => 3000,n,Playback(tt-weasels)
    exten => 3000,n,Verbose(====> End playing test message)

    exten => 911,1,Verbose(====> 911 call)
    exten => 911,n,Playback(no-911-1)
    exten => 911,n,Hangup()
    exten => 911,n,Verbose(====> End 911 call)

    ; Outbound Calls
    exten => _1NXXNXXXXXX,1,Verbose(====> 11-digit outbound call to ${EXTEN})
    exten => _1NXXNXXXXXX,n,GoSub(gv-out,s,1(${EXTEN}))
    exten => _1NXXNXXXXXX,n,Verbose(====> End 11-digit outbound call to ${EXTEN})

    exten => _NXXNXXXXXX,1,Verbose(====> 10-digit outbound call to ${EXTEN})
    exten => _NXXNXXXXXX,n,GoSub(gv-out,s,1(1${EXTEN}))
    exten => _NXXNXXXXXX,n,Verbose(====> End 10-digit outbound call to ${EXTEN})

    exten => _NXXXXXX,1,Verbose(====> 7-digit outbound call to ${EXTEN})
    exten => _NXXXXXX,n,Set(AREACODE=555)
    exten => _NXXXXXX,n,GoSub(gv-out,s,1(1${AREACODE}${EXTEN}))
    exten => _NXXXXXX,n,Verbose(====> End 7-digit outbound call to ${EXTEN})

    This is the real meat of the dialplan. You’ll want to change AREACODE to whatever area code you want to use for 7-digit dialing, as well as the number for the speed dial on extension 1010. As you can see, combining pattern matching with naming the SIP channels to match their associated extension number reduces the number of entries required in the dialplan. It also allows us to add more phones by just configuring sip.conf and voicemail.conf, with no changes to the dialplan.

  7. Now, reload the dialplan from the Asterisk CLI
    asterisk*CLI> dialplan reload

Now that we’ve configured the dialplan, all that’s left to do is test… (continue)

Posted in Computers and other Gadgety-Type Things | 1 Comment

Roll Your Own: Part 3 – Asterisk Configuration

(previous)

With Asterisk installed and sipgate and Google Voice configured, it’s time for the meat and potatoes of this whole thing: configuring Asterisk.

safe_asterisk
Before we get into the configuration, though, we need to make a quick security change. We’ll be using safe_asterisk to start asterisk as a daemon, because it will automatically restart Asterisk in case it crashes for some reason. The safe_asterisk script, however, has a fairly serious security flaw out of the box, and we need to patch it.

  1. Open /usr/sbin/safe_asterisk in your favorite text editor and comment out the TTY=9 line.
    # vim /usr/sbin/safe_asterisk
    #!/bin/sh
    # vim:textwidth=80:tabstop=4:shiftwidth=4:smartindent:autoindent
    CLIARGS="$*" # Grab any args passed to safe_asterisk
    TTY=9 # TTY (if you want one) for Asterisk to run on
    …becomes…
    #!/bin/sh
    # vim:textwidth=80:tabstop=4:shiftwidth=4:smartindent:autoindent
    CLIARGS="$*" # Grab any args passed to safe_asterisk
    #TTY=9 # TTY (if you want one) for Asterisk to run on
  2. Start Asterisk with safe_asterisk
    # safe_asterisk

Asterisk Configuration
Now that Asterisk is running, we need to get everything configured for our calls to work. If you’re not familiar with Asterisk Configuration, you may want to check out the wiki at Voip-Info.org (search for the file you’re working on) or the Asterisk Documentation Project for some good references.

  1. Before we begin our configurations, we’ll make backup copies of the samples of the configuration files we’ll change
    # cd /etc/asterisk
    # mv extensions.conf extensions.sample
    # mv sip.conf sip.sample
    # mv voicemail.conf voicemail.sample
    # mv features.conf features.sample
  2. We also need to a little bit of planning at this point. You’ll need to decide how you want to setup your dialplan. In this example, we’re going to use four digit internal extension numbers, with the names of SIP peers set to their extension numbers. You’re free to change this to suit your needs or wants, and I’ll try and point out all the things you will need to change from these examples.

SIP Configuration
The first thing we’ll configure is our SIP settings. We’ll need to configure Asterisk to connect to sipgate, and also configure Asterisk to accept connections from a phone. In this and any other examples 9999999e1 is your sipgate SIP-ID and AAAA1A is your sipgate SIP-Password.

  1. Create the file /etc/asterisk/sip.conf in the text editor of your choice.
  2. Add this to the beginning of the new file:
    [general]
    register => 9999999e1:AAAA1A@sipgate.com/9999999e1

    The [general] section of sip.conf is where configuration options that apply to all SIP peers are set. It is also where register statements are placed. Register statements allow Asterisk to connect as a client to other SIP servers. We connect to sipgate with a register statement so that calls coming into our sipgate number come to Asterisk.
  3. Add this block below the previous one:
    [sipgate]
    type=peer
    host=sipgate.com
    outboundproxy=proxy.live.sipgate.com
    insecure=invite
    qualify=yes
    dtmfmode=rfc2833
    username=9999999e1
    defaultuser=9999999e1
    fromuser=9999999e1
    fromdomain=sipgate.com
    secret=AAAA1A
    context=incoming
    disallow=all
    allow=ulaw

    This [sipgate] section of sip.conf configures the options to use for the sipgate connection. These options are all specified by sipgate.
  4. Add this last block below the [sipgate] section:
    [1000]
    type=friend
    host=dynamic
    nat=yes
    qualify=yes
    context=internal
    defaultuser=1000
    secret=1000
    callerid="Your Name" <1000>
    mailbox=1000

    This section defines the configuration for our SIP phone to connect to Asterisk at extension 1000.
  5. Save the file as /etc/asterisk/sip.conf . Now, connect to the running Asterisk daemon to get to the Asterisk CLI
    # asterisk -rvvv
  6. At the Asterisk command prompt, reload the SIP configuration. Most configuration changes in Asterisk don’t require restarting Asterisk, but simply reloading the configuration files that have been changed.
    asterisk*CLI> sip reload
    Reloading SIP
    == Parsing '/etc/asterisk/sip.conf': == Found
    == Parsing '/etc/asterisk/sip_notify.conf': == Found
    asterisk*CLI>
  7. Now we’ll setup our SIP phone to connect to Asterisk. Use 1000 in place of your sipgate SIP-ID and SIP-Password, and the hostname or IP of your server in place of sipgate.com in the phone’s configuration.
  8. Let’s make sure our SIP configuration is working properly.
    asterisk*CLI> sip show registry
    Host dnsmgr Username Refresh State Reg.Time
    sipgate.com:5060 N 1207176e0 105 Registered Tue, 20 Apr 2010 19:16:08
    1 SIP registrations.
    asterisk*CLI> sip show peers
    Name/username Host Dyn Nat ACL Port Status
    1000/1000 10.13.10.85 D N 5060 OK (50 ms)
    sipgate-kenny/9999999e1 172.16.17.10 5060 OK (45 ms)
    2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]
    asterisk*CLI>

    If you don’t have 1 registration and 2 peers showing up, there’s something amiss, and you’ll need to look into it.

Next we’ll configure voicemail.conf and features.conf… (continue)

Posted in Computers and other Gadgety-Type Things | Leave a comment