Building a DLink DSL-502T Based IGate

This project came about because a group of amateur radio operators in Auckland wanted to improve the APRS receive coverage by using IGates to add receive only coverage around South Auckland.

We found that a really low cost way of doing this (both initial investment and ongoing operational costs) was to use DLink DSL-502T ADSL routers with customized firmware.


The DLink DSL-502T is very common in New Zealand.  It was the router of choice for many first time ADSL users who signed up with the large ISP's.  Over time many users want devices with more capability (wireless or more ports) so the routers are available at very low cost (or free). 

For those who care about the technical details.... the official specification for a DSL-502T is

  • ADSL modem with ADSL2/2+ support to 24Mbit/s+.
  • Single 100MBps LAN port.
  • Single USB-B port (default firmware uses this to provide USB-over-ethernet to a PC host only, it's not clear if this can actually be used as a USB host)
  • Flash chip: 4MBytes - Samsung K8D3216UBC a 32Mbit NOR-type Flash Memory organized as 4M x 8
  • SDRAM: 16Mbytes - Nanya NT5SV8M16DS-6K
  • CPU: TNETD7300GDU Texas Instruments AR7 MIPS based

More complete hardware details are on the OpenWRT DSL-502T hardware page.

In it's IGate implement we don't use the ADSL modem or the USB-B port.  What the specification doesn't say is that there is an onboard serial port (even provided with soldered pin headers) which is perfect (with level conversion from RS-232 to 3.3V TTL) for connect to an TNC.

Using a DSL-502T as an IGate is as much an exercise of configuring software as it is connecting hardware.  The standard operating software makes the device an ADSL router.... we need to replace this so it becomes an IGate.

This article is written for those who are interested in how to build their own operating system image for the device and outlines the steps I followed.  It isn't hard if you have a Linux installation (real or in a VM).... I used Ubuntu 8.1 which work really well as a platform for building the operating software and flashing it into the routers.

If you don't want to get into the details and just want an image to flash visit the guys at WetNet who have prebuilt images available for download - for the DSL-502T you need an image compiled for an AR71xx.

Before going into the detail of how to we built and configured the firmware it is worth explaining what we wanted to achieve.

  • A standard set of firmware that we could flash into many routers.
  • Installation without needing to connect to each router to install extra packages or make configuration settings (unless absolutely necessary).
  • For the router to be able to indicate it's operational status using the front panel LED's (only Status, Ethernet and USB are controllable... it appears that the ADSL indicator is managed directly from the ADSL interface).
  • Central management of the APRSD configuration and have this automatically applied when the power is cycled on the router.

We achieved all these objectives using a custom OpenWRT build. 

It must be said that this project would not have been possible without the efforts of all those involved in the OpenWRT project (for creating the build scripts and environment), those who make it work on AR71xx based routers and those involved with the WebNet project who ported APRSD for the OpenWRT platform.  We are thankful to all these people and hope that the notes here benefit others wanting to package these components to build IGates.

The following outlines the process and scripts we used to configure the DSL-502T as an IGate to meet these objectives.

A suitably configured environment is required to build the OpenWRT firmware.  Assuming you are using Ubuntu 8.1

1.  Install the packages required by the OpenWrt Kamikaze buildsystem

sudo apt-get install build-essential binutils flex bison autoconf gettext texinfo sharutils subversion libncurses5-dev ncurses-term zlib1g-dev 

2.  Checkout and prepare Kamikaze and the packages.  We built out image based on Kamikaze 8.09.2

mkdir ~/openwrt
cd ~/openwrt
svn checkout svn:// .

3.  I installed the minicom and ntpclient packages in the image.  Minicom is useful for checking the serial port works..... and ntpclient to keep the time correct.  Without ntpclient the box doesn't keep very good time.

./scripts/feeds install minicom
./scripts/feeds install ntpclient

4.  By default the serial ports are configured as serial consoles.  This needs to be disabled to use them to connect with a TNC.  Disabling the ports requires a customized /etc/inittab to be included in the flash image.  

Any files in the ./files folder of the build will be added to the flash image when it is built. 

Create the following ./files/etc/inittab to configure the serial ports so they can be used.

::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K stop
#tts/0::askfirst:/bin/ash --login
#ttyS0::askfirst:/bin/ash --login
#tty1::askfirst:/bin/ash --login

5.  The default configuration for OpenWRT (at least for the version I built) is to bring the network up with a static IP address.  I wanted DHCP so a customized /etc/config/network needs to be included in the flash image. 

Create the following ./files/etc/config/network to configure the network for DHCP.

# Copyright (C) 2006

config interface loopback
    option ifname    lo
    option proto    static
    option ipaddr
    option netmask

config interface lan
    option ifname    eth0
    option proto    dhcp   


6.  While we are making changes to /etc/config it is a good idea to configure the system name and timezone.

Create the following ./files/etc/config/system to configure the system name and timezone (in this case New Zealand).

config system
    option hostname    OpenWRT_IGate
    option timezone    NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0


7.  We installed the ntpclient package earlier but this still needs to be configured so it connects to an appropriate time server.

The configuration details are in /etc/init.d.

Create the following ./files/etc/init.d/ntpclient to start the ntpclient with an appropriate time server (or pool in this case).

/usr/sbin/ntpclient -c 1 -s -h &

8.  OpenWRT uses symbolic links between /etc/rc.d and /etc/init.d so we need to create these in ./files to reference the updated ntpclient start script.

Create the following symbolic link in ./files/etc/rc.d

ln -s ../init.d/ntpclient S55ntpclient

9.  Time to build OpenWRT for the AR7 based DSL-502T.  First it is necessary to configure the build:

make menuconfig

With the following options:

Target System = TI AR7 [2.6]
Target Profile = No WiFi
Target Images = squashfs

Base System = base-files, br2648ctl, busybox, dropbear, hotplug2, libgcc, libpthread, libstdcpp, mtd, opkg, uci, uclibc, udevtrigger

Network = atm-tools, wget
Library = (none)
IPv6 = (none)

Kernel Modules = kmod-ipt-core, kmod-ipt-nathelper, kmod-sangam-atm-annex-a, kmod-ppp, kmod-pppoa, kmod-pppoe, kmod-ocx

Utilities = terminal/minicom, gpioctl

10.  We wanted to default the Minicom configuration so it opened port /dev/ttyS0 at 9600 baud, did not send the default initialization string but instead sent the "VER" command to the TNC.

This is done by creating the file minirc.dfl in ./files/etc with the following contents:

pu port             /dev/ttyS0
pu baudrate         9600
pu minit            VER^M
pu mreset          
pu rtscts           No 

11.   The aprsd package (or other amateur radio packages) is not included in the OpenWrt source tree at the time of writing.  The packages can be downloaded from

The OpenWrt-AX25.tgz that you download doesn't match the the folder structure required by the OpenWrt build (at least for version 8.09.2) so it is easiest to uncompress to a different location and then copy the files to the locations as shown in the following table:

OpenWRT-AX25.tgz OpenWRT Source
packages/libs/libax25 package/libs/libax25
packages/net/aprsd package/net/aprsd
packages/net/ax25-apps package/net/ax25-apps
packages/net/ax25-tools package/net/ax25-tools
packages/net/digi-ned package/net/digi-ned


12.  Ensure the aprsd and required libraries are flagged to be built:

make menuconfig

With the following additional options:

Library = libax25
Amateur Radio = aprsd


13.  If you are going to flash a single DSL-502T you can set the aprsd configuration by adding appropriately configured aprsd.conf, aprsd.config, INIT.TNC, RESTORE.TNC and welcome files to the ./files/etc/aprsd folder.  

Because we were going to install multiple DSL-502T IGates and were trying to create a standard image that could be flashed to all units it was important to have a more flexible configuration process for aprsd.

We went with the approach of storing the aprsd.config file for each unit on a central web server.  The files are named with the Ethernet MAC address of the router. 

The startup script downloads the appropriate config file on startup of the router and updates the version in flash if it has changed.  

The script we used is an extension to the standard aprsd startup script and is as follows:

#!/bin/sh /etc/rc.common
# Starts or stops aprsd server.
# Extended to perform additional DSL-502T IGate Configuration Load
# Ethernet and USB Leds are used to indicate status of router configuration
# Ethernet
#    Off =
#    On = IP Address OK from DHCP
#    Flash = No IP Address from DHCP
#    Off =
#    On = APRSD Configuration OK
#    Flash = APRSD Configuration Invalid 


# Initially both off
echo none > /sys/class/leds/ethernet/trigger
echo none > /sys/class/leds/usb/trigger

MYMAC=`ifconfig eth0 | head -1 | grep 'HWaddr ' | cut -c39-55`
MYIP=`ifconfig eth0 | head -2 | tail -1 | grep 'inet addr:' | cut -c21-33`

if [ -z $MYIP ]; then
        echo heartbeat > /sys/class/leds/ethernet/trigger
        exit 1
        echo default-on > /sys/class/leds/ethernet/trigger

cd /etc

if [ -n $MYMAC ]; then
        wget -q -N $SERVER$MYMAC.conf

if [ -f $MYMAC.conf ]; then
        if [ ! -f $APRSD_CONFIG ]; then
                cp $MYMAC.conf $APRSD_CONFIG
                CONFDIFF=`diff $MYMAC.conf $APRSD_CONFIG | wc -l`
                if [ $CONFDIFF -gt 0 ]; then
                        cp $MYMAC.conf $APRSD_CONFIG

# Check if $APRSD_CONFIG has been correctly configured

if [ ! -f $APRSD_CONFIG ]; then
        echo heartbeat > /sys/class/leds/usb/trigger
        exit 1

SERVERCALL=`cat $APRSD_CONFIG | grep 'AX_APRSD_SERVERCALL' | cut -d'=' -f 2`

if [ $SERVERCALL = '"nocall"' ]; then
        echo heartbeat > /sys/class/leds/usb/trigger
        exit 1

chmod 745 $APRSD_CONFIG

start() {
   echo  "Starting aprs server daemon. "
        # Create log directory - uncomment if you want logging
#       mkdir -p /var/log/aprsd       
        # Update aprsd.conf

        # Escape options that may include /
        AX_APRSD_PORT=`echo $AX_APRSD_PORT | sed 's/\//\\\&/g'`
        AX_APRSD_MYLOCATION=`echo $AX_APRSD_MYLOCATION | sed 's/\//\\\&/g'`
        AX_APRSD_NETBEACON=`echo $AX_APRSD_NETBEACON | sed 's/\//\\\&/g'`
        sed -i "s/\(tncport\)\(.*\)/\1 $AX_APRSD_PORT/" $APRSD_CONF
        sed -i "s/\(tncbaud\)\(.*\)/\1 $AX_APRSD_TNCBAUD/" $APRSD_CONF
        sed -i "s/\(servercall\)\(.*\)/\1 $AX_APRSD_SERVERCALL/" $APRSD_CONF
        sed -i "s/\(MyCall\)\(.*\)/\1 $AX_APRSD_MYCALL/" $APRSD_CONF
        sed -i "s/\(MyLocation\)\(.*\)/\1 $AX_APRSD_MYLOCATION/" $APRSD_CONF
        sed -i "s/\(MyEmail\)\(.*\)/\1 $AX_APRSD_MYEMAIL/" $APRSD_CONF
        sed -i "s/\(aprspath\)\(.*\)/\1 $AX_APRSD_PATH/" $APRSD_CONF
        sed -i "s/\(pass\)\(.*\)/\1 $AX_APRSD_PASS/" $APRSD_CONF
        sed -i "s/\(Server\)\(.*\)/\1 $AX_APRSD_SERVER/" $APRSD_CONF
        sed -i "s/\(NetBeacon\)\(.*\)/\1 $AX_APRSD_NETBEACON/" $APRSD_CONF
        #  start aprsd if enabled
        eval aprsd=$AX_APRSD
        if [ "$aprsd" = "TRUE" ]; then
                /usr/bin/aprsd -d
                echo default-on > /sys/class/leds/usb/trigger
                touch /var/lock/aprsd

stop() {
   echo  "Stopping aprs server daemon. "
        rm -f /var/lock/aprsd
        killall -q -INT aprsd

There are a few interesting things in the script.

  • The Ethernet and USB LED's on the DSL-502T are used to indicate status.
  • Ethernet flashing means no IP address was assigned so there is a problem somewhere with DHCP.
  • Ethernet on means an IP address was assigned.
  • USB flashing means that no aprsd.config file could be downloaded (and none already exists in flash).
  • USB on means that the device has a valid aprsd.config file (either newly downloaded or already existing).
  • When both Ethernet and USB LED's are lit the aprsd service will have been started.
  • The aprsd.config file was extended to include additional settings which are not included in the standard file and only exist in aprsd.conf.

14.  With all the modules selected the OpenWRT image is ready to build.


This could take a while.  Everything going well you will see a string of make messages, the last few messages if all went well being:

 make[2] package/rootfs-prepare
 make[3] package/preconfig
 make[2] target/install
 make[3] -C target/linux install
 make[6] -C target/linux/generic-2.6/image/lzma-loader clean compile

Your image is now built and available at ./bin/openwrt-ar7-squashfs.bin

This is the image that you flash to your DSL-502T with the command:

./scripts/ -setmtd1 ./bin/openwrt-ar7-squashfs.bin

Note:  Depending on the version of your DSL-502T the default IP address may be (rather than

Once the firmware is installed the DSL-502T will restart.... the restart process can take up to 60 seconds.  An operational IGate will be flashing the Status LED (like a heartbeat) and have Ethernet and USB LED's on.

Check your IGate appears using APRS.FI but note that your NetBeacon is not sent immediately on startup.... it will only be sent after the specified time.   Setting the NetBeacon interval to 1 minute initially to check the IGate appears and once you are properly communicating with the APRS-IS server update the NetBeacon interval to something more reasonable - we use 60 minutes.



Powered by Easytagcloud v2.1

Contact Andrew Quinn