SIP.edu CSU Deployment Notes

Gabriel L. Somlo, December 2004

Table of Contents

  1. General Information
  2. Software Installation
  3. Configuration
    1. Configuring the Zaptel Driver
    2. Configuring Asterisk
    3. Configuring SER
  4. Information for Callers
    1. Configuring X-Lite as a Standalone Client
    2. Configuring KPhone as a Standalone Client

1. General Information

2. Software Installation

We are running a SER/Asterisk combination. Both programs run on the same single-CPU P4-2.4Ghz-1Gb PC. The link to our PBX is provided by a Digium T100P PRI card.

We run Fedora Core 2, and have generated updated RPM packages for Zaptel, libpri, Asterisk, and SER:

Note1: We used these as a starting point for our packages.
Note2: To build these on a Fedora box, run 'rpmbuild --rebuild *.src.rpm'

After having built and installed the binary RPMs from the sources listed above, and added the '_sip._udp' DNS record to our nameserver, we proceeded to set up the config files for Asterisk and SER.

3. Configuration

3.1. Configuring the Zaptel Driver

There are two ways to "start" the zaptel driver:

  1. using the '/etc/init.d/zaptel' script provided with the rpm package
  2. appending entries to /etc/modprobe.conf (using the examples provided in /usr/share/zaptel/modprobe.conf)

After exchanging a few emails with Mark Spencer (the author of the software), here's the tradeoff between the two approaches above:

After careful consideration, and given that we only have one card in the system, I have built the RPM such that the init script is not set to start by default. The modprobe.conf option was used, and the following lines have been added to /etc/modprobe.conf:

###### zaptel driver #######
alias char-major-196 wct1xxp
install wct1xxp /sbin/modprobe --ignore-install wct1xxp; /sbin/ztcfg

The contents of the /etc/zaptel.conf file was developed in close cooperation with Jim Hebbeln, who maintains our Nortel DMS-100 PBX:

span=1,1,0,esf,b8zs
bchan=1-23
dchan=24
loadzone = us
defaultzone=us

3.2. Configuring Asterisk

Asterisk has lots and lots of config files, and offers a huge number of features. We tried to turn off as much as we could of what we didn't need. Currently, the /etc/asterisk/ directory contains only the following files:

The first three are unmodified versions of the originals shipped with the RPM package. The latter four were modified to suit our configuration as indicated below.

3.2.1. Modifying /etc/asterisk/zapata.conf

Most of these settings were derived as a continuation of the joint effort with Jim Hebbeln. This is the current content of the file:

[channels]
context=default
switchtype=dms100
signalling=pri_net
usecallerid=yes
hidecallerid=no
usecallingpres=yes
callwaitingcallerid=yes
threewaycalling=yes
transfer=yes
cancallforward=yes
callreturn=yes
echocancel=yes
echocancelwhenbridged=yes
echotraining=yes
rxgain=0.0
txgain=0.0
group=1
channel => 1-23
callgroup=1
pickupgroup=1
jitterbuffers=4

3.2.2. Modifying /etc/asterisk/modules.conf

We turned off a number of unused modules that Asterisk would have loaded on startup. Our current file looks like this:

[modules]
autoload=yes
noload => pbx_gtkconsole.so
noload => pbx_kdeconsole.so
noload => app_intercom.so
noload => chan_modem.so
noload => chan_modem_aopen.so
noload => chan_modem_bestdata.so
noload => chan_modem_i4l.so
load => res_musiconhold.so
noload => chan_alsa.so
noload => chan_oss.so
noload => chan_skinny.so
noload => cdr_manager.so
noload => chan_iax2.so
noload => chan_mgcp.so
noload => chan_agent.so
noload => chan_phone.so
noload => app_queue.so
noload => app_enumlookup.so
noload => app_voicemail.so
noload => app_ices.so

3.2.3. Modifying /etc/asterisk/sip.conf

Both SER and Asterisk will try to use port 5060 for SIP connections. Since SER (described later) is our "public" point of contact, we changed the port on which Asterisk listens for SIP connections to 5065. Also, since SER and Asterisk both run on the same machine, the IP address listed for the SER proxy is whatever ifconfig returns for eth0 on this box (which we'll refer to using AAA.BBB.CCC.DDD). Here's the contents of the file:

[general]
context=default
port=5065
bindaddr=0.0.0.0
srvlookup=yes
[ser]
type=user
context=proxy
host=AAA.BBB.CCC.DDD

3.2.4. Modifying /etc/asterisk/extensions.conf

This is where incoming calls sent by SER are handled. We set the caller ID name to the caller name provided in the SIP header (contained in the ${CALLERIDNAME} variable), and the number to 000-000-0001, (which is an invalid phone number). The content of the file is:

[general]
static=yes
writeprotect=no
[globals]
CONSOLE=Console/dsp
IAXINFO=guest
TRUNK=Zap/g2
TRUNKMSD=1
[proxy]
exten => _970NXXXXXX,1,SetCallerID,"sip:${CALLERIDNAME}<0000000001>"
exten => _970NXXXXXX,2,Dial(Zap/g1/${EXTEN:3})
exten => _970NXXXXXX,3,Hangup
[default]
include => proxy

3.3. Configuring SER

The SER package installs a '/usr/sbin/serctl' script. A line containing the SIP domain must be added to the top of this file:

SIP_DOMAIN="colostate.edu"

We currently do not offer registration for user agents. SER's only purpose is to forward all SIP requests to Asterisk. We therefore do not need authentication or database support for now (we do plan to offer user-agent registration in the future, though). We use an LDAP lookup script based on the example provided by Columbia.edu to obtain phone numbers from the first.last@colostate.edu email-like SIP URIs.

Our /etc/ser/ser.cfg file looks like this:

check_via=no    # (cmd. line: -v)
dns=no           # (cmd. line: -r)
rev_dns=no      # (cmd. line: -R)
listen=AAA.BBB.CCC.DDD		# this is where SER listens (port 5060)
alias="colostate.edu"		# this is the default domain we serve
alias="AAA.BBB.CCC.DDD"		# (ACK and BYE) URIs will also have Asterisk's IP:5065 !
fifo="/tmp/ser_fifo"
loadmodule "/usr/lib/ser/modules/sl.so"
loadmodule "/usr/lib/ser/modules/tm.so"
loadmodule "/usr/lib/ser/modules/rr.so"
loadmodule "/usr/lib/ser/modules/maxfwd.so"
loadmodule "/usr/lib/ser/modules/usrloc.so"
loadmodule "/usr/lib/ser/modules/registrar.so"
loadmodule "/usr/lib/ser/modules/exec.so"
modparam("usrloc", "db_mode",   0)
modparam("rr", "enable_full_lr", 1)
route{
        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483","Too Many Hops");
                break;
        };
        if ( msg:len > max_len ) {
                sl_send_reply("513", "Message too big");
                break;
        };
        record_route(); 
        if (loose_route()) {
                t_relay();
                break;
        };

	################################################################
	# until here, everything is pretty much the standard boilerplate
	# material that is shipped in the default SER config file.
	################################################################

        # reject REGISTER attempts for now
        if (method=="REGISTER") {
                sl_send_reply( "503", "Registration Unavailable" );
                break;
        };

        # resolve alphanumeric names in the URI
        if (uri=~"sip:[a-zA-Z\.]*@colostate\.edu") {
                exec_dset( "/etc/ser/siplookup" );
        };

        # forward all calls to sip:970XXXYYYY@colostate.edu to Asterisk
        # ACK and BYE requests sometimes have URI @AAA.BBB.CCC.DDD:5065 (i.e., inteneded for Asterisk!)
        # uri==myself would match anything @colostate.edu or @AAA.BBB.CCC.DDD
        # we just want specific phone numbers @colostate.edu to match
        if (uri=~"sip:970[0-9]{7}@(colostate\.edu)|(AAA\.BBB\.CCC\.DDD)" ) {
                forward( localhost, 5065 );
                break;
        };

        # send not found error for any other URI
        sl_send_reply( "404", "Not Found" );

}

The siplookup script is based on Columbia.edu's example. We have a few hard-coded email-phone translations first (e.g., my desktop phone is listed in LDAP, but I want my cellphone to ring when a SIP.edu call comes in). If no hard-coded exceptions are found, the LDAP directory is used to figure out the phone number. Here's our siplookup script:

#!/bin/bash

# convert   sip:@colostate.edu   into   sip:970XXXYYYY@colostate.edu
#
# Gabriel L. Somlo, 2004-12-07
#

LDAP_SERV="ldapserver.colostate.edu"
LDAP_BASE="dc=colostate,dc=edu"

if [ -z "${1}" ]; then
  echo
  echo "   Usage:  $0 sip:@colostate.edu"
  echo
  echo "   Returns the corresponding numerical SIP URI:"
  echo
  echo "       sip:970XXXYYYY@colostate.edu"
  echo
  exit 1
fi

EMAIL=$(echo ${1} | cut -d: -f2)

# look up hardcoded special cases first:
PHONEINFO=$(grep -i "^${EMAIL} " << EOT
Joe.Bloggs@colostate.edu 9705671017
EOT)
PHONE=${PHONEINFO#* }

# search LDAP directory if special-case hardcoded number not found:
if [ -z "${PHONE}" ]; then
  PHONE=$(ldapsearch -LLL -x -h ${LDAP_SERV} -b ${LDAP_BASE} mail=${EMAIL} telephonenumber | grep -i telephonenumber | cut -d' ' -f2 | tr -d '-')
fi

# print out original unmodified URI if nothing found, or @colostate.edu
if [ -z "${PHONE}" ]; then
  echo "${1}"
else
  echo "sip:${PHONE}@colostate.edu"
fi

4. Information for Callers

This information is intended for those who will call SIP.edu users. In essence, if you are one of the users reachable via SIP.edu, this is what you need to show to those who might want to call you.

Currently, this information is only applicable for callers with a valid public IP address. There are workarounds for when the caller is behind a NAT gateway, but that scenario is not (yet) being addressed in this document.

Essentially, the caller will ned a SIP-capable user agent (i.e., "phone" -- either software or hardware, see the Cookbook for details). This document covers the use of X-Lite for Windows and the Mac, and KPhone for Linux. These can be downloaded at the following locations:

Registration with a VoIP service provider may be available to the caller, in which case that provider's instructions should be followed. These instructions are intended for standalone callers who do not have any sort of account with any kind of VoIP service provider.

4.1. Configuring X-Lite as a Standalone Client

After downloading X-Lite, the first time the application is started, it will run the user through its "Audio Tuning Wizard" (i.e., it will optimize the audio and microphone settings). The steps are:

  1. set the volume to a comfortable level while a recording is being played
  2. user talks into the microphone and adjusts gain until playback of the user's recorded voice is satisfactory
  3. calibrate the microphone by recording a period of silence to compare against the previous voice recording.

Once the audio setup is completed, the Menu window will open automatically, offering to configure the "SIP Proxy settings". The window looks like this:
SIP Proxy Settings Menu
The following options must be configured:

Hit 'BACK', then close the menu window. X-lite should now tell you that you're "logged in" and to enter a "phone number":
X-Lite is ready to dial
The "phone number" should be a SIP URI (in CSU's case, this looks exactly like the e-mail address listed in the LDAP directory, e.g., <first>.<last>@colostate.edu).

If you missed the original menu configuration window, you can always revisit by clicking the menu button on X-lite. Navigate to 'System Settings', then 'SIP Proxy', then 'Default:'. This will bring back the interface described above, and allow you to make the required setting changes:
X-Lite Menu Button X-Lite SIP Proxy Menu

4.2. Configuring KPhone as a Standalone Client

When KPhone first starts, it brings up the "Identity" configuration menu, which looks like this:
KPhone Config Menu
The following options must be configured:

You are now ready to dial your party's SIP URI. Click on the "ear" symbol to place the call. To reconfigure your identity, select "File" and then "Identity".The main KPhone window looks like this:
Dialing on KPhone


Last Modified: Dec. 21, 2004; Send corrections and comments to somlo [at] acns dot colostate dot edu