Archive for January, 2009

Inauguration Day

Tuesday, January 20th, 2009

Today was a big day of change. I only caught the last part of President Obama's inauguration speech, so I'm hoping the full thing will be on the new Whitehouse.gov Blog soon.  I really like the changes that are visable on the site.  There are some things that are not seen though.  According to Jason Kottke, the new robots.txt file is a mere two lines.  The old robots.txt was over 2,400 lines long.  What this means is that the old Bush whitehouse.gov was telling Google and all the other search engines not to index their site.  The new whitehouse.gov is allowing everything to be indexed, which means it will show up in Google and archived on web.archive.org.  It's nice to see transparency at this level.

Not only was there change at the federal level, but Jack Markell was sworn in as Delaware's new Governor.  Delawareans might notice there are major changes on delaware.gov as well.

I'm happy to see these positive changes at both the state and federal levels.  I have a lot of faith that things will change for the better, but my expectations have risen as well.  These leaders have campaigned on better government and I expect better leadership than Bush and Minner.

On a somewhat not so related note, I got my electric bill today.  They included the energy sources used for the 2007 calendar year.  I'm including it below as it might be interesting to see what that mix looks like in a year or two.

Source Percentage
Coal 55.9%
Gas 7.3%
Nuclear 34.2%
Oil 0.5%
Captured Methane Gas 0.2%
Geothermal 0.0%
Hydroelectric 0.9%
Solar 0.0%
Solid Waste 0.6%
Wind 0.2%
Wood or other Biomass 0.2%
Conventional Energy Subtotal 97.9%
Renewable Energy Subtotal 2.1%

I hope to see large improvements in our energy policies. Such as use of more renewable energies like wind and higher efficiency solar panels that can sell back to the grid to lessen the load on those hot summer months. I think using oil from the middle east in our cars is a larger problem at the moment, but it's all related.

[EDIT 20-Jan-2009: I know it seems strange I'm talking about energy sources from 2007.  Maybe they are that slow??  See for yourself, here is a link to the insert that was included with my bill. ]

[EDIT 21-Jan-2009: The Inauguration is now on Youtube.  I also saw an interesting article on ARS Technica regarding the electrical grid and energy storage.]

Configuring Linksys SPA 3102 for Asterisk

Thursday, January 1st, 2009

As I mentioned in my previous post, I've been working on installing Asterisk.  I purchased a Linksys SPA 3102 ATA device.  It has FXO and FXS ports as well as two ethernet ports to go between your Internet connection and router.  The FXO port accepts a dial tone from the phone company and the FXS port generates one for your phones.  Since I have DSL and the phone line that comes along with it, I wanted to make use of that for local and emergency calls.

Because this device has so many configuration options, I wanted to document what I did in case I need to refer back to it in the future.  At some point, I'd like to look into creating an XML file to provision the device.  But I'm not ready for that yet.  Most of what I did was based on this forum post, but I didn't follow it exactly.

I've installed Asterisk on my Linode, which is on a static ip out on the Internet, and I've installed the SPA-3102 behind my home router, which is a WRT54G running the Tomato firmware behind a dynamic ip.  Since I have DSL, I have a combination DSL modem and router in one.  It's pretty limited in what it can do and I was afraid of it interfering with the VOIP traffic.  What other people recommended (online somewhere) was to put the DSL modem into bridge mode and configure my WRT54G to establish the PPPoE connection.  A useful tip from one of the forums was to clone the MAC address of the DSL modem to the WRT54G WAN port, otherwise you might end up in a situation where you need to call tech support.

With the home network reconfigured, it was time to get started with the SPA-3102.  My first order of business was to flash the device with updated firmware and reset it to factory defaults.  When I downloaded the flash, I was let down to see that you needed to run some flash program under Windows.  I later found out you can put the firmware image on a web server and use an "Upgrade URL" to flash the device (get the Admin Guide and search for "upgrade url" for more information).  For me, the flash and reset procedure went something like this..

  1. Turn off wireless on your laptop.
  2. Connect your laptop to LAN port of SPA-3102.
  3. Connect the WAN port of the SPA-3102 to your local network.
  4. Browse to http://192.168.0.1/ from your laptop (make sure you click admin and advanced to see all of the configuration options).
  5. Note the WAN IP address the SPA-3102 was given.
  6. Enable the WAN web server (under Router->Wan Setup).
  7. Went to my desktop computer and fired up the Windows virtual machine.
  8. Under Windows, I opened the remote web management to verify I could connect to the WAN IP of the SPA-3102.
  9. Ran the firmware updater and followed the prompts.
  10. After the firmware update is complete, verify the version by browsing to the web management interface.
  11. Connect a phone to the phone port of the SPA-3102 (you should hear a dial tone).
  12. Dial **** to access the IVR.
  13. Dial 73738# to perform full factory reset.
  14. Dial 1 to confirm the action.

Now that the upgrade and reset procedure is complete, I returned to the laptop to enable the WAN web server again.  I then put my laptop away and finished configuring the device from my desktop computer.

As you should have noticed by now, the web management of the device is broken down by router options and voice options.  I configured the router options first.  This is a little misleading as I'm not using the device as a router, but that is where some of the basic networking options are kept.  Before configuring the basic stuff, I went to my WRT54G and gave the device a static DHCP IP address.  This way the device would be on a static IP address, but I wouldn't need to configure that in the device itself.  After that was done, I proceeded with the following basic networking configuration options..

  1. Browsed to Router -> WAN Setup tab.
  2. Set the HostName to "spa-3102" and Domain to "local".
  3. Set Primary NTP Server to "0.pool.ntp.org" and Secondary NTP Server to "1.pool.ntp.org".
  4. Enable WAN Web Server was set to "yes" earlier.
  5. Browsed to Router -> LAN Setup tab.
  6. Set Networking Service to "Bridge".
  7. Set Enable DHCP Server to "no".
  8. Click "Submit All Changes" button.

After the device resets, you can verify the settings on the Router -> Status page.  With the basic stuff out of the way, you can move onto the voice options.  These are a little more complicated and you will probably end up tweaking things as you configure Asterisk.

  1. Browse to Voice -> System.
  2. Set the admin password and user password.
  3. Click the "Submit All Changes" button and the device will reset.  Once it does, log in to the device.
  4. Browse to Voice -> Regional.
  5. Vertical Service Activation Codes.  Note: I read a forum post that said to clear all of these out so Asterisk would handle them if entered.  I have not done that yet.
  6. Under Miscellaneous, set the Time Zone.  Note: I still need to figure out the Daylight Savings Time Rule syntax, but I have a couple months for that.  The time zone parameter affects the time that is displayed on your phones if you have phones that do that.
  7. Browse to Voice -> Line 1.
  8. NAT Settings.  Note: I did not need to enable the NAT settings.  If you do, you will need to enable all of the NAT and STUN server settings under the SIP tab as well.  See the Admin Guide for more information.
  9. Set Proxy to your Asterisk server hostname.
  10. Set Register to "yes".  This is the default.  Note: The registration settings initiate contact to the Asterisk server and will keep the connection alive along with some Asterisk settings in the sip.conf file.
  11. Set Make Call Without Reg to "no".  This is the default.
  12. Set Ans Call Without Reg to "no".  This is the default.
  13. Set Display Name to "Line1".
  14. Set User Id to "line1".
  15. Set Password to something secret.
  16. Dial Plan.  Note: I did not modify this, but I may tweak it at some point.
  17. Browse to Voice -> PSTN Line.
  18. Set Proxy to your Asterisk server hostname.
  19. Make sure registration is enabled and required for making and answering calls.
  20. Set Display Name to "PSTN".
  21. Set User Id to "pstn".
  22. Set Password to something secret.
  23. Set Dial Plan 1 to "(xx.)".
  24. Set Dial Plan 8 to "S0<:123@asterisk.domain.com>" where asterisk.domain.com is your Asterisk server.  Note: I believe this hostname needs to match your proxy hostname for authentication purposes.
  25. Set VoIP-To-PSTN Gateway Enable to "yes".
  26. Set Line 1 VoIP Caller DP to "1".
  27. Set VoIP Caller Default DP to "1".
  28. Set PSTN-To-VoIP Gateway Enable to "yes".
  29. Set PSTN Ring Thru Line 1 to "no".
  30. Set PSTN CID For VoIP CID to "yes".
  31. Set PSTN Caller Default DP to "8".
  32. Set PSTN Answer Delay to "5".  Note: This is to allow enough time for caller id.
  33. Click "Submit All Changes" button.

Now your Linksys SPA 3102 should be configured.  The next part involves configuring Asterisk. The installation and global configuration of Asterisk is outside the scope of this blog post. Below are sections of configuration files you need to modify for the SPA-3102.

First, the sip.conf file will handle the connections from the device to the Asterisk server. You should have a global section and most likely have other devices.

; Line1 on SPA3102
;
[line1]
type=friend
host=dynamic
context=internal
username=line1
secret=secretpassword
nat=yes
canreinvite=no
dtmfmode=rfc2833
qualify=yes
disallow=all
allow=ulaw

; PSTN on SPA3102
;
[pstn]
type=friend
host=dynamic
context=pstn
username=pstn
secret=secretpassword
nat=yes
canreinvite=no
dtmfmode=rfc2833
qualify=yes
insecure=port,invite
disallow=all
allow=ulaw

Then the extensions.conf file will tell how to route the calls. The "context=internal" for the line1 device above will route those calls to "[internal]". For me that also handles all of my devices. The "context=pstn" for the pstn device will route those calls to the section shown below. Since I put 123@asterisk.domain.com in for dial plan 8 above, we have to describe how to handle those incoming calls below.

[pstn]
exten => 123,1,NoOP(${CALLERID}) ; show the caller ID info in the console
exten => 123,n,Ringing()
exten => 123,n,Answer()
exten => 123,n,Playback(silence/1)
exten => 123,n,Playback(pls-wait-connect-call)
exten => 123,n,Wait(3)
exten => 123,n,Dial(SIP/line1,60)
exten => 123,n,Congestion

Right now all of this is pretty basic just to get things running. I'll probably end up doing more with the extensions.conf file and I plan on signing up with a sip provider to make outgoing long distance calls. The short-term plans are to keep using the local line for incoming calls, but I could port that number somewhere if needed. Also, I need to say thanks to Ryan Tucker for answering all my Asterisk questions along the way!

Compiling Dahdi Modules on Linode

Thursday, January 1st, 2009

Happy New Years everyone! This holiday I decided to work on setting up Asterisk, which is an open source pbx system. I had some issues where I wasn't getting any audio and it became apparent that I needed to compile the dahdi_dummy kernel module for a timing source. Since my VPS account is hosted at Linode, where they run Xen, I'm able to build my own kernel modules and my own kernel images if I wanted.

I was using the 2.6.18.8 kernel and everything built fairly easily under that, but modprobe had a segmentation fault when I loaded the dahdi_dummy module. Linode recently made the 2.6.28 kernel available, so I decided to give that a try instead.  I prefer to use the kernels that Linode provides for the stability and support.  Linode makes the kernel source available from which the kernels are built.  I did run into a few glitches though.  The first was that the dahdi modules were looking for bounds.h, which did exist.  It seems that "make clean" removes some of the generated header files.  Running "make prepare" solves that quickly (thanks caker).  I then found that the scripts/genksyms/genksyms binary was compiled for 64bit Linux.  Since I'm using a 32bit distribution, that didn't work out so well.  That part of the kernel tree needs to get cleaned and rebuilt in order to compile the dahdi modules.  After messing around awhile, I ended up rebuilding the entire kernel just to get a few small files.  I decided it's be best to write a small script to only clean the sections I need and make this easier next time around.

The script I used is below.

#!/bin/bash
#
# Script to clean genksyms in the kernel source and prepare the source to be
# used when compiling modules for things like asterisk.  This was needed to
# remove binaries in the scripts tree because the Linode kernels are built on
# a 64bit server and my Linode is using a 32bit distribution.
#
# Copyright (c) 2009 Patrick Hennessy
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#

# Set this to where your kernel source is placed.  I usually have a symlink
# for both of the locations below.
#
# KSOURCE=/lib/modules/$(uname -r)/build
#
KSOURCE=/usr/src/linux

# Simple test for the Makefile.
#
if [ ! -e $KSOURCE/Makefile ]; then
        echo "Can't find $KSOURCE/Makefile.  Make sure $KSOURCE exists."
        exit
fi

# Patch the Makefile to clean the scripts tree when doing clean.
#
patch -d $KSOURCE << END
--- ../2.6.28-linode15.orig/Makefile    2008-12-29 15:36:08.000000000 -0500
+++ Makefile    2009-01-01 03:08:19.000000000 -0500
@@ -1174,7 +1174,7 @@
 #
 clean: rm-dirs  := $(CLEAN_DIRS)
 clean: rm-files := $(CLEAN_FILES)
-clean-dirs      := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs) Documentation)
+clean-dirs      := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs) Documentation scripts)

 PHONY += $(clean-dirs) clean archclean
 $(clean-dirs):
@@ -1194,7 +1194,7 @@
 #
 mrproper: rm-dirs  := $(wildcard $(MRPROPER_DIRS))
 mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
-mrproper-dirs      := $(addprefix _mrproper_,Documentation/DocBook scripts)
+mrproper-dirs      := $(addprefix _mrproper_,Documentation/DocBook)

 PHONY += $(mrproper-dirs) mrproper archmrproper
 $(mrproper-dirs):
END

# Run make targets to prepare the tree.
#
make -f $KSOURCE/Makefile clean
make -f $KSOURCE/Makefile oldconfig
make -f $KSOURCE/Makefile scripts/genksyms/
make -f $KSOURCE/Makefile prepare

This should be useful for other Linode users building dahdi or other kernel modules under 32bit Linux distributions.

[2009-Jan-01 EDIT:  The reason I didn't do "make mrproper" or "make distclean" is that I needed the Module.symvers file, which is created during the kernel compile.  That file appears to be used to add symbols when building modules.  Even while using difference force options, I was getting "no symbol version for struct_module" errors.  Once that Module.symvers file was present, I was able to build and load the modules as expected.]

[2009-Jan-02 EDIT: You may be using a different version of gcc than what the Linode kernel was compiled with. In that case, you'll need to pass the "--force-vermagic" option to modprobe when loading the module.]

[2009-Jan-02 EDIT: Updated the script to run oldconfig after the clean stage.]


css.php