Asterisk PBX, Google Voice and an Old Buffalo TeraStation NAS

Compiling Asterisk came to be a little bit of a bother. The main issue is that you’re dealing with a fairly old NAS so some of the shared libraries may not be compatible.
 

I had an old Buffalo TeraStation (Model #HD-H0.6TGL/R5) laying around that I was trying to figure out what to do with. I had recently replaced it with a 4TB NAS so its use as a storage device wasn’t really needed. After a little bit of thought, I decided that I would use it as a backup device, but I really wanted it to be something…more. I then remembered having a conversation with a co-worker regarding software PBXs, specifically Asterisk, and integrating it with Google Voice. The big bonus here was the fact that, as of this writing, Google Voice still allows free calls to Canada, which helps us tremendously since we have family there. So, another adventure begins :-).

Rooting the TeraStation

This, of course, was the first thing I needed to do. This was probably the easiest part as all I needed to go to was to Dave Walker’s website and download his TeraStation firmware + telnet + root access package. This package has a Windows-based firmware updater that will search for your TeraStation on the network and upload the rooted firmware. The updater put my TeraStation in “EM” mode (emergency mode) and then uploaded the firmware. Once the process completed, I was able to telnet into my NAS using my admin password.

Next step was to install some utility programs and libraries (such as gzip, grep, man, etc.), that Dave also provided via his OpenTera v5 and OpenTeraDev v3 packages.

# wget http://downloads.nas-central.org/Users/itimpi/OpenTera_v5.zip
# unzip OpenTera_v5.zip
# chmod +x *.*
# ./Update_OpenTera.sh

Next is the OpenTeraDev v3 package, which installs development tools needed to compile programs such as gcc.

# wget http://downloads.nas-central.org/Users/itimpi/OpenTeraDev_v3.zip
# unzip OpenTeraDev_v3.zip
# chmod +x *.*
# ./Update_OpenTeraDev.sh

Compiling Pre-Requisites

NOTE: As you configure/make/make install, eventually you will run out off space if your default installation is set to /usr/local. The workaround is to always specify the prefix whenever you configure:

./configure --prefix=/mnt/array1/usr/local

With the OpenTeraDev v3 package on hand, I could now compile the Asterisk 1.8 source. Before I could do that, however, there were a couple of requirements, one of which was libxml2. What I found was I could not compile libxml2 v2.8 since it required gcc v3.4. I didn’t want to have to go through the steps of recompiling the compiler so I settled for libxml2 v2.7, which compiled just fine in gcc v3.3.

# wget ftp://xmlsoft.org/libxml2/old/libxml2-2.7.1.tar.gz
# tar zxvf libxml2-2.7.1.tar.gz
# cd libxml2-2.7.1
# ./configure --prefix=/mnt/array1/usr/local
...
# make
...
# make install
...
# cd /usr/local/lib
# ln -s /mnt/array1/usr/local/lib/libxml2.so.2.7.1 libxml2.so
# ln -s /mnt/array1/usr/local/lib/libxml2.so.2.7.1 libxml2.so.2
# ldconfig -v

Note that ldconfig updates your shared libraries so that when you compile Asterisk, it will be able to find them. One other problem I encountered was that in order to run Google Voice with Asterisk, you’ll need to compile and install the iksemel library.

# wget http://iksemel.googlecode.com/files/iksemel-1.4.tar.gz
# tar zxvf iksemel-1.4.tar.gz
# cd iksemel-1.4
# ./configure --prefix=/mnt/array1/usr/local
...
# make
...
# make install
...
# cd /usr/local/lib
# ln -s /mnt/array1/usr/local/lib/libiksemel.so.3.1.1 libiksemel.so
# ln -s /mnt/array1/usr/local/lib/libiksemel.so.3.1.1 libiksemel.so.3
# ldconfig -v

Compiling Asterisk 1.8

First, download the source:

# wget http://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-1.8.19.1.tar.gz
# tar zxvf asterisk-1.8.20.0

NOTE: If you’re following along, you may need to go to http://downloads.asterisk.org/pub/telephony/asterisk/ to see what current version is out there and try that out.

Compiling Asterisk came to be a little bit of a bother. The main issue is that you’re dealing with a fairly old NAS so some of the shared libraries may not be compatible. There was one thing that caused an issue when running Asterisk (this was after compiling), and it involved a shared library function call to getaddrinfo() in the netsock2.c file. The issue occurred when attempting to bind port 5060; getaddrinfo() attempted to get the IP address of the NAS box but failed with an error during the boot up sequence as evidenced by the startup log. A netstat -an verified the issue; the service would not bind to port 5060 no matter what configuration I tried. Turned out the issue in the netsock2.c file was that it was setting the hints.ai_flag to use the AI_NUMERICSERV flag. However, even though AI_NUMERICSERV was set, it wasn’t recognized by the getaddrinfo() function. The fix is to simply define AI_NUMERICSERV to 0 (edit main/netsock2.c):

  1. Look for the following at line 216:
    #ifdef AI_NUMERICSERV
  2. Insert before the above line:
    #undef AI_NUMERICSERV
    #define AI_NUMERICSERV 0

Then, re-compile and install:

# cd asterisk-1.8.20.0
# ./configure --prefix=/mnt/array1/usr/local --disable-xmldoc
...
# make
...
# make install
...

The --disable-xmldoc was necessary because I didn’t install the libxml2 development libraries, which include the libxml2 documentation. Next, remember to make the sample configs!

# make samples

These sample configuration files will be located in the <prefix>/etc/asterisk folder.

Configuring Asterisk 1.8

For configuring Asterisk, I simply followed this guide (thanks Jayson!). For convenience, the following are my configuration files:

jabber.conf:

[general]
debug=yes
autoprune=no
autoregister=yes

[gmail]
type=client
serverhost=talk.google.com
username=<gmail_username>@gmail.com/Talk
secret=<gmail_password>
port=5222
statusmessage="Asterisk Server"
timeout=100

gtalk.conf:

[general]
context=users
allowguests=yes
bindaddr=0.0.0.0

[guest]
disallow=all
allow=ulaw
context=users
connection=gmail

sip.conf:

[rons-iphone]
type=friend
host=dynamic
secret=<some_password>
context=users
deny=0.0.0.0/0
permit=10.7.0.0/255.255.255.0

features.conf

[general]
parkext=>700
parkpos=>701-720
context=>parkedcalls
parkingtime=>180
comebacktoorigin=yes
parkedmusicclass=default

voicemail.conf

[vm]
601=><numeric_pin>,Ron,ronaldcs@dforge.net,attach=no|tz=eastern|maxmsg=10

extensions.conf

[docs:users]
[users]
include=>longdistance2
include=>parkedcalls

exten=>s,1,Answer()
exten=>s,n,Set(CALLERID(number)=${CALLERID(name):2:10})                         
exten=>s,n,Set(CALLERID(name)=${CALLERID(number)})                              
exten=>s,n,Wait(2)
exten=>s,n,SendDTMF(1)
exten=>s,n,Dial(SIP/,20)
exten=>s,n,VoiceMail(601@vm,u)

exten=>601,1,Dial(SIP/rons-iphone,20)
exten=>601,n,VoiceMail(601@vm,u)

exten=>650,1,Answer(500)
exten=>650,n,VoiceMailMain(@vm)

[longdistance2]
exten=>_NXXNXXXXXX,1,Dial(Gtalk/gmail/+1${EXTEN}@voice.google.com)             
exten=>_1NXXNXXXXXX,1,Dial(Gtalk/gmail/+${EXTEN}@voice.google.com)             

Note that my extensions.conf file is slightly different than Jayson’s. First off, I parse out the caller ID near the beginning of the file. Secondly, I didn’t want to have to dial 9 in order to make an outside call. So I added a couple of masks to take care of local and long distance calls without having to dial 9.

Here are a few things I still want to do, which I may blog about at a later time:

  • Voicemail to e-mail
  • Add an additional outgoing line via Google Voice
  • Wake-up call
  • Video Conferencing