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!