PerlAPRS - Automated Control in APRS Networks

San Diego, California Pix
Figure 1 San Diego, California
San Diego, California Pix
  • PerlAPRS is an application which can monitor both local TNC and remote Internet APRS packets. It then can perform an automated action based on criteria specified by the user. The criteria that PerlAPRS uses is the callsign of the station and its location specified as a Maidenhead Grid Square. Other requirements specified by the user increase functionality of the program in real world applications. The actions executed can be written in any language, but UNIX style shell scripts are ideally suited for this purpose. Scripts can be developed to perform functions such as automatic notification via email as well as logging. PerlAPRS is freely distributed under the GNU licensing agreement.
  • Introduction
  • The Callsign File
  • Shell Scripts
  • Starting PerlAPRS
  • How It Works
  • Maidenhead Grids
  • Conclusion
  • Acknowledgement
  • System Requirements
  • Software Distribution
  • Unix Enviornment


The Automatic Position Reporting System is one of the most popular facets of amateur radio today. It is a marriage of several cutting edge technologies including the Global Positioning System (GPS), amateur packet radio, and the global Internet. It incorporates satellite technology, wireless networks, and both analog and digital communication. The applications to support the APRS protocol are also sophisticated. They provide the user with an easy to use interface into the APRS world. Software such as MacAPRS for the Apple Macintosh, WinAPRS for Windows 95/NT, and APRSdos for DOS machines provide powerful and elegant solutions. With this software and support system, it is possible to display any APRS network. Other support software for APRS includes the work of Steve Dimse, K4HG, who extended the concept for the promulgation of APRS packets to the Internet with javAPRS. In addition, Steve Boyle, KD6WXD; and Dale Heatherington, WA4DSY, developed APRS servers for the Internet which allow users to remotely connect to the server and examine remote APRS networks.

These programs provide flexibility, functionality, and a highly visual means for tracking APRS activity. However, they are passive in that they provide predominately monitoring functionality. They do not provide the ability to control. For example, if you wish to know when an APRS tracker escorting marathon runners reaches a specific location, you need more than monitoring capability, you need control functionality. It is this ability that PerlAPRS provides.

PerlAPRS is a program written in the Perl computer language. Perl runs on all popular computer platforms today including MacOS, Windows3.1/95/NT, AMIGA, Unix, Linux, and many more. In addition, since Perl is compiled at run time, there is no need for a version precompiled or packaged for a specific platform. Also, since all source code is included for PerlAPRS, the user may easily alter the program to meet specific needs and is encouraged to do so. However, most users will find modifying the shell scripts rather than the program should meet most requirements.

PerlAPRS examines incoming packets from an APRS network and executes commands when a callsign and location match the criteria specified by the user. Location criteria is specified using grid squares. For example, when KC5PVL enters grid square DM12LW, a computer command specified by the user can be automatically executed.Figure 1 shows grid squares overlaid on the city of San Diego, California, it will serve as the basis for the examples in this paper. The map shows several grid squares that are targeted for an action when the criteria specified in the callsign.dat file is met.

The Callsign File

When PerlAPRS starts, it reads the user's callsign database file with the default filename of callsign.dat. This file provides the list of callsigns that PerlAPRS is to search for. The file consists of one or more lines of text as shown in Figure 2. A separate line (record) is required for each callsign. Each line of the file is further broken into five fields, a separate field for each parameter.

KI6MP-10 DM12JV  2       1440
KC6VVT-9 DM12IT  3       1440
KD6AZU DM12KR  3       180
KE6PHB DM12LT  5       60
*      DM12LN  2       60
Figure 2 Example Callsign File

The first field indicates the callsign that PerlAPRS is to listen for. In the example, PerlAPRS will listen for KI6MP-10, along with KC6VVT-9, KD6AZU, and KE6PHB. The asterisk character, shown on the last line of the example, is a wildcard that means "any" callsign.

The second field indicates the command that will be executed when the callsign is heard. It can be any computer command, however, as we will discuss later, shell scripts are powerful and easily implement commands. In the example, will be executed when KI6MP-10 is heard.

The third field represents the grid square in which the callsign must be heard. Returning to the example, PerlAPRS is listening for KI6MP-10 in grid square DM12JV. The fourth field is provided to limit the number of times the command is executed during an active period. This parameter is necessitated by the repetitive nature of APRS packets. For example, if a station continues to broadcast packets while located within the grid square, the command would be executed each time a packet is heard. Since some APRS packets (e.g., mobile) are transmitted every few minutes, in many cases it would be undesirable to have the command executed repetitively in a short period. For this reason, the value is typically a small number (e.g., 1-5). However, indicating a large value will cause the command to be executed virtually without limit. Conversely, if one wishes to disable execution, setting the value to zero essentially disables the command without removing it from the database. In the example, the command,, will be executed no more than 2 times during an active period.

The last field is provided to allow the user to specify the active period. The active period is the time expressed in minutes in which PerlAPRS is actively listening for the specified callsign. This is important, since without a means of resetting the execution counter, it would be inconvenient to leave the program running for an extended period (e.g., many weeks).

The following scenario may help to illustrate the need for specifying the active period. Assume we wish to leave PerlAPRS running indefinitely. Also assume we don't want to execute a command every time a packet is heard since this could be hundreds of time during a 24 hour period. If we set the execution counter to a small value, we will limit the number of times the command is executed. However, once that count is reached, commands will no longer be executed. The active period parameter is therefore provided to allow the user to specify when the execution counter specified in field 4 is to be reset. Returning to our example, we see that a command will be executed no more than 2 times in a 24 hour (1440 minutes) period for KI6MP-10. At the end of the 24 hour period, the counter is reset and the command can again be executed up to 2 times during the next active period.

When PerlAPRS begins it reads in the callsign file and shows the original information provided by the user along with the conversion of the grid square to latitude and longitude. To completely describe the grid square, requires the latitude and longitude of the lower left and upper right points of the square. These corner points are used by PerlAPRS to determine if the station is within the grid square.

[rparry@blue aprs]$ perlAPRS -s

                        *** USER DATA ***
    Callsign   Command  Grid     Exe  Reset  LwrLat  LwrLon    UprLat  UprLon
 1   KI6MP-10  DM12JV    2   1440   3252.0 -11715.0   3255.0 -11710.0
 2   KC6VVT-9  DM12IT    3   1440   3247.5 -11720.0   3250.0 -11715.0
 3     KD6AZU  DM12KR    3    180   3242.5 -11710.0   3245.0 -11705.0
 4     KE6PHB  DM12LT    5     60   3247.5 -11705.0   3250.0 -11700.0
 5          *  DM12LN    2     60   3232.5 -11705.0   3235.0 -11700.0
Figure 3 Output from PerlAPRS based on user's callsign file

Shell Scripts

When an APRS packet is heard, the command specified by the user is executed. It is important to emphasize that virtually any command can be executed, one is not limited to shell scripts. However, they are simple to write, flexible, and powerful. Scripts should meet the needs of most users. Alternatively, one can use Perl scripts which are even more powerful, yet still easy to write.How to write shell scripts is a subject all by itself, and for this reason only a few examples are provided here. You don't have to be a software engineer to write scripts, but a knowledge of UNIX commands is important. The examples below were developed on a Linux system. These commands are not expected to work on other systems without customization. They are provided here as examples for illustrative purposes.The following shell script will make a sound by sending the audio file chirp.wav to the audio output port of the system. #!/bin/bash cat /sounds/chirp.wav > /dev/audio Shown below is a simple shell script to send email. #!/bin/bash echo "Match for KK5SU" | mail -s "perlAPRS notification"

Starting PerlAPRS

PerlAPRS is invoked from the command line like most UNIX style commands. Note that in the examples below, several command line arguments may be passed to the program which allow the user to alter PerlAPRS defaults.perlAPRS -h
perlAPRS -help

Display a help screen. perlAPRS -v
perlAPRS -version

Display the current version of the software. perlAPRS -s
perlAPRS -show

Normally PerlAPRS will not provide any output. The "show" option allows the user to see the progress of PerlAPRS. The show option will display only valid APRS packets that contain a position (latitude and longitude). perlAPRS -d
perlAPRS -debug

The debug option forces PerlAPRS to display packets that do not contain a valid position. This option is primarily for program debugging purposes. perlAPRS -d -s
This example shows how PerlAPRS can be made to display both packets with and without latitude and longitude information. perlAPRS -p /dev/cua2 perlAPRS -port /dev/cua2
The default port that PerlAPRS will open is "/dev/cua1". However, you can specify an alternate serial port using this option. For this example, a Linux serial port name is indicated. For other platforms, consult the system's documentation. perlAPRS -p
perlAPRS -p
perlAPRS -p

If an Internet address is specified, PerlAPRS will open a socket to the address and obtain TNC data from the Internet. The examples listed are three presently know APRS servers. The text preceding the colon is the host name. The number following the colon is the port number which is fixed at 14579 for APRS applications perlAPRS -p trip.tnc
A third specification for the port option is not actually a port, but a data file. If you have saved raw TNC packets to a text file, PerlAPRS will open the file rather than opening a serial port or an Internet communication's socket. This last variation of the port command is included for completeness, its main purpose is to allow PerlAPRS testing using known packets. perlAPRS -f callsign2.dat
If a command file is not specified on the command line, PerlAPRS will use the default filename callsign.dat. However, as shown in the example, the user can force an alternate command file to be called using the -f option.perlAPRS &
This example shows how most users will run PerlAPRS. In this example, PerlAPRS will not show any output. It is also run as a background process by adding the ampersand character (&).

How It Works

Figure 4 shows a sample output from PerlAPRS with the "-s" (show) option on. When a packet arrives, the callsign of the originating station is extracted along with the station's latitude and longitude. This information is then compared with each callsign in the database created by the user. If a match is found, the command is executed. The first line in the example below shows a packet from originating station KD6AZU. PerlAPRS extracts the callsign, latitude, and longitude, and displays them on the line following the packet. Since this is a valid APRS posit packet, PerlAPRS will search the callsign database looking for a match for KD6AZU. As shown in the example, the first two attempts at a match fail. The third comparison is a match shown in bold print for illustrative purposes. The command,, is then executed and the execution counter is incremented. Note that the first line of the match included the time that the packet was heard along with the maximum execution count specified by the user (e.g., 3). The second line of the match shows the time that the execution counter will be reset, the present value of the counter (e.g., 1) and the name of the execution command. When a second and third APRS packet arrives from KD6AZU, a match occurs and the command is executed again. When the fourth packet arrives, the command is not execution since the maximum execution count has been reached. No additional matches for KD6AZU will cause command execution. However, by the time the fifth packet arrives, the execution counter has been reset by the timeout and command is executed again.
Packet= KD6AZU>APRS,KD4DLT-7,N4NEQ-2,WIDE*:@042327/3243.70N/11707.70W/0
             KD6AZU       3243.700    11707.700
        -  KI6MP-10       DM12JV
        -  KC6VVT-9       DM12IT
        *    KD6AZU       DM12KR Sun Aug 10 15:56:13 1997    3
                                 Sun Aug 10 15:57:13 1997    1
        -    KE6PHB       DM12LT
        -         *       DM12LN
Packet= KD6AZU>APRS,KD4DLT-7,N4NEQ-2,WIDE*:@042327/3243.70N/11707.70W/0
             KD6AZU       3243.700    11707.700
        -  KI6MP-10       DM12JV
        -  KC6VVT-9       DM12IT
        *    KD6AZU       DM12KR Sun Aug 10 15:56:23 1997    3
                                 Sun Aug 10 15:57:13 1997    2
        -    KE6PHB       DM12LT
        -         *       DM12LN
Packet= KD6AZU>APRS,KD4DLT-7,N4NEQ-2,WIDE*:@042327/3243.70N/11707.70W/0
             KD6AZU       3243.700    11707.700
        -  KI6MP-10       DM12JV
        -  KC6VVT-9       DM12IT
        *    KD6AZU       DM12KR Sun Aug 10 15:56:34 1997    3
                                 Sun Aug 10 15:57:13 1997    3
        -    KE6PHB       DM12LT
        -         *       DM12LN
Packet= KD6AZU>APRS,KD4DLT-7,N4NEQ-2,WIDE*:@042327/3243.70N/11707.70W/0
             KD6AZU       3243.700    11707.700
        -  KI6MP-10       DM12JV
        -  KC6VVT-9       DM12IT
        *    KD6AZU       DM12KR Sun Aug 10 15:56:44 1997    3
                                 Sun Aug 10 15:57:13 1997    3
        -    KE6PHB       DM12LT
        -         *       DM12LN

Packet= KD6AZU>APRS,KD4DLT-7,N4NEQ-2,WIDE*:@042327/3243.70N/11707.70W/0
             KD6AZU       3243.700    11707.700
        -  KI6MP-10       DM12JV
        -  KC6VVT-9       DM12IT
        *    KD6AZU       DM12KR Sun Aug 10 15:57:14 1997    3
                                 Sun Aug 10 15:58:14 1997    1
        -    KE6PHB       DM12LT
        -         *       DM12LN
Figure 4 Output from PerlAPRS

Maidenhead grids

PerlAPRS relies on the use of grid squares to specify location. It accepts grid square parameters in 2, 4, or 6 letter formats. A 2 letter grid square covers such a large geographic area that the entire United States can be described in only 8 grid squares. A four letter grid square is smaller, but still represents a very large area (approximately the size of Connecticut). The 6 letter grid square is much smaller and is well suited for many applications in metropolitan areas.It is not possible to describe the area of a grid square for a given format (e.g., 2, 4, or 6 letters) since they vary with their location on the earth. To illustrate the point, Figure 5 shows the size of a 2 and 4 letter grid square for the northern and southern portions of the United States. Even larger variations in grid square size occur between the poles and the equator.
MaidenHead Grid Square Pix
Figure 5 Grid Square Comparisons

Note that only the longitudinal distance varies between the southern and northern portion of the United States. The reason for this apparent anomaly stems from the fact that lines of latitude are parallel to each other and therefore separated by a constant distance. Lines of longitude are not parallel, they meet at the poles and are farthest apart at the equator.


PerlAPRS was developed to expand the usefulness of APRS to automated unmanned operations. It is an application that should prove useful in circumstances that require a specific action to a predefined packet specification. Using shell scripts or other languages developed by the user in conjunction with PerlAPRS should provide the framework for developing and extending APRS to many unique applications.


Thanks to Bob Bruninga, WA4APR; for permission to use the APRS trademark. Special thanks also to Keith Sproul, WU2Z; Mark Sproul, KB2ICI; and Steve Dimse, K4HG; for their pioneering work in this area.

System Requirements

Linux was the development platform for PerlAPRS, however, it will work on any platform that supports perl version 5.002 or later. In addition, since Perl is available on virtually every popular computer platform, PerlAPRS should be able to be implemented easily. Any limitations are more likely to be with the platform's ability to support shell scripts. However, as emphasized in this paper, any computer language can be used to developing commands.

Software Distribution

PerlAPRS is a freeware program available under the GNU General Public License, Version 2, June 1991, Free Software Foundation, Inc. 625 Massachusetts Avenue, Cambridge, MA 02139. It may be downloaded from the author's home pages at: Further information regarding the necessary files to download and system requirements are included there.

Unix Enviornment

The documentation above should give you all you need to get started. There are a few points to remember however.
  1. In a UNIX enviornment, an executable file such as "perlAPRS" must have the file permissions set to executable. Use chmod 755 perlAPRS to set the permissions correctly.
  2. Devices, like files and directories, must also have their permissions set. For example, perlAPRS will attempt to open the default serial device "dev/cua1". On some systems, I/O default permissions are limited to root only. If you get the error message, "Can't open PORT /dev/cua1" the permissions may need to be altered. This is done with, "chmod 666 /dev/cua1". If you are not sure, use "ls -l /dev/cua1" to check.
  3. If your system was setup properly, you should be able to forget about the following. But just in case, PerlAPRS requires a perl module called which should be included with every Perl distribution. This module is required only to support perlAPRS's ability to get APRS packets from the Internet. If you get an error message that perlAPRS can't find the module, you can check where perl is looking by type at the command prompt: perl -e 'print "@INC\n";'. The variable @INC is the "include" array which tells perl where to look for the modules and other things that it needs. If your is not located where perl is looking, then you need to add your directory path to the @INC array with either of the following, the first is preferred.use lib '/mypath/'
    BEGIN {unshift (@INC, '/mypath/'}The code needs to be added prior to the command: use Socket, for example:use lib '/mypath/'
    require 5.002;
    use Socket;
    use strict;