Configuring an IP04

This page lists the various changes I've made to the configuration of the IP04 four port IP-PBX to make it play nicely with Nodephone. I've also made some other changes to make it work the way I want.

If you want to rebuild any packages from source, start by reading David Rowe's IP04 Developer HOWTO. To apply any of the patches I include below, you'll need to have setup your own development environment by following David's instructions.

Note: One of the things I did fairly early on was to replace the default installation of Asterisk 1.4.4 with the most recent package available in David Rowe's repository, version Any config file changes suggested on this page were made to this later version, and may not be applicable to the older version.


Synchronising the clock with NTP

Install ntp:

ip04:~> ipkg update ip04:~> ipkg install ntp

By default, ntpdate is run once at boot time to set the time from To use a different time server, edit /etc/init.d/ntp and change the ntp server name.

I've tried configuring and running ntpd but it doesn't seem to work on uClinux. so to keep the clock in sync, you'll need to run ntpdate regularly. To do this, install cron if you haven't already done so:

ip04:~> ipkg update ip04:~> ipkg install cron

Edit /etc/config/crontab to add a job to run ntpdate hourly. You'll need to add a line like this:

12 * * * * root ntpdate -s

This runs ntpdate at 12 minutes past the hour, every hour, sending any log output to syslog rather than to stdout. This is sufficient to keep correct time.

Setting the timezone

uClibc doesn't understand zoneinfo style timezone definitions, so you need to define DST transitions in the TZ environment variable (by putting its value into /etc/TZ. Use the stdoffset[dst[offset][,start[/time],end[/time]]] form of $TZ as described here

For Sydney, /etc/TZ should contain this:

ip04:~> cat /etc/TZ AEST-10AEDT-11,M10.1.0/02:00:00,M4.1.0/03:00:00

I read somewhere (but can't remember where) that Asterisk requires a zoneinfo file to use the correct timezone in voicemail timestamps. This seems odd to me, given that Aterisk is linked with the same uClibc that doesn't understand zoneinfo files, but, just in case, I copied /usr/share/zoneinfo/Australia/Sydney from one of my Ubuntu installations into /etc/localtime on my IP04.

If you've installed cron, update /etc/init.d/cron to set TZ before starting cron. Here is a patch to fix that.

Preventing cron from exiting on SIGHUP

If you log in to your IP04 and stop and restart cron (e.g. to set TZ as described above), cron will exit as soon as you logout. This is because a SIGHUP is sent to all child processes when the parent (the shell) is terminated. Asterisk and lighttpd are not affected by this because they have SIGHUP handlers. Cron does not have such a handler, and the default action when SIGHUP is received is to terminate the process.

To fix this, cron needs to be patched to ignore SIGHUP. Here is the patch which does this.

Without this patch, the only way to restart cron is to reboot, unless you want to leave a remote session permanently logged in.

Add correct Nodephone configuration

The IP04 default firmware includes the Mini-Asterisk GUI for system configuration. This is a basic but functional GUI which requires no knowledge of Asterisk to get started. Unfortunately, its SIP and SIP-NAT configurations don't work with Nodephone. I have submitted a patch to fix this, but until it has been incorporated into the Mini-Asterisk GUI, you can get the necessary patches here:

Automatically using Nodephone for outgoing calls

The default dial plan in the IP04 requires first dailling 0 to select the FXO port (PSTN) or 1 to select your SIP provider. I wanted all calls to go out via Nodephone by default (except emergency calls which would always use the PSTN), only selecting the PSTN if an override code was dialled first. This is the dial plam I'm using to do this:

; '#' to select PSTN exten => _#.,1,Dial(Zap/g2/${EXTEN:1}) ; emergency calls to PSTN (112 is the GSM emergency number) exten => 000.,1,Dial(Zap/g2/000) exten => 112.,1,Dial(Zap/g2/000) ; 106 is the TTY emergency number exten => 106.,1,Dial(Zap/g2/106) ; everything else to Nodephone exten => _X.,1,Dial(SIP/0290430669/${EXTEN}) [incoming] ; Pre-configured incoming calls exten => s,1,Dial(Zap/3&Zap/4) ;; mini-asterisk - don't remove this comment

I would like it to automatically fall back to using the PSTN if Nodephone is unavailable (possibly with a different dial tone to alert the caller), but I haven't yet figured out how to do that. When I do, I'll post details here.

Getting Caller ID to work

Caller ID on analogue ports requires the asterisk-spandsp package. Backup your config files (/etc/asterisk) first, then run:

ip04:~> ipkg update ip04:~> ipkg remove asterisk ip04:~> ipkg install asterisk-spandsp-

After doing this, caller ID still didn't work on the FXS ports in the firmware loaded into the IP04 when I received it. After much trial and error, I asked David Rowe if he knew of any software or hardware bug that would prevent it from working, and luckily for me, he'd recently found a bug in this area. I needed a new version of the zaptel-sport package which David has made available in his repository.

Make sure that the follwing are set in /etc/asterisk/zapata.conf:

usecallerid=yes hidecallerid=no restrictcid=no cidsignalling = bell sendcalleridafter=2

Installation is very simple, but backup /etc/zaptel.conf, /etc/asterisk/zapata.conf and /etc/asterisk/zapscan.conf first, as these files may be changed during installation:

ip04:~> ipkg update ip04:~> ipkg remove zaptel-sport ip04:~> ipkg install zaptel-sport

Note that David forgot to bump the version number when he updated the package, so don't rely on the version number of your installed zaptel-sport package when deciding whether you need this fix.

Update 2ng August 2010: All calls from the PSTN with incoming CID blocked or unavailable were showing on my analogue phone (Panasonic cordless) as "Out of area". After some debugging I discovered that although Asterisk can detect the difference between blocked and unknown CID on incoming calls, it discards this information and treats them both the same when sending the received CID on to any phones. As a workaround, I've patched Asterisk to set the CID numer (or name) to "Private" rather than NULL if the CID_PRIVATE_NUMBER (or CID_PRIVATE_NAME) flag is set. I do want to try to improve the patch to make Asterisk save the CID flags and use them when generating CID, but that's going to need much more work.

Configuring the analogue interfaces for Australian conditions

In /etc/zaptel.conf, change loadzone=us to loadzone=au and defaultzone=us to defaultzone=au.

Make sure that the follwing are set in /etc/asterisk/zapata.conf:

busydetect=yes ringtimeout=2500

Changing prgress tones (dial, busy, etc) to standard Australian tones

In /etc/asterisk/indications.conf, change country=us to country=au.

Changing extension numbers to not overlap PSTN number ranges

There are two ranges of numbers which are reserved in (almost) all call zones in Australia (see this page on Wikipedia. One of these ranges is allocated in Victoria but unused elsewhere, whilst the other range is unused in all zones. I want my internal extension numbers to fall in the reserved range to remove any possibility of someone dialling an extension when they meant to dial an external number.

To change the number range, I'll have to modify /etc/asterisk/extensions.conf and patch the Mini-Asterisk GUI because it has 6xxx hard-coded as the internal number range. Details to come ....

Syslogging to remote host

I run a syslog server for my LAN, so I wanted my IP04 to use it. The installed busybox isn't built with remote syslog support, so to enable it I had to rebuild busybox.

Here is the patch to enable remote syslog. Apply this patch, then build uClinux with make -f uClinux. This builds uClinux and tools, including busybox. If you've already done this, you'll need to run make -f clean, or delete the uClinux-dist directory and unpack a clean copy, because it doesn't properly rebuild busybox if you modify the config files and run make again.

After rebuilding busybox, copy it to /bin/ on your IP04 and change the syslogd and klogd symlinks to point to the new binary. Modify /etc/inittab to start syslogd with the -R <syslog_hostname> switch, then reboot (or kill syslogd and klogd) and you should see log messages being sent to your syslog server.

Enabling syslog rotation

Rebuild busybox to include syslog logrotate support. I don't need this, but I saw that busybox supported it so I thought I'd include instructions on how to do it for anyone who did need it. No patch yet, but it's easy to do: set CONFIG_USER_BUSYBOX_FEATURE_ROTATE_LOGFILE in patch/vendors/Rowetel/IP04/config.vendor-2.6.x, then rebuild busybox as described above.

Fix remote syslog so that boot messages aren't lost

When syslogging to a remote host, boot messages are lost. This may be due to syslogd and klogd being started before the network is up. I plan to try starting syslogd and klogd via a script in /etc/init.d rather than via /etc/inittab to see if I can fix this.

Fixing Asterisk startup warnings

You need to make various changes to config files. Details to come ...

Using the MMC card

Limited testing so far. Works with SD cards (not SDHC) up to 2GB, but only if card is not partitioned. Using a partioned card results in an error from the kernel saying that the partition is larger than the device, even if it's not (although I've so far only tested this with a 2GB card, more tests to come later ...).

Requires the spi_mmc module to be loaded, unloaded then reloaded before first mounting the card, otherwise the mount fails and you get an error in syslog ("Could not read this MMC/SD card CSD/CID registers."). On subsequent mounts, unloading and reloading the module seems to be sufficient.

2GB cards must be formatted with the logical block size set to 1024 bytes. The IP04's kernel drivers use the logical block size only and ignore the card's hardware block size, which for 2GB cards is always 1024 bytes. 1GB or smaller cards have 512 byte hardware sectors.

Setting the tx and rx gain on analogue ports

I need to do this. I'll post details when I've finished.

Setting up asterisk call logging to a remote mysql database

Another thing on my to-do list. Need to build libmysqlclient from uClinux-disdt, and from asterisk-addons. I'll post details when I've finished this.

Fixing hook flash on FXS ports

The recall buttons on my two analogue handsets didn't work, and changing the hook flash timing settings in my Asterisk configuration files didn't help. After some time searching through the source code, I found that there's a compiled-in minimum hook flash time (it's actually the maximum length of a dial pulse, but a dial pulse and a hook flash differ only in duration) in the zaptel package. That limit is either 80ms or 200ms, depending upon whether zaptel was compiled with SHORT_FLASH_TIME enabled or not. In the IP04 package, SHORT_FLASH_TIME is disabled, so your analogue handsets must be configured to send a hook flash pulse longer than 200ms. I changed one of my handsets to send a 270ms hook flash and the other to send a 300ms hook flash. That was the closest I could make them.

I then configured Asterisk to accept hook flashes between 250ms and 350ms duration by setting flash and rxflash in /etc/asterisk/zapata.conf:

flash=250 ; minimum hook flash (recall) length rxflash=350 ; maximum hook flash length

Now hook flash works from both of my analogue handsets.

Setting up music on hold

Music on hold is configured in /etc/asterisk/musiconhold.conf. Exluding comments and blank lines, these are the settings that my IP04 came with:

[default] mode=files directory=/var/lib/asterisk/moh random = yes

With this configuration, Asterisk will choose a random file from the directory /var/lib/asterisk/moh whenever it needs to play hold music. This is exactly how I want it to work, so I didn't need to make any changes.

Asterisk can transcode music files on the fly, but this can be costly in CPU cycles, and the Blackfin CPU in the IP04 isn't a very powerful processor. It's much better to have multiple copies of your hold music, encoded in multiple formats, and let Asterisk play the hold music in the most appropriate format.

You can use ffmpeg to create multiple versions of each track, for example:

for i in *.flac do f=`basename $i .flac` ffmpeg -i $i -ar 8000 -ac 1 -ab 64000 $f.wav \ -ar 8000 -ac 1 -ab 64000 -f mulaw $f.pcm -map 0:0 -map 0:0 done

You then need to copy *.wav and *.pcm (and any other formats you've encoded) into /var/lib/asterisk/moh on your IP04 and restart Asterisk.

To test music on hold, add a dialplan rule like this to /etc/asterisk/extensions.conf:

exten => 6100,1,Answer() exten => 6100,2,MusicOnHold()

After reloading the dialplan, dial extension 6100 and you should hear a random track from your hold music collection.