Ham::APRS::FAP - Finnish APRS Parser (Fabulous APRS Parser)


  use Ham::APRS::FAP qw(parseaprs);
  my $aprspacket = 'OH2RDP>BEACON,OH2RDG*,WIDE:!6028.51N/02505.68E#PHG7220/RELAY,WIDE, OH2AP Jarvenpaa';
  my %packetdata;
  my $retval = parseaprs($aprspacket, \%packetdata);
  if ($retval == 1) {
        # decoding ok, do something with the data
        while (my ($key, $value) = each(%packetdata)) {
                print "$key: $value\n";
  } else {
        warn "Parsing failed: $packetdata{resultmsg} ($packetdata{resultcode})\n";


This module is a fairly complete APRS parser. It parses normal, mic-e and compressed location packets, NMEA location packets, objects, items, messages, telemetry and most weather packets. It is stable and fast enough to parse the APRS-IS stream in real time.

The package also contains the Ham::APRS::IS module which, in turn, is an APRS-IS client library.


Unless a debugging mode is enabled, all errors and warnings are reported through the API (as opposed to printing on STDERR or STDOUT), so that they can be reported nicely on the user interface of an application. This parser is not known to crash on invalid packets. It is used to power the web site.

APRS features specifically NOT handled by this module:

  • special objects (area, signpost, etc)

  • network tunneling/third party packets

  • direction finding

  • station capability queries

  • status reports (partially)

  • user defined data formats

This module is based (on those parts that are implemented) on APRS specification 1.0.1.

This module requires a reasonably recent Date::Calc module.


None by default.


result_messages( )

Returns a reference to a hash containing all possible return codes as the keys and their plain english descriptions as the values of the hash.


Convert mic-e message bits (three numbers 0-2) to a textual message. Returns the message on success, undef on failure.


Enables (debug(1)) or disables (debug(0)) debugging.

When debugging is enabled, warnings and errors are emitted using the warn() function, which will normally result in them being printed on STDERR. Succesfully printed packets will be also printed on STDOUT in a human-readable format.

When debugging is disabled, nothing will be printed on STDOUT or STDERR - all errors and parsing results need to be collected from the returned hash reference.

distance($lon0, $lat0, $lon1, $lat1)

Returns the distance in kilometers between two locations given in decimal degrees. Arguments are given in order as lon0, lat0, lon1, lat1, east and north positive. The calculation uses the great circle distance, it is not too exact, but good enough for us.

direction($lon0, $lat0, $lon1, $lat1)

Returns the initial great circle direction in degrees from lat0/lon0 to lat1/lon1. Locations are input in decimal degrees, north and east positive.


Count the number of digipeated hops in a (KISS) packet and return it. Returns -1 in case of error. The header parameter can contain the full packet or just the header in TNC2 format. All callsigns in the header must be AX.25 compatible and remember that the number returned is just an educated guess, not absolute truth.


Check the callsign for a valid AX.25 callsign format and return cleaned up (OH2XYZ-0) callsign or undef if the callsign is not a valid AX.25 address.

Please note that it's very common to use invalid callsigns on the APRS-IS.

parseaprs($packet, $hashref, %options)

Parse an APRS packet given as a string, e.g. "OH2XYZ>APRS,RELAY*,WIDE:!2345.56N/12345.67E-PHG0123 hi there" Second parameter has to be a reference to a hash. That hash will be filled with as much data as possible based on the packet given as parameter.

Returns 1 if the decoding was successfull, returns 0 if not. In case zero is returned, the contents of the parameter hash should be discarded, except for the error cause as reported via hash elements resultcode and resultmsg.

The third parameter is an optional hash containing any of the following options:

isax25 - the packet should be examined in a form that can exist on an AX.25 network (1) or whether the frame is from the Internet (0 - default).

accept_broken_mice - if the packet contains corrupted mic-e fields, but some of the data is still recovable, decode the packet instead of reporting an error. At least aprsd produces these packets. 1: try to decode, 0: report an error (default). Packets which have been successfully demangled will contain the mice_mangled flag.

raw_timestamp - Timestamps within the packets are not decoded to an UNIX timestamp, but are returned as raw strings.


my %hash;

my $ret = parseaprs("OH2XYZ>APRS,RELAY*,WIDE:!2345.56N/12345.67E-PHG0123 hi", \%hash, 'isax25' => 0, 'accept_broken_mice' => 0);


Convert a KISS-frame into a TNC-2 compatible UI-frame. Non-UI and non-pid-F0 frames are dropped. The KISS-frame to be decoded should not have FEND (0xC0) characters in the beginning or in the end. Byte unstuffing must not be done before calling this function. Returns a string containing the TNC-2 frame (no CR and/or LF) or undef on error.


Convert a TNC-2 compatible UI-frame into a KISS data frame (single port KISS TNC). The frame will be complete, i.e. it has byte stuffing done and FEND (0xC0) characters on both ends. If conversion fails, return undef.


Accepts a TNC-2 format frame and extracts the original sender callsign, destination callsign (without ssid) and payload data for duplicate detection. Returns sender, receiver and body on success, undef on error. In the case of third party packets, always gets this information from the innermost data. Also removes possible trailing spaces to improve detection (e.g. aprsd replaces trailing CRs or LFs in a packet with a space).

make_object($name, $tstamp, $lat, $lon, $symbols, $speed, $course, $altitude, $alive, $usecompression, $posambiguity, $comment)

Creates an APRS object. Returns a body of an APRS object, i.e. ";OBJECTNAM*DDHHMM/DDMM.hhN/DDDMM.hhW$CSE/SPDcomments..." or undef on error.


 1st: object name, has to be valid APRS object name, does not need to be space-padded
 2nd: object timestamp as a unix timestamp, or zero to use current time
 3rd: object latitude, decimal degrees
 4th: object longitude, decimal degrees
 5th: object symbol table (or overlay) and symbol code, two bytes if the given symbole length is zero (""), use point (//)
 6th: object speed, -1 if non-moving (km/h)
 7th: object course, -1 if non-moving
 8th: object altitude, -10000 or less if not used
 9th: alive or dead object (0 == dead, 1 == alive)
 10th: compressed (1) or uncompressed (0)
 11th: position ambiguity (0..4)
 12th: object comment text

Note: Course/speed/altitude/compression is not implemented.

This function API will probably change in the near future. The long list of parameters should be changed to hash with named parameters.

make_timestamp($timestamp, $format)

Create an APRS (UTC) six digit (DHM or HMS) timestamp from a unix timestamp. The first parameter is the unix timestamp to use, or zero to use current time. Second parameter should be one for HMS format, zero for DHM format.

Returns a 7-character string (e.g. "291345z") or undef on error.

make_position($lat, $lon, $speed, $course, $altitude, $symbols, $optionref)

Creates an APRS position for position/object/item. Parameters:

 1st: latitude in decimal degrees
 2nd: longitude in decimal degrees
 3rd: speed in km/h, -1 == don't include
 4th: course in degrees, -1 == don't include. zero == unknown course, 360 == north
 5th: altitude in meters above mean sea level, -10000 or under == don't use
 6th: aprs symbol to use, first table/overlay and then code (two bytes). If string length is zero (""), uses default.
 7th: hash reference for options:
 "compressed": 1 for compressed format
 "ambiguity": Use amount (0..4) of position ambiguity. Note that position ambiguity and compression can't be used at the same time.
 "dao": Use !DAO! extension for improved precision

Returns a string such as "1234.56N/12345.67E/CSD/SPD" or in compressed form "F*-X;n_Rv&{-A" or undef on error.

Please note: course/speed/altitude are not supported yet, and neither is compressed format or position ambiguity.

This function API will probably change in the near future. The long list of parameters should be changed to hash with named parameters.


APRS specification 1.0.1,

APRS addendums, e.g.

The source code of this module - there are some undocumented features.

libfap, a C library port of this module,

Python bindings for libfap,


Tapio Sokura, OH2KKU <>

Heikki Hannikainen, OH7LZB <>


Copyright 2005-2012 by Tapio Sokura

Copyright 2007-2012 by Heikki Hannikainen

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.