Analog remix part 1: a VoIP manual service exchange

Recently, I decided to revisit the analog side of my home Asterisk VoIP system, specifically, the Northern Electric 302 that I keep hooked up and on display. It’s a conversation piece, for when folks spot the rotary-dial phone, they ask, “Does that thing work?” At that point I explain that I can answer calls on it, but because of the rotary dial (and because I haven’t fashioned or purchased a rotary-to-DTMF converter) I can’t place a call from it.

Until now. With a little tweaking of the analog adapter, a fresh rediscovery of VoiceXML through the Tropo application platform, and some straightforward CGI programming, I have a robotic operator ready to connect me to whatever number I tell her. No dialing necessary!
Speech recognition is not new technology, but I think that using it here is a clever way to get around the limitations of my old technology (the rotary dial) by using the computerized equivalent of even-older “technology” (the human operator). So this discussion on implementing a manual service exchange in VoIP is dedicated to Almon Strowger, inventor of the automatic telephone switch.
There are three components to this:
  • configuring the analog adapter as an automatic ringdown (hot-line) or warm-line
  • programming the speech-to-text “operator” service on Tropo
  • programming the call-back CGI on a web server that can connect to the Asterisk Manager and perform call-handling functions
listed in order of difficulty.
Part 1: the automatic ringdown
Most VoIP-analog adapters (and probably most IP phones for that matter) have the ability to act as a hot-line, which rings a set destination when the phone goes off-hook, or a warm-line, which does the same after a timeout period (for example, six seconds without any digits entered). If you’ve got your vintage analog gear on a dedicated ATA, go for the hot-line, because you’ll never actually be “dialing” anything. As for me, I’ve got my 302 bridged with a Panasonic cordless system, so I need to maintain the ability to dial. But after six seconds of no dialing, the ATA assumes I want the operator and connects the call appropriately.
The hot-line/warm-line is configured in the endpoint’s dial plan. Refer to your device’s manual. The common Cisco/Linksys/Sipura SPA adapters all seem to have the same dial plan syntax, documented here. Here are the key items from that document:

The following implements a Hot Line phone, which automatically calls 1 212 5551234.

The following provides a Warm Line to a local office operator (1000) after five seconds, unless a four-digit extension is dialed by the user.

In my case, my “operator” extension is going to be 1100, so part of my dial plan will contain | P6 <:1100> |, which tells the ATA to automatically connect the call to extension 1100 after six seconds of no input.
Now that the need to dial has been eliminated, we’ll need something useful at extension 1100, which will be the Tropo-powered speech synthesis and recognition system, discussed in a future post.

PSU VoIPad

Today, I received a late door prize from my visit to Interop New York last month. A box arrived containing a congratulatory letter and an Apple iPad! Thanks, Network Hardware Resale, the “world’s largest provider of used Cisco equipment.”

Can the iPad be a useful VoIP client? I have not been following development of the iPad at all, and last I remember it had no multitasking capabilities (coming soon?) so it seems clumsy as an IP phone. And large. If anyone uses a SIP client on the iPad, leave a comment and let me know what to get from the iTunes store.

UPDATE: The iPad won’t be geeked-out with SIP clients until my wife gets first pass at it, to see if it can mostly replace her 2004-vintage laptop. I have pretty high hopes for it in that.

Adding Google Voice to FreePBX

If you’ve moved ahead to Asterisk 1.8 in production or are testing it out, use FreePBX as your configuration GUI, and want to add Google Voice such that inbound and outbound routing can easily be configured from FreePBX, here’s a small how-to. Unless and until a GTalk FreePBX module comes along, there’s some command-line work to do, but only for initial configuration.

References:

How To Add Google Voice To FreePBX

Part 1: In the shell

  1. Refer to the Asterisk Wiki: Calling Using Google. We’ll be following that as our guide.
  2. From the command line, as user root or asterisk, verify that the res_jabber and chan_gtalk modules are loaded.
    • [root@asterisk18 ~]# asterisk -rx "module show" | grep res_jabber
      res_jabber.so                  AJI - Asterisk Jabber Interface          0
      [root@asterisk18 ~]# asterisk -rx "module show" | grep chan_gtalk
      chan_gtalk.so                  Gtalk Channel Driver                     0
    • If one or both of those grep commands returns nothing, you need to build the modules (don’t forget to have OpenSSL development libraries installed) and make sure they are loading at Asterisk startup (autoload=yes OR load => res_jabber.so and load=> chan_gtalk.so in /etc/asterisk/modules.conf).
  3. There are three config files in /etc/asterisk to edit by hand (use vi, nano, emacs or whatever you like): jabber.conf, gtalk.conf, and extensions_custom.conf.
    • jabber.conf

      Edit or replace jabber.conf to follow what is listed in Calling Using Google, and which I am pasting almost verbatim here. (I removed debug=yes.) This establishes the XMPP connection.

      [general]
      autoprune=no
      autoregister=yes

      [asterisk]
      type=client
      serverhost=talk.google.com
      username=your_google_username@gmail.com/asterisk
      secret=your_google_password
      port=5222
      priority=1
      usetls=yes
      usesasl=yes
      statusmessage="I am an Asterisk Server"
      timeout=100

    • gtalk.conf

      Again referring to the Asterisk wiki, edit gtalk.conf thus:

      [general]
      context=from-google
      allowguest=yes
      bindaddr=0.0.0.0
      ;externip=1.2.3.4 ; if you know your external ip addr
      stunaddr=stun01.sipphone.com ; use STUN if you're on dynamic IP and NAT

      [guest]
      disallow=all
      allow=ulaw
      context=from-google
      connection=asterisk

      Some notes about gtalk.conf:

      • Use context from-google, which we will set up in the extensions_custom.conf.
      • connection=asterisk must match the connection definition (in square brackets) in jabber.conf.
      • Use externip or stunaddr to get your external IP address if you’re behind a NAT.
    • extensions_custom.conf

      Make a section like this:

      [from-google]
      exten => s,1,Answer()
      exten => s,n,Wait(2)
      exten => s,n,SendDTMF(1)
      exten => s,n,Set(CALLERID(num)=${CUT(CALLERID(name),@,1)})
      exten => s,n,Set(CALLERID(name)=${CUT(CALLERID(name),/,1)})
      exten => s,n,Goto(from-trunk,YOUR-GV-NUMBER,1)
      exten => s,h,Hangup

      • Replace YOUR-GV-NUMBER with your Google Voice DID.
      • The Set commands fix up the caller ID to get rid of the long XMPP ID that is passed on an inbound call.
  4. Once these files are in place, restart Asterisk (amportal restart).
  5. Issue the following command to see that the XMPP connection to Google Talk has been established:

    # asterisk -rx "jabber show connections"
    Jabber Users and their status:
           User: ...@gmail.com/asterisk     - Connected
    ----
       Number of users: 1

  6. Now you’re ready to set up a Google Voice trunk and inbound and outbound routes in FreePBX.

Part 2: FreePBX

  1. Add a new Custom Trunk.
    • Trunk name: Google Voice
    • Outbound Caller ID: put your Google Voice DID, even though this will be ignored (GV always uses your GV number for the outbound Caller ID)
    • Dialed Number Manipulation Rules: Google Voice requires that the number be a full 11 digits, starting with 1. Either here or in your outbound route (or both), make sure you are sending a full 11-digit number. See the screenshot for my config.
    • Custom Dial String: This is the most important part. Enter gtalk/asterisk/+$OUTNUM$@voice.google.com where asterisk matches the client definition in your jabber.conf (in square brackets). If you’ve followed this how-to exactly, then this line is correct.
    • Submit changes.
    • Screenshot (click for full version):
      gvtrunk-small.png
  2. Add a new Outbound Route.
    • You can send any US domestic calls through Google Voice. Just configure an appropriate outbound route and select Google Voice as the trunk. In this screenshot, I have configured 11-, 10-, and 7-digit dialing within my own area code.
    • Screenshot (click for full version):
      outroute-small.png
  3. Add a new Inbound Route.
    • Refer back to this line you entered in extensions_custom.conf: exten => s,n,Goto(from-trunk,YOUR-GV-NUMBER,1) Whatever you entered for YOUR-GV-NUMBER will be the DID you use for your inbound route.
    • Description: Google Voice (or whatever you want)
    • DID Number: YOUR-GV-NUMBER
    • Other stuff: defaults
    • Destination: wherever you want the incoming call to go. In my screenshot, it is directly dialing an extension.
    • Screenshot (click for full version):
      inroute-small.png
  4. Submit all changes and apply configuration. Done! You have added a Google Voice two-way trunk to FreePBX and can use it in your inbound and outbound routing. Don’t forget to log in to Google Voice and select Google Chat (…@gmail.com) as the phone to which your incoming calls are forwarded!

Asterisk 1.8 on the Rackspace Cloud

In this post I’ll share the few notes I have on installing Asterisk 1.8 on a Rackspace CloudServer. First, note that I am not promoting this specific cloud provider. (There are several others, such as Amazon EC2 and Linode.) But I am all about VoIP on the cheap, and the baseline RS CloudServer seems to be as inexpensive as you can get. Moreover, I started using RS CloudServers a little while ago just for some quick Linux testing, and liked them. So when I thought about testing Asterisk 1.8, I set up a new instance there.

I’m not a software engineer and can’t effectively analyze Asterisk’s code to say whether it should or should not perform well in a cloud environment, but testing in this environment shows that it works fine, with one caveat: you can’t use the DAHDI kernel module. On other providers where the kernel headers and sources are available, you can compile DAHDI, but RS Cloud does not provide their Xen-optimized kernel source. The good news is that with Asterisk 1.8 (actually, starting in 1.6.2), you don’t need DAHDI unless you have directly-attached telephony hardware, which you don’t, because your server is in the cloud.

To further explain that: previously, you’d need a DAHDI hardware module or the DAHDI dummy driver to provide the timer for the IAX2 protocol and MeetMe. IAX2 no longer needs it, and while MeetMe does still need at least the dummy timer, there’s a new conference bridge application available that doesn’t need it–app_confbridge. (And if you don’t care about having a conference bridge anyway, this whole matter is moot.)

After all that introduction, I’m glad to say that actually building Asterisk and FreePBX on the cloud server is straightforward and only requires a few adjustments from building on physical hardware. I’m going on the assumption that you have built Asterisk and FreePBX before on a physical server. Here are the extra steps I had to take to build on RS Cloud.

Asterisk

  • Create an instance of CentOS 5.5 on the 256 MB RAM/10 GB storage server. For test, this is enough. If you end up running a lot of calls through it, you’ll need a bigger VM. But the 256 MB server is a bargain at 1.5 cents per hour and 22 cents per gigabyte download and 8 cents per gigabyte upload. (Can you even get old hardware, electricity and bandwidth for testing for this price?)
  • yum update and add build tools to the environment (yum install gcc make gcc-c++ ncurses-devel libtool subversion). This is also a good time to add the packages that FreePBX needs. (My list included mysql-server mysql-devel libxml2-devel libtiff-devel php-pear php-pear-DB php-gd php-mysql php-pdo perl-DateManip mod_ssl)
  • useradd -c "Asterisk PBX" -d /var/lib/asterisk asterisk; mkdir /var/run/asterisk; mkdir /var/log/asterisk
  • Get asterisk-1.8.x.tar.gz and expand. There is no more asterisk-addons package; it’s now part of the asterisk tar file.
  • For Google Talk/XMPP/Google Voice:
    • yum install openssl-devel
    • svn co http://iksemel.googlecode.com/svn/trunk/ iksemel-read-only
    • Build iksemel with ./autogen.sh; ./configure; make; make install
    • Iksemel puts its libraries in /usr/local/lib, so add this location to your library path: echo /usr/local/lib > /etc/ld.so.conf.d/local.conf; ldconfig
  • Build: cd to the asterisk-1.8 directory, then ./configure; make menuselect
  • Review the modules being built. app_meetme won’t be available because DAHDI isn’t built. Add app_confbridge instead. Make sure res_jabber and chan_gtalk are selected if you want to set up Google Talk/Voice. Review the other modules including the ones listed in Add-ons (formerly a separate tar file) especially if you are adding FreePBX–you’ll want cdr_mysql.
  • Keep building: make; make install; make samples
  • Important for the RS Cloud environment: there is no TTY9, which safe_asterisk puts the Asterisk console on. Edit /usr/sbin/safe_asterisk and comment out line 5 (TTY=9) and set CONSOLE=no on line 6. Everything else should be fine.
  • Asterisk should be ready to go!

FreePBX

  • When I installed FreePBX 2.8.0, it complained that Asterisk 1.8 was not supported. The repository has an updated installer (see http://www.freepbx.org/v2/changeset/10494) but if you’re going from the 2.8.0 (or earlier?) tarball, you’ll have to make the change highlighted here. Edit line 899 in install_amp and change 1.7 to 1.9.
  • Now install FreePBX according to your own documentation or that available on FreePBX.org

Startup

  • Add /usr/local/sbin/amportal start to the end of /etc/rc.d/rc.local, or make an init script for /etc/init.d. I’m lazy and chose the former.
  • Start everything up with amportal start.

More to do

Get familiar with iptables, if you’re not already. This is the way to control access on your RS CloudServer node. By default it permits SSH, so you’ll want to add lines to permit web, SIP, IAX2, and so on.

Since you’re running in 256 MB RAM, you might want to pare down the /etc/httpd/conf/httpd.conf and reduce the number of web servers spawned, to save a little memory. The RS CloudServer is already pretty thin, otherwise.

Testing

I did some additional configuration of FreePBX, not essential to this posting, and then configured a softphone extension and a Google Voice trunk (to be discussed in a later posting). Then I made some calls. Even with both legs of the call going over the Internet, from a shared hosting facility, using G.711 uLaw (PCMU), the sound was great.

Later

More on the Google Voice setup and FreePBX, and considerations for having your PBX out on the Internet. This would be a good time to start thinking about secure RTP!

Asterisk 1.8, FreePBX 2.8, and Google Voice on a Cloudy Day

This past weekend, I had a chance to test out all of the named technologies, all together–including the cloud.

The news last week was that Asterisk 1.8 connects directly to Google Voice via the Google Talk protocol. No more scripts or free DIDs to act as intermediary. And if you’ve set up GTalk with Asterisk on previous versions, it’s simple to go the extra couple steps and enable Google Voice.

Tested, and it works. Thanks to Michigan Telephone who drew my attention to the Asterisk wiki where the Google Voice setup is documented. If you’re already in a place where you can install Asterisk 1.8 and want to try it out, that wiki document will take you the whole way through it. (One note, however: I have allowguest=yes, which is how this option is documented in the sample gtalk.conf, rather than allowguests=yes, which is how it is documented in the wiki, and allowguest [no s] works for me.)

While I am a huge fan of Google Voice, what was more interesting than getting that working this weekend was getting it running in the cloud–namely, Rackspace CloudServers. This was my venture into cloud VoIP, starting with dev/test, and partially out of necessity–I don’t have any more hardware at home to use for testing. I’ll give the end of the story first: it works nearly as well as my physical hardware setup at home in terms of audio quality and general calling functions, and an order of magnitude better for rapid deployment of a testing environment in which to set up the new versions of Asterisk and FreePBX. Naturally, I began to think: could I move my home PBX to the cloud? Not yet, and I have a number of technical reasons (not FUD) why, but I plan to try tackling them.

This is an introduction, and I know a number of folks stop by this blog looking for technical how-tos, so this week and next I will be digging into these topics: setting up Asterisk 1.8 and FreePBX 2.8, configuring Google Voice and nicely integrating into FreePBX (not just hacking it into the extensions_custom.conf by hand some config file editing required…), setting up a RS CloudServer for Asterisk, and some of the technical considerations I mentioned in the previous paragraph.

That’s a lot to write about, and I’ll get to it piece by piece. Meanwhile, if you want to just try it out (minus the cloud part), go get the latest Incredible PBX/PBX In A Flash from NerdVittles, install the ISO and have at it. They’ve gotten it working and bundled it together so that you can have a cutting-edge PBX… in a flash! But as for me and this blog, let’s just call it Asterisk PBX in a slow-cooker.