Home » Amateurfunk » Software » qaprstools

qaprstools - Qt based APRS tools

Repository:http://gitorious.org/qaprstools
Mailing list:http://groups.google.com/group/qt-ham

It looks like that APRS hasn't been designed by IT people. The protocol is a bunch of ad-hoc recipes. This makes APRS complicated to parse. It does not contain a recurring structure that is a just place-holder to fill-in the data. XML or ProtoBuf work that way. No, instead the data tags the presence, length and interpretation of the data.

Existing Parsers 

For Perl 

There exist some parsers for APRS data. One well known one is used by http://aprs.fi, it's the Perl-written Ham-APRS-FAP.

For C and Python 

Then there's the C-written libfap. Here the author did a marvelous task, because string-handling is very weakly supported in C, and APRS-parsing is very heavy on the string manipulation side. Is should be noted that libfap also contains Python bindings.

For C++ (using Qt) 

As I write most of my programs in C++ using the Qt toolkit, I thought that there must be a better way to do this. Qt's QString is quite versatile. And while QRegExp isn't a match for Perl's regexp, it's usable for the job. So I ended writing qaprstools.

Usage 

The classes are self-contained (meaning: it's easy to rip them out of my project and put them into your own). Getting rid of my "mydebug.h" and "mydebug.cpp" helper is quite simply.

The license for the code is GPLv2 or later --- note, it's not LGPL, so if you use this code in your application, your whole application must be GPLv2 or later. This is on purpose, I detest closed-source ham radio applications. :-)

APRSParser 

qaprstools contains currently the parser APRSParser in (definition, implementation). It can parse all APRS packets except some weather reports. Usage is quite simply:

    APRSParser parser;
    enum result res = parser.parse("OH8MTM-9>APOTC1,OH6RDD*,WIDE2-2,qAo,OH7JHF:!6228.64N/02540.37E>009/053/A=000392")

If you didn't get an error, you can retrieve most of the parsed data directly from the parser instance, e.g.

     qDebug("speed %f", parser.speed);
     qDebug("course %d", parser.course);

And the output will be:

     speed 98.155998
     course 9

If you set the preprocessor symbol DEBUGLVL in aprs_parser.cpp to 3, you'll see what data has been parsed:

     OH8MTM-9>APOTC1,OH6RDD*,WIDE2-2,qAo,OH7JHF:!6228.64N/02540.37E>009/053/A=000392
     pktheader => OH8MTM-9>APOTC1,OH6RDD*,WIDE2-2,qAo,OH7JHF
     pktbody => !6228.64N/02540.37E>009/053/A=000392
     srccallsign => OH8MTM-9
     check_ax25_call(APOTC1)
     dstcallsign => APOTC1
       check digicall 'OH6RDD*'
       hop: 1 OH6RDD
       check digicall 'WIDE2-2'
       hop: 0 WIDE2-2
       check digicall 'qAo'
       hop: 0 qAo
       check digicall 'OH7JHF'
       hop: 0 OH7JHF
       packettype: '!'
     messaging => 0
     APRSParser::normalpos_to_decimal(6228.64N/02540.37E>009/053/A=000392)
     format => 1
       symbol code, table: '>', '/' (456)
     posambiguity => 0
     latitude => 62.4773
     longitude => 25.6728
     posresolution => 18.52
     APRSParser::comments_to_decimal(009/053/A=000392)
     course => 9
     speed => 98.156
       rest now: '/A=000392' (848)
     altitude => 119.482
     comment =>
     APRSParser::setError(0, (null))

The full example of this little demo can be seen here.

APRSConnect 

If you don't have a radio, you can connect to APRS-IS servers and may use APRSConnect (definition, implementation) for this.

And again the usage is quite simple:

   APRSConnect conn;
   conn.setHost("dl.aprs2.net");
   conn.setUser("test");
   conn.setFilter("t/poimnwtqsu");
   conn.setProgram("telnet", "0.1");
   conn.setLog("../filetest/test.dat");
   conn.doConnect();

This demo connects to one APRS-IS server and gets all the APRS packets. They are simply stored in a file. The complete running example can be seen here

Have fun!